Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #ifndef CFUTURE_H_
- #define CFUTURE_H_
- #include <stdio.h>
- #include <pthread.h>
- #ifdef DEBUG
- #include <random>
- #include <limits>
- #endif // DEBUG
- #include "./type.h"
- namespace liam {
- namespace cstyle {
- #ifdef DEBUG
- #define msg(format, ...) \
- printf("T(%d)|" format "\n", static_cast<int>(pthread_self()), ##__VA_ARGS__)
- #else
- #define msg(format, ...)
- #endif
- struct future {
- pthread_t thread;
- pthread_attr_t attr;
- thread_routine_t func;
- };
- struct future_arg {
- thread_routine_t func;
- void* arg;
- };
- struct promise {
- int result;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- bool done;
- #ifdef DEBUG
- int id;
- #endif // DEBUG
- };
- inline future* future_create(thread_routine_t start_routine) {
- future* f = reinterpret_cast<future*>(malloc(sizeof(future)));
- pthread_attr_init(&f->attr);
- pthread_attr_setdetachstate(&f->attr, PTHREAD_CREATE_JOINABLE);
- f->func = start_routine;
- return f;
- }
- inline 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;
- }
- inline void future_start(future* f, void* arg) {
- future_arg* farg = reinterpret_cast<future_arg*>(malloc(sizeof(future_arg)));
- farg->func = f->func;
- farg->arg = arg;
- pthread_create(&f->thread, &f->attr, future_func_wrapper, farg);
- }
- inline void future_stop(future* f) {
- pthread_cancel(f->thread);
- }
- inline void future_close(future* f) {
- void* status;
- // int rc = pthread_join(f->thread, &status);
- pthread_join(f->thread, &status);
- pthread_attr_destroy(&f->attr);
- free(f);
- }
- inline promise* promise_create() {
- promise* p = reinterpret_cast<promise*>(malloc(sizeof(promise)));
- pthread_mutex_init(&p->mutex, NULL);
- pthread_cond_init(&p->cond, NULL);
- #ifdef DEBUG
- std::random_device rd;
- std::mt19937 urbg(rd());
- std::uniform_int_distribution<> rint(std::numeric_limits<int>::min(),
- std::numeric_limits<int>::max());
- p->id = rint(urbg);
- #endif // DEBUG
- msg("P(%d) created", p->id);
- return p;
- }
- inline 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;
- msg("P(%d) set UNLOCK", p->id);
- pthread_mutex_unlock(&p->mutex);
- pthread_cond_signal(&p->cond);
- }
- inline 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;
- }
- inline bool promise_done(promise* p) {
- pthread_mutex_lock(&p->mutex);
- bool done = p->done;
- pthread_mutex_unlock(&p->mutex);
- return done;
- }
- inline void promise_close(promise* p) {
- pthread_mutex_destroy(&p->mutex);
- pthread_cond_destroy(&p->cond);
- free(p);
- }
- } // namespace cstyle
- } // namespace liam
- #endif // CFUTURE_H_
Add Comment
Please, Sign In to add comment