Last active
March 30, 2020 15:48
-
-
Save debuti/d574b1eb1b40c7a1450e82d09241a781 to your computer and use it in GitHub Desktop.
Lamport's bakery in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pthread.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <inttypes.h> | |
#include <errno.h> | |
#define NUM_THREADS 3 | |
#define NUM_SECTIONS 1 | |
volatile int i = 0; | |
uint8_t joining[NUM_SECTIONS][NUM_THREADS]={0!=0}; | |
uint64_t numbers[NUM_SECTIONS][NUM_THREADS]={0}; | |
uint64_t max(long sid) { | |
uint64_t result = 0; | |
for (int idx = 0; idx < NUM_THREADS; idx++) | |
if (numbers[sid][idx]>result) result = numbers[sid][idx]; | |
return result; | |
} | |
void lock(long sid, long pid) { | |
joining[sid][pid] = (0==0); | |
numbers[sid][pid] = 1 + max(sid); | |
joining[sid][pid] = (0!=0); | |
for (int idx=0; idx < NUM_THREADS; idx++) { | |
while (joining[sid][idx]) {} | |
while ((numbers[sid][idx] != 0) && | |
(numbers[sid][idx]<numbers[sid][pid] || | |
(numbers[sid][idx]==numbers[sid][pid] && idx<pid))) {} | |
} | |
} | |
void unlock(long sid, long pid) { | |
numbers[sid][pid] = 0; | |
} | |
void *thr(void *threadid) { | |
long tid = (long)threadid; | |
printf("[%ld]\n", tid); | |
lock(0, tid); | |
#ifdef DEBUG | |
printf("Joining: "); for (int idx=0; idx < NUM_THREADS; idx++) printf("%d,", joining[0][idx]); printf("\n"); | |
printf("Numbers: "); for (int idx=0; idx < NUM_THREADS; idx++) printf("%ld,", numbers[0][idx]); printf("\n"); | |
#endif | |
i = 0; | |
for (int idx = 0; idx < 1000000000; idx++) i = i + 1; | |
unlock(0, tid); | |
pthread_exit(NULL); | |
} | |
void main () { | |
pthread_t threads[NUM_THREADS]; | |
pthread_attr_t attr; | |
void *status; | |
int rc; | |
pthread_attr_init(&attr); | |
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); | |
for(long t=0; t<NUM_THREADS; t++){ | |
printf("[M] creating thread %ld\n", t); | |
rc = pthread_create(&threads[t], &attr, thr, (void *)t); | |
if (rc) { | |
printf("[M] ERROR; return code from pthread_create() is %d\n", rc); | |
exit(-1); | |
} | |
} | |
for(long t=0; t<NUM_THREADS; t++) { | |
rc = pthread_join(threads[t], &status); | |
if (rc) { | |
printf("[M] ERROR; return code from pthread_join() is %d\n", rc); | |
exit(-1); | |
} | |
printf("[M] completed join with thread %ld having a status of %ld\n",t,(long)status); | |
} | |
printf("i = %d\n", i); // Should print 1000000000 | |
pthread_attr_destroy(&attr); | |
pthread_exit(NULL); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PROG = bakery | |
all: clean $(PROG) | |
$(PROG): $(PROG).c | |
gcc -g -o $@ -pthread -O0 $(CFLAGS) $< | |
clean: | |
-rm $(PROG) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment