-
-
Save sachinites/893a548803beb7f0c0439df9bf0a47bc to your computer and use it in GitHub Desktop.
small future and promise library in C with pthreads
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 <stdio.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <stdbool.h> | |
#include <time.h> | |
#include <stdarg.h> | |
#include <string.h> | |
#include "future.h" | |
future* future_create(void *(*start_routine) (void *)) { | |
future* f = malloc(sizeof(future)); | |
pthread_attr_init(&f->attr); | |
pthread_attr_setdetachstate(&f->attr, PTHREAD_CREATE_JOINABLE); | |
f->func = start_routine; | |
srand(time(NULL)); | |
f->id = rand(); | |
return f; | |
} | |
void* future_func_wrapper(void *arg) { | |
//msg("WRAP"); | |
future_arg* f = (future_arg*) arg; | |
void* res = f->func(f->arg); | |
free(f); | |
//msg("WRAPPED"); | |
pthread_exit(res); | |
return res; | |
} | |
void future_start(future* f, void* arg) { | |
future_arg* farg = malloc(sizeof(future_arg)); | |
farg->func = f->func; | |
farg->arg = arg; | |
pthread_create(&f->thread, &f->attr, future_func_wrapper, farg); | |
} | |
void future_stop(future* f) { | |
pthread_cancel(f->thread); | |
} | |
void future_close(future* f) { | |
void * status; | |
int rc = pthread_join(f->thread, &status); | |
pthread_attr_destroy(&f->attr); | |
free(f); | |
} | |
promise* promise_create() { | |
promise* p = malloc(sizeof(promise)); | |
pthread_mutex_init(&p->mutex, NULL); | |
pthread_cond_init(&p->cond, NULL); | |
srand(time(NULL)); | |
p->id = rand(); | |
msg("P(%d) created", p->id); | |
return p; | |
} | |
void promise_set(promise* p, int res) { | |
msg("P(%d) set LOCK", p->id); | |
pthread_mutex_lock(&p->mutex); | |
p->result = res; | |
p->done = true; | |
pthread_cond_signal(&p->cond); | |
msg("P(%d) set UNLOCK", p->id); | |
pthread_mutex_unlock(&p->mutex); | |
} | |
int promise_get(promise* p) { | |
msg("P(%d) get LOCK", p->id); | |
pthread_mutex_lock(&p->mutex); | |
while(!p->done) { | |
msg("P(%d) get WAIT", p->id); | |
pthread_cond_wait(&p->cond, &p->mutex); | |
} | |
msg("P(%d) get UNLOCK", p->id); | |
pthread_mutex_unlock(&p->mutex); | |
return p->result; | |
} | |
bool promise_done(promise* p) { | |
pthread_mutex_lock(&p->mutex); | |
bool done = p->done; | |
pthread_mutex_unlock(&p->mutex); | |
return done; | |
} | |
void promise_close(promise* p) { | |
pthread_mutex_destroy(&p->mutex); | |
pthread_cond_destroy(&p->cond); | |
free(p); | |
} |
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 <stdbool.h> | |
typedef struct _future { | |
pthread_t thread; | |
pthread_attr_t attr; | |
void *(*func) (void *); | |
} future; | |
typedef struct _future_arg { | |
void *(*func) (void *); | |
void * arg; | |
} future_arg; | |
typedef struct _promise { | |
int result; | |
pthread_mutex_t mutex; | |
pthread_cond_t cond; | |
bool done; | |
int id; | |
} promise; | |
future* future_create(void *(*start_routine) (void *)); | |
void future_start(future* f, void* arg); | |
void future_stop(future* f); | |
void future_close(future* f); | |
promise* promise_create(); | |
int promise_get(promise* p); | |
void promise_set(promise *p, int res); | |
bool promise_done(promise* p); | |
void promise_close(promise *p); | |
#ifdef DEBUG | |
#define msg(format, ...) printf("T(%d)|" format "\n", (int)pthread_self(), ##__VA_ARGS__) | |
#else | |
#define msg(format, ...)· | |
#endif |
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 <stdio.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <stdbool.h> | |
#include "future/future.h" | |
void* func(void * arg) { | |
promise* p = (promise*) arg; | |
printf("\tstarted thread\n"); | |
sleep(3); | |
printf("\tthread will set promise\n"); | |
promise_set(p, 42); | |
printf("\tstopping thread\n"); | |
return NULL; | |
} | |
int main() { | |
long t; | |
printf("main thread\n"); | |
future* f = future_create(func); | |
promise* p = promise_create(); | |
future_start(f, p); | |
printf("got result from future: %d\n", promise_get(p)); | |
promise_close(p); | |
future_close(f); | |
pthread_exit(NULL); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment