/[livstidsfanger]/trunk/livstidsfanger.c
ViewVC logotype

Diff of /trunk/livstidsfanger.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 4 by trond, 2014-11-07T07:56:17Z Revision 12 by trond, 2014-11-08T12:40:52Z
# Line 1  Line 1 
1  // Programmet bruker ISO C 2011 (ISO/IEC 9899:2011) og Pthreads (IEEE Std 1003.1c-1995). -*- coding: utf-8 -*-  // Programmet bruker ISO C 2011 (ISO/IEC 9899:2011) og Pthreads (IEEE Std 1003.1c-1995). -*- coding: utf-8 -*-
2  // Løsning laget av Trond Endrestøl <Trond.Endrestol@ximalas.info>, 2014-11-06.  // Løsning programmert av Trond Endrestøl <Trond.Endrestol@ximalas.info>, 2014-11-06.
3    
4  // $Ximalas$  // $Ximalas$
5    
6    #if __STDC_VERSION__ < 199901L
7    #error det er tvilsomt om du får kompilert denne kildekoden med så gammel C-kompilator
8    #endif
9    
10  #include <errno.h>  #include <errno.h>
11  #include <pthread.h>  #include <pthread.h>
12  #include <signal.h>  #include <signal.h>
13    #include <stdbool.h>
14  #include <stdio.h>  #include <stdio.h>
15  #include <stdlib.h>  #include <stdlib.h>
16  #include <string.h>  #include <string.h>
17    #include <time.h>
18  #include <unistd.h>  #include <unistd.h>
19    
20  #if __STDC_VERSION__ >= 201112L  #if __STDC_VERSION__ >= 201112L
# Line 26  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; Line 32  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
32    
33  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
34  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
35  static unsigned brytere[2U];  static bool brytere[2U];
36    
37  noreturn void *livstidsfange(void *arg);  noreturn void *livstidsfange(void *arg);
38  void visResultater(void);  void visResultater(void);
# Line 37  noreturn int main(int argc, char **argv) Line 43  noreturn int main(int argc, char **argv)
43    size_t i;    size_t i;
44    pthread_t tid = pthread_self();    pthread_t tid = pthread_self();
45    
46    atexit(visResultater);    if (argc >= 0) { // Bare for å få clang til å ti stille.
47    signal(SIGINT, signalhandler);      atexit(visResultater);
48        signal(SIGINT, signalhandler);
49      } // if
50    
51    #ifdef __FreeBSD__
52    srandomdev();    srandomdev();
53    #else
54      srandom((unsigned int)time(NULL));
55    #endif
56    
57    memset((void *)&antallBesok, 0, sizeof(antallBesok));    memset((void *)&antallBesok, 0, sizeof(antallBesok));
58    brytere[0] = random() & 1;    brytere[0] = random() & 1;
# Line 48  noreturn int main(int argc, char **argv) Line 60  noreturn int main(int argc, char **argv)
60    
61    tellendeLivstidsfange = random() % ANTALL_LIVSTIDSFANGER;    tellendeLivstidsfange = random() % ANTALL_LIVSTIDSFANGER;
62    
63      printf("bryter %u er i utgangspunktet vippet %s\n", 1U, brytere[0] == true ? "opp" : "ned");
64      printf("bryter %u er i utgangspunktet vippet %s\n", 2U, brytere[1] == true ? "opp" : "ned");
65      printf("livstidsfange %zu er utpekt som den tellende livstidsfange\n\n", tellendeLivstidsfange + 1);
66    
67    puts("maintråden venter på å få låst mutex");    puts("maintråden venter på å få låst mutex");
68    pthread_mutex_lock(&mutex);    pthread_mutex_lock(&mutex);
69    puts("mutex er låst av maintråden");    puts("mutex er låst av maintråden");
# Line 56  noreturn int main(int argc, char **argv) Line 72  noreturn int main(int argc, char **argv)
72      printf("maintråden oppretter livstidsfange %2zu\n", i + 1);      printf("maintråden oppretter livstidsfange %2zu\n", i + 1);
73    
74      if ( (errno = pthread_create(&tid, NULL, livstidsfange, (void *)i)) != 0) {      if ( (errno = pthread_create(&tid, NULL, livstidsfange, (void *)i)) != 0) {
75          fflush(stdout);
76        fprintf(stderr,        fprintf(stderr,
77                "%s: pthread_create(&tid, NULL, livstidsfange, (void *)%2zu) = %s (%d)\n",                "%s: pthread_create(&tid, NULL, livstidsfange, (void *)%2zu) = %s (%d)\n",
78                argv[0], i, strerror(errno), errno);                argv[0], i, strerror(errno), errno);
79        exit(1);        fflush(stderr);
80          _exit(1);
81      } // if      } // if
82    } // for    } // for
83    
# Line 83  noreturn void *livstidsfange(void *arg) Line 101  noreturn void *livstidsfange(void *arg)
101  {  {
102    size_t i = (size_t)arg;    size_t i = (size_t)arg;
103    
104    unsigned harVippetBryter1 = 0U;    bool harVippetBryter1 = false;
105    unsigned bryter1HarVartOppe = 0U;    bool bryter1HarVartOppe = false;
106    
107    unsigned forrigeGangErGyldig = 0U;    bool forrigeGangErGyldig = false;
108    unsigned forrigeGang = 0U;    bool forrigeGang = false;
109    
110    // Den tellende livstidsfangen kan allerede nå telle seg selv.    // Den tellende livstidsfangen kan allerede nå telle seg selv.
111    if (i == tellendeLivstidsfange) {    if (i == tellendeLivstidsfange) {
# Line 106  noreturn void *livstidsfange(void *arg) Line 124  noreturn void *livstidsfange(void *arg)
124    
125      // Utføre selve simuleringen ved å sjekke brytere, m.m.      // Utføre selve simuleringen ved å sjekke brytere, m.m.
126      antallBesok[i]++;      antallBesok[i]++;
127      printf("livstidsfange %2zu har besøkt rommet %u ganger\n", i + 1, antallBesok[i]);      printf("livstidsfange %2zu har besøkt rommet %u gang%s\n", i + 1, antallBesok[i], antallBesok[i] == 1 ? "" : "er");
128    
129      if (i == tellendeLivstidsfange) {      if (i == tellendeLivstidsfange) {
130        if (brytere[0] == 0U) {        if (brytere[0] == false) {
131          printf("livstidsfange %2zu ser at bryter 1 er nede og vipper opp bryter 1\n", i + 1);          printf("livstidsfange %2zu ser at bryter 1 er nede og vipper opp bryter 1\n", i + 1);
132          brytere[0] = 1U;          brytere[0] = true;
133        } // if        } // if
134        else {        else {
135          brytere[0] = !brytere[0];          brytere[0] = !brytere[0];
136          printf("livstidsfange %2zu vipper %s bryter 1\n", i + 1, brytere[0] == 1U ? "opp" : "ned");          printf("livstidsfange %2zu vipper %s bryter 1\n", i + 1, brytere[0] == true ? "opp" : "ned");
137    
138          if (forrigeGangErGyldig == 1U && forrigeGang == 0U) {          if (forrigeGangErGyldig == true && forrigeGang == false) {
139            antallLivstidsfanger++;            antallLivstidsfanger++;
140            printf("livstidsfange %2zu har talt opp %u livstidsfanger\n", i + 1, antallLivstidsfanger);            printf("livstidsfange %2zu har talt opp %u livstidsfanger\n", i + 1, antallLivstidsfanger);
141    
# Line 127  noreturn void *livstidsfange(void *arg) Line 145  noreturn void *livstidsfange(void *arg)
145            } // if            } // if
146          } // if          } // if
147    
148          forrigeGangErGyldig = 1U;          forrigeGangErGyldig = true;
149          forrigeGang = brytere[0];          forrigeGang = brytere[0];
150        } // else        } // else
151      } // if      } // if
152      else { // Vanlig livstidsfange.      else { // Vanlig livstidsfange.
153        if (brytere[0] == 1U) {        if (brytere[0] == true) {
154          printf("livstidsfange %2zu ser at bryter 1 er oppe, mens bryter 2 er %s\n", i + 1, brytere[1] == 1U ? "oppe" : "nede");          printf("livstidsfange %2zu ser at bryter 1 er oppe, mens bryter 2 er %s\n", i + 1, brytere[1] == true ? "oppe" : "nede");
155          bryter1HarVartOppe = 1U;          bryter1HarVartOppe = true;
156    
157          brytere[1] = !brytere[1];          brytere[1] = !brytere[1];
158          printf("livstidsfange %2zu vipper %s bryter 2\n", i + 1, brytere[1] == 1U ? "opp" : "ned");          printf("livstidsfange %2zu vipper %s bryter 2\n", i + 1, brytere[1] == true ? "opp" : "ned");
159        } // if        } // if
160        else {        else {
161          printf("livstidsfange %2zu ser at bryter 1 er nede, mens bryter 2 er %s\n", i + 1, brytere[1] == 1U ? "oppe" : "nede");          printf("livstidsfange %2zu ser at bryter 1 er nede, mens bryter 2 er %s\n", i + 1, brytere[1] == true ? "oppe" : "nede");
162    
163          if (harVippetBryter1 == 0U && bryter1HarVartOppe == 1U) {          if (harVippetBryter1 == false && bryter1HarVartOppe == true) {
164            brytere[0] = !brytere[0];            brytere[0] = !brytere[0];
165            printf("livstidsfange %2zu vipper %s bryter 1\n", i + 1, brytere[0] == 1U ? "opp" : "ned");            printf("livstidsfange %2zu vipper %s bryter 1\n", i + 1, brytere[0] == true ? "opp" : "ned");
166    
167            harVippetBryter1 = 1U;            harVippetBryter1 = true;
168          } // if          } // if
169          else {          else {
170            brytere[1] = !brytere[1];            brytere[1] = !brytere[1];
171            printf("livstidsfange %2zu vipper %s bryter 2\n", i + 1, brytere[1] == 1U ? "opp" : "ned");            printf("livstidsfange %2zu vipper %s bryter 2\n", i + 1, brytere[1] == true ? "opp" : "ned");
172          } // else          } // else
173        } // else        } // else
174      } // else      } // else
# Line 168  void visResultater(void) Line 186  void visResultater(void)
186    
187    fflush(stderr);    fflush(stderr);
188    fflush(stdout);    fflush(stdout);
   fflush(stderr);  
   fflush(stdout);  
   puts("");  
189    
190    printf("livstidsfange %2zu er den tellende livstidsfangen\n\n", tellendeLivstidsfange + 1);    puts("\nResultater:\n");
191    
192      printf("bryter %u er ved avslutning vippet %s\n", 1U, brytere[0] == true ? "opp" : "ned");
193      printf("bryter %u er ved avslutning vippet %s\n", 2U, brytere[1] == true ? "opp" : "ned");
194      printf("livstidsfange %2zu var den tellende livstidsfangen\n\n", tellendeLivstidsfange + 1);
195    
196    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {    for (i = 0; i < ANTALL_LIVSTIDSFANGER; i++) {
197      printf("livstidsfange %2zu: antall besøk = %u\n", i + 1, antallBesok[i]);      printf("livstidsfange %2zu: antall besøk: %u\n", i + 1, antallBesok[i]);
198    } // for    } // for
199      puts("");
200    
201      printf("antall livstidsfanger talt av den tellende livstidsfangen er %u\n", antallLivstidsfanger);
202    
203    fflush(stdout);    fflush(stdout);
204    fflush(stdout);    fflush(stdout);
205  } // visResultater()  } // visResultater()


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

svn@ximalas.info
ViewVC Help
Powered by ViewVC 1.3.0-beta1