Created
October 21, 2021 14:38
-
-
Save sitano/bcd52ebb25eff044c0ecd03990452d05 to your computer and use it in GitHub Desktop.
experimenting with cond signal and ruby scheduler
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
#define _MULTI_THREADED | |
#include <pthread.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <fcntl.h> | |
/* For safe condition variable usage, must use a boolean predicate and */ | |
/* a mutex with the condition. */ | |
int acquired = 0; | |
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | |
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | |
#define NTHREADS 5 | |
void check(const char *str, int err) { | |
if (err) | |
printf("[%d] err=%d: %s", gettid(), err, str); | |
} | |
void acq(int id) { | |
check("lock()", pthread_mutex_lock(&mutex)); | |
while (acquired) { | |
printf("[%d] %d: wait\n", gettid(), id); | |
check("pthread_cond_wait()\n", pthread_cond_wait(&cond, &mutex)); | |
} | |
printf("[%d] %d: acq\n", gettid(), id); | |
acquired = 1; | |
check("unlock()", pthread_mutex_unlock(&mutex)); | |
} | |
void rel(int id) { | |
check("lock()", pthread_mutex_lock(&mutex)); | |
printf("[%d] %d: rel\n", gettid(), id); | |
acquired = 0; | |
pthread_cond_signal(&cond); | |
check("unlock()", pthread_mutex_unlock(&mutex)); | |
} | |
void *threadfunc(void *parm) { | |
char buf[4096]; | |
while (1) { | |
acq((int)parm); | |
int fd = open("/dev/null", "w"); | |
if (!fd) { | |
printf("bad bad bad: %s\n", strerror(errno)); | |
} | |
for (int i = 0; i < 1000; i ++) { | |
write(fd, buf, 4096); | |
} | |
close(fd); | |
rel((int)parm); | |
} | |
return NULL; | |
} | |
int main(int argc, char **argv) { | |
int rc=0; | |
int i; | |
pthread_t threadid[NTHREADS]; | |
printf("Create %d threads\n", NTHREADS); | |
for(i=0; i<NTHREADS; ++i) { | |
check("pthread_create()", pthread_create(&threadid[i], NULL, threadfunc, (i+1))); | |
} | |
while (1) { | |
sleep(1); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
output:
acquisitions only by 1 thread
so that Ruby also can't reschedule until winning thread waits on separate yield cond