/[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 5 by trond, 2014-11-07T08:04:18Z
# 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 laget av Trond Endrestøl <Trond.Endrestol@ximalas.info>, 2014-11-06.
3    
4  // $Ximalas$  // $Ximalas$
5    
6  #include <errno.h>  #include <errno.h>
7  #include <pthread.h>  #include <pthread.h>
8  #include <signal.h>  #include <signal.h>
9    #include <stdbool.h>
10  #include <stdio.h>  #include <stdio.h>
11  #include <stdlib.h>  #include <stdlib.h>
12  #include <string.h>  #include <string.h>
13  #include <unistd.h>  #include <unistd.h>
14    
15  #if __STDC_VERSION__ >= 201112L  #if __STDC_VERSION__ >= 201112L
16  #include <stdnoreturn.h>  #include <stdnoreturn.h>
17  #else  #else
18  #define noreturn  #define noreturn
19  #endif  #endif
20    
21  #define ANTALL_LIVSTIDSFANGER 19U  #define ANTALL_LIVSTIDSFANGER 19U
22    
23  static unsigned antallBesok[ANTALL_LIVSTIDSFANGER];  static unsigned antallBesok[ANTALL_LIVSTIDSFANGER];
24    
25  static size_t tellendeLivstidsfange;  static size_t tellendeLivstidsfange;
26  static unsigned antallLivstidsfanger;  static unsigned antallLivstidsfanger;
27    
28  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
29  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;  static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
30  static unsigned brytere[2U];  static bool brytere[2U];
31    
32  noreturn void *livstidsfange(void *arg);  noreturn void *livstidsfange(void *arg);
33  void visResultater(void);  void visResultater(void);
34  void signalhandler(int sig);  void signalhandler(int sig);
35    
36  noreturn int main(int argc, char **argv)  noreturn int main(int argc, char **argv)
37  {  {
38    size_t i;    size_t i;
39    pthread_t tid = pthread_self();    pthread_t tid = pthread_self();
40    
41    atexit(visResultater);    atexit(visResultater);
42    signal(SIGINT, signalhandler);    signal(SIGINT, signalhandler);
43    
44    srandomdev();    srandomdev();
45    
# Line 71  noreturn void *livstidsfange(void *arg) Line 72  noreturn void *livstidsfange(void *arg)
72    
73      puts("fengselsdirektøren signalerer livstidsfangene");      puts("fengselsdirektøren signalerer livstidsfangene");
74      pthread_cond_signal(&cond);      pthread_cond_signal(&cond);
75      puts("signal er sendt fra fengselsdirektøren");      puts("signal er sendt fra fengselsdirektøren");
76    
77      puts("fengselsdirektøren venter på å få låst mutex");      puts("fengselsdirektøren venter på å få låst mutex");
78      pthread_mutex_lock(&mutex);      pthread_mutex_lock(&mutex);
79      puts("mutex er låst av fengselsdirektøren");      puts("mutex er låst av fengselsdirektøren");
80    } // while    } // while
81  } // main()  } // main()
82    
83  noreturn void *livstidsfange(void *arg)  noreturn void *livstidsfange(void *arg)
84  {  {
85    size_t i = (size_t)arg;    size_t i = (size_t)arg;
86    
87    unsigned harVippetBryter1 = 0U;    bool harVippetBryter1 = false;
88    unsigned bryter1HarVartOppe = 0U;    bool bryter1HarVartOppe = false;
89    
90    unsigned forrigeGangErGyldig = 0U;    bool forrigeGangErGyldig = false;
91    unsigned forrigeGang = 0U;    bool forrigeGang = false;
92    
93    // Den tellende livstidsfangen kan allerede nå telle seg selv.    // Den tellende livstidsfangen kan allerede nå telle seg selv.
94    if (i == tellendeLivstidsfange) {    if (i == tellendeLivstidsfange) {
95      antallLivstidsfanger++;      antallLivstidsfanger++;
96    } // if    } // if
97    
98    while (1) {    while (1) {
99      // Vente på tur.      // Vente på tur.
100      printf("livstidsfange %2zu venter på å få låst mutex\n", i + 1);      printf("livstidsfange %2zu venter på å få låst mutex\n", i + 1);
101      pthread_mutex_lock(&mutex);      pthread_mutex_lock(&mutex);
102      printf("livstidsfange %2zu har låst mutex\n", i + 1);      printf("livstidsfange %2zu har låst mutex\n", i + 1);
103    
104      printf("livstidsfange %2zu venter på signal fra fengselsdirektøren\n", i + 1);      printf("livstidsfange %2zu venter på signal fra fengselsdirektøren\n", i + 1);
105      pthread_cond_wait(&cond, &mutex);      pthread_cond_wait(&cond, &mutex);
106      printf("livstidsfange %2zu har fått signal fra fengselsdirektøren og har låst mutex\n", i + 1);      printf("livstidsfange %2zu har fått signal fra fengselsdirektøren og har låst mutex\n", i + 1);
107    
108      // Utføre selve simuleringen ved å sjekke brytere, m.m.      // Utføre selve simuleringen ved å sjekke brytere, m.m.
109      antallBesok[i]++;      antallBesok[i]++;
110      printf("livstidsfange %2zu har besøkt rommet %u ganger\n", i + 1, antallBesok[i]);      printf("livstidsfange %2zu har besøkt rommet %u ganger\n", i + 1, antallBesok[i]);
111    
112      if (i == tellendeLivstidsfange) {      if (i == tellendeLivstidsfange) {
113        if (brytere[0] == 0U) {        if (brytere[0] == false) {
114          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);
115          brytere[0] = 1U;          brytere[0] = true;
116        } // if        } // if
117        else {        else {
118          brytere[0] = !brytere[0];          brytere[0] = !brytere[0];
119          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] == 1U ? "opp" : "ned");
120    
121          if (forrigeGangErGyldig == 1U && forrigeGang == 0U) {          if (forrigeGangErGyldig == true && forrigeGang == false) {
122            antallLivstidsfanger++;            antallLivstidsfanger++;
123            printf("livstidsfange %2zu har talt opp %u livstidsfanger\n", i + 1, antallLivstidsfanger);            printf("livstidsfange %2zu har talt opp %u livstidsfanger\n", i + 1, antallLivstidsfanger);
124    
125            if (antallLivstidsfanger == ANTALL_LIVSTIDSFANGER) {            if (antallLivstidsfanger == ANTALL_LIVSTIDSFANGER) {
126              printf("livstidsfange %2zu avslutter simuleringen\n", i + 1);              printf("livstidsfange %2zu avslutter simuleringen\n", i + 1);
127              exit(0);              exit(0);
128            } // if            } // if
129          } // if          } // if
130    
131          forrigeGangErGyldig = 1U;          forrigeGangErGyldig = true;
132          forrigeGang = brytere[0];          forrigeGang = brytere[0];
133        } // else        } // else
134      } // if      } // if
135      else { // Vanlig livstidsfange.      else { // Vanlig livstidsfange.
136        if (brytere[0] == 1U) {        if (brytere[0] == true) {
137          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");
138          bryter1HarVartOppe = 1U;          bryter1HarVartOppe = true;
139    
140          brytere[1] = !brytere[1];          brytere[1] = !brytere[1];
141          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");
142        } // if        } // if
143        else {        else {
144          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");
145    
146          if (harVippetBryter1 == 0U && bryter1HarVartOppe == 1U) {          if (harVippetBryter1 == false && bryter1HarVartOppe == true) {
147            brytere[0] = !brytere[0];            brytere[0] = !brytere[0];
148            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");
149    
150            harVippetBryter1 = 1U;            harVippetBryter1 = true;
151          } // if          } // if
152          else {          else {
153            brytere[1] = !brytere[1];            brytere[1] = !brytere[1];
154            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");
155          } // else          } // else
156        } // else        } // else
157      } // else      } // else
158    
159      // Tusle ut av rommet.      // Tusle ut av rommet.
160      printf("livstidsfange %2zu låser opp mutex\n", i + 1);      printf("livstidsfange %2zu låser opp mutex\n", i + 1);
161      pthread_mutex_unlock(&mutex);      pthread_mutex_unlock(&mutex);
162      printf("livstidsfange %2zu har låst opp mutex\n", i + 1);      printf("livstidsfange %2zu har låst opp mutex\n", i + 1);
163    } // while    } // while
164  } // livstidsfange()  } // livstidsfange()
165    
166  void visResultater(void)  void visResultater(void)
167  {  {
168    size_t i;    size_t i;
169    


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

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