Skip to content

Instantly share code, notes, and snippets.

@Geal
Last active June 5, 2024 06:49
Show Gist options
  • Select an option

  • Save Geal/8f85e02561d101decf9a to your computer and use it in GitHub Desktop.

Select an option

Save Geal/8f85e02561d101decf9a to your computer and use it in GitHub Desktop.

Revisions

  1. Geal revised this gist Oct 20, 2014. 3 changed files with 49 additions and 17 deletions.
    41 changes: 30 additions & 11 deletions future.c
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,9 @@
    #include <pthread.h>
    #include <unistd.h>
    #include <stdbool.h>
    #include <time.h>
    #include <stdarg.h>
    #include <string.h>

    #include "future.h"

    @@ -13,12 +16,30 @@ future* future_create(void *(*start_routine) (void *)) {
    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) {
    pthread_create(&f->thread, &f->attr, f->func, 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) {
    @@ -32,33 +53,31 @@ 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) {
    printf("promise_set LOCK\n");
    msg("P(%d) set LOCK", p->id);
    pthread_mutex_lock(&p->mutex);
    p->result = res;
    p->done = true;
    if(p->done) {
    printf("promise is done\n");
    } else {
    printf("promise is not done\n");
    }
    pthread_cond_signal(&p->cond);
    printf("promise_set UNLOCK\n");
    msg("P(%d) set UNLOCK", p->id);
    pthread_mutex_unlock(&p->mutex);
    }

    int promise_get(promise* p) {
    printf("promise_get LOCK\n");
    msg("P(%d) get LOCK", p->id);
    pthread_mutex_lock(&p->mutex);
    while(!p->done) {
    printf("promise_get WAIT\n");
    msg("P(%d) get WAIT", p->id);
    pthread_cond_wait(&p->cond, &p->mutex);
    }
    printf("promise_get UNLOCK\n");
    msg("P(%d) get UNLOCK", p->id);
    pthread_mutex_unlock(&p->mutex);
    return p->result;
    }
    15 changes: 14 additions & 1 deletion future.h
    Original file line number Diff line number Diff line change
    @@ -6,19 +6,32 @@ typedef struct _future {
    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);
    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
    10 changes: 5 additions & 5 deletions main.c
    Original file line number Diff line number Diff line change
    @@ -6,23 +6,23 @@

    #include "future/future.h"

    promise* p;

    void* func(void *threadId) {
    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");
    pthread_exit(NULL);
    return NULL;
    }

    int main() {
    long t;
    printf("main thread\n");
    future* f = future_create(func);
    p = promise_create();
    future_start(f, NULL);
    promise* p = promise_create();
    future_start(f, p);

    printf("got result from future: %d\n", promise_get(p));

  2. Geal created this gist Oct 20, 2014.
    77 changes: 77 additions & 0 deletions future.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,77 @@
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <stdbool.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;

    return f;
    }

    void future_start(future* f, void* arg) {
    pthread_create(&f->thread, &f->attr, f->func, arg);
    }

    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);

    return p;
    }

    void promise_set(promise* p, int res) {
    printf("promise_set LOCK\n");
    pthread_mutex_lock(&p->mutex);
    p->result = res;
    p->done = true;
    if(p->done) {
    printf("promise is done\n");
    } else {
    printf("promise is not done\n");
    }
    pthread_cond_signal(&p->cond);
    printf("promise_set UNLOCK\n");
    pthread_mutex_unlock(&p->mutex);
    }

    int promise_get(promise* p) {
    printf("promise_get LOCK\n");
    pthread_mutex_lock(&p->mutex);
    while(!p->done) {
    printf("promise_get WAIT\n");
    pthread_cond_wait(&p->cond, &p->mutex);
    }
    printf("promise_get UNLOCK\n");
    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);
    }
    24 changes: 24 additions & 0 deletions future.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    #include <stdbool.h>

    typedef struct _future {
    pthread_t thread;
    pthread_attr_t attr;
    void *(*func) (void *);
    } future;

    typedef struct _promise {
    int result;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    bool done;
    } promise;

    future* future_create(void *(*start_routine) (void *));
    void future_start(future* f, void* arg);
    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);
    32 changes: 32 additions & 0 deletions main.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <stdbool.h>

    #include "future/future.h"

    promise* p;

    void* func(void *threadId) {
    printf("\tstarted thread\n");
    sleep(3);
    printf("\tthread will set promise\n");
    promise_set(p, 42);
    printf("\tstopping thread\n");
    pthread_exit(NULL);
    }

    int main() {
    long t;
    printf("main thread\n");
    future* f = future_create(func);
    p = promise_create();
    future_start(f, NULL);

    printf("got result from future: %d\n", promise_get(p));

    promise_close(p);
    future_close(f);
    pthread_exit(NULL);
    }