rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

test_condition.c (5710B)


      1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr)
      2  *
      3  * The RSys library is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published
      5  * by the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * The RSys library is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #define _POSIX_C_SOURCE 199506L /* POSIX threads */
     17 
     18 #include "condition.h"
     19 #include "list.h"
     20 
     21 #include <string.h>
     22 #include <pthread.h>
     23 
     24 static const char* src_str[] = {
     25 "Rcvfbqr 1, XARR-QRRC VA GUR QRNQ:\n\
     26 ---------------------------------",
     27 
     28 "BAPR LBH ORNG GUR OVT ONQNFFRF NAQ PYRNA BHG GUR ZBBA ONFR LBH'ER FHCCBFRQ GB\n\
     29 JVA, NERA'G LBH? NERA'G LBH? JURER'F LBHE SNG ERJNEQ NAQ GVPXRG UBZR? JUNG\n\
     30 GUR URYY VF GUVF? VG'F ABG FHCCBFRQ GB RAQ GUVF JNL!",
     31 
     32 "VG FGVAXF YVXR EBGGRA ZRNG, OHG YBBXF YVXR GUR YBFG QRVZBF ONFR. YBBXF YVXR\n\
     33 LBH'ER FGHPX BA GUR FUBERF BS URYY. GUR BAYL JNL BHG VF GUEBHTU.",
     34 
     35 "GB PBAGVAHR GUR QBBZ RKCREVRAPR, CYNL GUR FUBERF BS URYY NAQ VGF NZNMVAT\n\
     36 FRDHRY, VASREAB!",
     37 
     38 "Rcvfbqr 2, GUR FUBERF BS URYY:\n\
     39 ------------------------------",
     40 
     41 "LBH'IR QBAR VG! GUR UVQRBHF PLORE- QRZBA YBEQ GUNG EHYRQ GUR YBFG QRVZBF ZBBA\n\
     42 ONFR UNF ORRA FYNVA NAQ LBH NER GEVHZCUNAG! OHG ... JURER NER LBH? LBH\n\
     43 PYNZORE GB GUR RQTR BS GUR ZBBA NAQ YBBX QBJA GB FRR GUR NJSHY GEHGU.",
     44 
     45 "QRVZBF SYBNGF NOBIR URYY VGFRYS!  LBH'IR ARIRE URNEQ BS NALBAR RFPNCVAT SEBZ\n\
     46 URYY, OHG LBH'YY ZNXR GUR ONFGNEQF FBEEL GURL RIRE URNEQ BS LBH! DHVPXYL, LBH\n\
     47 ENCCRY QBJA GB GUR FHESNPR BS URYY.",
     48 
     49 "ABJ, VG'F BA GB GUR SVANY PUNCGRE BS QBBZ! -- VASREAB.",
     50 
     51 "Rcvfbqr 3, VASREAB:\n\
     52 -------------------",
     53 
     54 "GUR YBNGUFBZR FCVQREQRZBA GUNG ZNFGREZVAQRQ GUR VAINFVBA BS GUR ZBBA ONFRF\n\
     55 NAQ PNHFRQ FB ZHPU QRNGU UNF UNQ VGF NFF XVPXRQ SBE NYY GVZR.",
     56 
     57 "N UVQQRA QBBEJNL BCRAF NAQ LBH RAGRE.  LBH'IR CEBIRA GBB GBHTU SBE URYY GB\n\
     58 PBAGNVA, NAQ ABJ URYY NG YNFG CYNLF SNVE -- SBE LBH RZRETR SEBZ GUR QBBE GB\n\
     59 FRR GUR TERRA SVRYQF BS RNEGU!  UBZR NG YNFG.",
     60 
     61 "LBH JBAQRE JUNG'F ORRA UNCCRAVAT BA RNEGU JUVYR LBH JRER ONGGYVAT RIVY\n\
     62 HAYRNFURQ. VG'F TBBQ GUNG AB URYY- FCNJA PBHYQ UNIR PBZR GUEBHTU GUNG QBBE\n\
     63 JVGU LBH ...",
     64 
     65 "Rcvfbqr 4, GUL SYRFU PBAFHZRQ:\n\
     66 ------------------------------",
     67 
     68 "GUR FCVQRE ZNFGREZVAQ ZHFG UNIR FRAG SBEGU VGF YRTVBAF BS URYYFCNJA ORSBER\n\
     69 LBHE SVANY PBASEBAGNGVBA JVGU GUNG GREEVOYR ORNFG SEBZ URYY. OHG LBH FGRCCRQ\n\
     70 SBEJNEQ NAQ OEBHTUG SBEGU RGREANY QNZANGVBA NAQ FHSSREVAT HCBA GUR UBEQR NF N\n\
     71 GEHR UREB JBHYQ VA GUR SNPR BS FBZRGUVAT FB RIVY.",
     72 
     73 "ORFVQRF, FBZRBAR JNF TBAAN CNL SBE JUNG UNCCRARQ GB QNVFL, LBHE CRG ENOOVG.",
     74 
     75 "OHG ABJ, LBH FRR FCERNQ ORSBER LBH ZBER CBGRAGVNY CNVA NAQ TVOOVGHQR NF N\n\
     76 ANGVBA BS QRZBAF EHA NZBX VA BHE PVGVRF.",
     77 
     78 "ARKG FGBC, URYY BA RNEGU!"
     79 };
     80 
     81 struct stream
     82 {
     83   struct list_node list_fill;
     84   struct list_node list_flush;
     85   struct mutex* mutex;
     86   struct cond* cond_fill;
     87   struct cond* cond_flush;
     88 };
     89 
     90 struct buff
     91 {
     92   struct list_node node;
     93   char scratch[1024];
     94 };
     95 
     96 static void*
     97 read(void* arg)
     98 {
     99   struct stream* stream = arg;
    100   size_t i = 0;
    101   ASSERT(stream);
    102 
    103   FOR_EACH(i, 0, sizeof(src_str)/sizeof(const char*)) {
    104     struct list_node* buff_node = NULL;
    105     struct buff* buff = NULL;
    106 
    107     mutex_lock(stream->mutex);
    108     if(is_list_empty(&stream->list_flush)) {
    109       cond_wait(stream->cond_flush, stream->mutex);
    110     }
    111     mutex_unlock(stream->mutex);
    112 
    113     buff_node = list_head(&stream->list_flush);
    114     buff = CONTAINER_OF(buff_node, struct buff, node);
    115     CHK(strcmp(buff->scratch, src_str[i]) == 0);
    116     printf("\n%s\n", buff->scratch);
    117 
    118     mutex_lock(stream->mutex);
    119     list_move_tail(buff_node, &stream->list_fill);
    120     mutex_unlock(stream->mutex);
    121 
    122     cond_broadcast(stream->cond_fill);
    123   }
    124   return NULL;
    125 }
    126 
    127 static void*
    128 write(void* arg)
    129 {
    130   struct stream* stream = arg;
    131   size_t i = 0;
    132   ASSERT(stream);
    133 
    134   FOR_EACH(i, 0, sizeof(src_str)/sizeof(const char*)) {
    135     struct list_node* buff_node = NULL;
    136     struct buff* buff = NULL;
    137 
    138     mutex_lock(stream->mutex);
    139     if(is_list_empty(&stream->list_fill)) {
    140       cond_wait(stream->cond_fill, stream->mutex);
    141     }
    142     mutex_unlock(stream->mutex);
    143 
    144     buff_node = list_head(&stream->list_fill);
    145     buff = CONTAINER_OF(buff_node, struct buff, node);
    146 
    147     ASSERT(sizeof(buff->scratch)/sizeof(char) > strlen(src_str[i]));
    148     strcpy(buff->scratch, src_str[i]);
    149 
    150     mutex_lock(stream->mutex);
    151     list_move_tail(buff_node, &stream->list_flush);
    152     mutex_unlock(stream->mutex);
    153 
    154     cond_broadcast(stream->cond_flush);
    155   }
    156   return NULL;
    157 }
    158 
    159 int
    160 main(int argc, char** argv)
    161 {
    162   struct buff buff[2];
    163   struct stream stream;
    164   pthread_t thread;
    165   (void)argc, (void)argv;
    166 
    167   list_init(&stream.list_fill);
    168   list_init(&stream.list_flush);
    169   stream.mutex = mutex_create();
    170   CHK(stream.mutex != NULL);
    171   stream.cond_flush = cond_create();
    172   CHK(stream.cond_flush != NULL);
    173   stream.cond_fill = cond_create();
    174   CHK(stream.cond_fill != NULL);
    175 
    176   list_init(&buff[0].node);
    177   list_init(&buff[1].node);
    178   list_add(&stream.list_fill, &buff[0].node);
    179   list_add(&stream.list_fill, &buff[1].node);
    180 
    181   CHK(pthread_create(&thread, NULL, read, &stream) == 0); /* Sub thread */
    182   write(&stream);
    183   CHK(pthread_join(thread, NULL) == 0);
    184 
    185   mutex_destroy(stream.mutex);
    186   cond_destroy(stream.cond_flush);
    187   cond_destroy(stream.cond_fill);
    188   return 0;
    189 }