Skip to content

Instantly share code, notes, and snippets.

@debuti
Last active March 30, 2020 15:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save debuti/d574b1eb1b40c7a1450e82d09241a781 to your computer and use it in GitHub Desktop.
Save debuti/d574b1eb1b40c7a1450e82d09241a781 to your computer and use it in GitHub Desktop.
Lamport's bakery in C
#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);
}
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