File:  [local] / rpl / src / operations_atomiques.c
Revision 1.75: download - view: text, annotated - select for diffs - revision graph
Sat Mar 13 12:50:51 2021 UTC (3 years, 1 month ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_33, HEAD
En route pour la 4.1.33.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.33
    4:   Copyright (C) 1989-2021 Dr. BERTRAND Joël
    5: 
    6:   This file is part of RPL/2.
    7: 
    8:   RPL/2 is free software; you can redistribute it and/or modify it
    9:   under the terms of the CeCILL V2 License as published by the french
   10:   CEA, CNRS and INRIA.
   11:  
   12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
   13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
   15:   for more details.
   16:  
   17:   You should have received a copy of the CeCILL License
   18:   along with RPL/2. If not, write to info@cecill.info.
   19: ================================================================================
   20: */
   21: 
   22: 
   23: #include "rpl-conv.h"
   24: 
   25: 
   26: /*
   27: ================================================================================
   28:   Procédure de lecture atomique
   29: ================================================================================
   30:   Entrée :
   31: --------------------------------------------------------------------------------
   32:   Sortie :
   33: --------------------------------------------------------------------------------
   34:   Effets de bord : néant
   35: ================================================================================
   36: */
   37: 
   38: ssize_t
   39: read_atomic(struct_processus *s_etat_processus,
   40:         int descripteur, void *tampon, size_t longueur_tampon)
   41: {
   42:     logical1            drapeau;
   43: 
   44:     size_t              longueur_residuelle;
   45:     ssize_t             longueur_lue;
   46: 
   47:     struct timespec     attente;
   48: 
   49:     void                *pointeur;
   50: 
   51:     longueur_residuelle = longueur_tampon;
   52:     pointeur = tampon;
   53: 
   54:     attente.tv_sec = 0;
   55:     attente.tv_nsec = GRANULARITE_us * 1000;
   56: 
   57:     while(longueur_residuelle != 0)
   58:     {
   59:         errno = 0;
   60:         longueur_lue = 0;
   61: 
   62:         while(longueur_lue == 0)
   63:         {
   64:             do
   65:             {
   66:                 longueur_lue = read(descripteur, pointeur,
   67:                         (longueur_residuelle > PIPE_BUF)
   68:                         ? PIPE_BUF : longueur_residuelle);
   69: 
   70:                 if ((longueur_lue == 0) &&
   71:                         (longueur_tampon == longueur_residuelle))
   72:                 {
   73:                     return(((ssize_t) longueur_tampon) -
   74:                             ((ssize_t) longueur_residuelle));
   75:                 }
   76: 
   77:                 if ((longueur_lue == -1) && (errno == EINTR))
   78:                 {
   79:                     scrutation_interruptions(s_etat_processus);
   80:                     nanosleep(&attente, NULL);
   81:                     drapeau = d_vrai;
   82:                 }
   83:                 else
   84:                 {
   85:                     drapeau = d_faux;
   86:                 }
   87:             } while(drapeau == d_vrai);
   88: 
   89:             if (longueur_lue != 0)
   90:             {
   91:                 if (longueur_lue < (ssize_t) ((longueur_residuelle > PIPE_BUF)
   92:                         ? PIPE_BUF : longueur_residuelle))
   93:                 {
   94:                     pointeur += longueur_lue;
   95:                     longueur_residuelle -= (size_t) longueur_lue;
   96: 
   97:                     return(((ssize_t) longueur_tampon) -
   98:                             ((ssize_t) longueur_residuelle));
   99:                 }
  100:             }
  101:         }
  102: 
  103:         pointeur += longueur_lue;
  104:         longueur_residuelle -= (size_t) longueur_lue;
  105:     }
  106: 
  107:     return(((ssize_t) longueur_tampon) - ((ssize_t) longueur_residuelle));
  108: }
  109: 
  110: 
  111: /*
  112: ================================================================================
  113:   Procédure de lecture atomique interruptible par var_volatile_requete_arret
  114: ================================================================================
  115:   Entrée :
  116: --------------------------------------------------------------------------------
  117:   Sortie :
  118: --------------------------------------------------------------------------------
  119:   Effets de bord : néant
  120: ================================================================================
  121: */
  122: 
  123: ssize_t
  124: read_atomic_signal(struct_processus *s_etat_processus,
  125:         int descripteur, void *tampon, size_t longueur_tampon)
  126: {
  127:     logical1            drapeau;
  128: 
  129:     size_t              longueur_residuelle;
  130:     ssize_t             longueur_lue;
  131: 
  132:     struct timespec     attente;
  133: 
  134:     void                *pointeur;
  135: 
  136:     longueur_residuelle = longueur_tampon;
  137:     pointeur = tampon;
  138: 
  139:     attente.tv_sec = 0;
  140:     attente.tv_nsec = GRANULARITE_us * 1000;
  141: 
  142:     while(longueur_residuelle != 0)
  143:     {
  144:         errno = 0;
  145:         longueur_lue = 0;
  146: 
  147:         while(longueur_lue == 0)
  148:         {
  149:             do
  150:             {
  151:                 longueur_lue = read(descripteur, pointeur,
  152:                         (longueur_residuelle > PIPE_BUF)
  153:                         ? PIPE_BUF : longueur_residuelle);
  154: 
  155:                 // Traitement des signaux en attente nécessaire
  156:                 // au positionnement de la variable
  157:                 // (*s_etat_processus).var_volatile_requete_arret
  158:                 // qui se fait dans un thread séparé.
  159: 
  160:                 while((*s_queue_signaux).pointeur_ecriture !=
  161:                         (*s_queue_signaux).pointeur_lecture)
  162:                 {
  163:                     scrutation_interruptions(s_etat_processus);
  164:                     nanosleep(&attente, NULL);
  165:                 }
  166: 
  167:                 if (((longueur_lue == 0) &&
  168:                         (longueur_tampon == longueur_residuelle)) ||
  169:                         ((*s_etat_processus).var_volatile_requete_arret == -1))
  170:                 {
  171:                     return(((ssize_t) longueur_tampon) -
  172:                             ((ssize_t) longueur_residuelle));
  173:                 }
  174: 
  175:                 if ((longueur_lue == -1) && (errno == EINTR))
  176:                 {
  177:                     scrutation_interruptions(s_etat_processus);
  178:                     nanosleep(&attente, NULL);
  179:                     drapeau = d_vrai;
  180:                 }
  181:                 else
  182:                 {
  183:                     drapeau = d_faux;
  184:                 }
  185:             } while(drapeau == d_vrai);
  186: 
  187:             if (longueur_lue != 0)
  188:             {
  189:                 if (longueur_lue < (ssize_t) ((longueur_residuelle > PIPE_BUF)
  190:                         ? PIPE_BUF : longueur_residuelle))
  191:                 {
  192:                     pointeur += longueur_lue;
  193:                     longueur_residuelle -= (size_t) longueur_lue;
  194: 
  195:                     return(((ssize_t) longueur_tampon) -
  196:                             ((ssize_t) longueur_residuelle));
  197:                 }
  198:             }
  199:         }
  200: 
  201:         pointeur += longueur_lue;
  202:         longueur_residuelle -= (size_t) longueur_lue;
  203:     }
  204: 
  205:     return(((ssize_t) longueur_tampon) - ((ssize_t) longueur_residuelle));
  206: }
  207: 
  208: 
  209: /*
  210: ================================================================================
  211:   Procédure d'écriture atomique
  212: ================================================================================
  213:   Entrée :
  214: --------------------------------------------------------------------------------
  215:   Sortie :
  216: --------------------------------------------------------------------------------
  217:   Effets de bord : néant
  218: ================================================================================
  219: */
  220: 
  221: ssize_t
  222: write_atomic(struct_processus *s_etat_processus,
  223:         int descripteur, void *tampon, size_t longueur_tampon)
  224: {
  225:     logical1            drapeau;
  226: 
  227:     size_t              longueur_residuelle;
  228:     ssize_t             longueur_ecrite;
  229: 
  230:     struct timespec     attente;
  231: 
  232:     void                *pointeur;
  233: 
  234:     longueur_residuelle = longueur_tampon;
  235:     pointeur = tampon;
  236: 
  237:     attente.tv_sec = 0;
  238:     attente.tv_nsec = GRANULARITE_us * 1000;
  239: 
  240:     while(longueur_residuelle != 0)
  241:     {
  242:         errno = 0;
  243:         longueur_ecrite = 0;
  244: 
  245:         while(longueur_ecrite == 0)
  246:         {
  247:             do
  248:             {
  249:                 longueur_ecrite = write(descripteur, pointeur,
  250:                         (longueur_residuelle > PIPE_BUF)
  251:                         ? PIPE_BUF : longueur_residuelle);
  252: 
  253:                 if (longueur_ecrite == -1)
  254:                 {
  255:                     if (errno == EINTR)
  256:                     {
  257:                         scrutation_interruptions(s_etat_processus);
  258:                         nanosleep(&attente, NULL);
  259:                         drapeau = d_vrai;
  260:                     }
  261:                     else // EPIPE
  262:                     {
  263:                         return(-1);
  264:                     }
  265:                 }
  266:                 else
  267:                 {
  268:                     drapeau = d_faux;
  269:                 }
  270:             } while(drapeau == d_vrai);
  271: 
  272:             if (longueur_ecrite == 0)
  273:             {
  274:                 scrutation_interruptions(s_etat_processus);
  275:                 nanosleep(&attente, NULL);
  276:             }
  277:         }
  278: 
  279:         pointeur += longueur_ecrite;
  280:         longueur_residuelle -= (size_t) longueur_ecrite;
  281:     }
  282: 
  283:     return((ssize_t) longueur_tampon);
  284: }
  285: 
  286: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>