Guest User

Untitled

a guest
Jan 17th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.89 KB | None | 0 0
  1. #pragma once
  2.  
  3. #ifndef CFUTURE_H_
  4. #define CFUTURE_H_
  5.  
  6. #include <stdio.h>
  7. #include <pthread.h>
  8.  
  9. #ifdef DEBUG
  10. #include <random>
  11. #include <limits>
  12. #endif // DEBUG
  13.  
  14. #include "./type.h"
  15.  
  16. namespace liam {
  17. namespace cstyle {
  18. #ifdef DEBUG
  19. #define msg(format, ...) \
  20. printf("T(%d)|" format "\n", static_cast<int>(pthread_self()), ##__VA_ARGS__)
  21. #else
  22. #define msg(format, ...)
  23. #endif
  24.  
  25. struct future {
  26. pthread_t thread;
  27. pthread_attr_t attr;
  28. thread_routine_t func;
  29. };
  30.  
  31. struct future_arg {
  32. thread_routine_t func;
  33. void* arg;
  34. };
  35.  
  36. struct promise {
  37. int result;
  38. pthread_mutex_t mutex;
  39. pthread_cond_t cond;
  40. bool done;
  41. #ifdef DEBUG
  42. int id;
  43. #endif // DEBUG
  44. };
  45.  
  46. inline future* future_create(thread_routine_t start_routine) {
  47. future* f = reinterpret_cast<future*>(malloc(sizeof(future)));
  48.  
  49. pthread_attr_init(&f->attr);
  50. pthread_attr_setdetachstate(&f->attr, PTHREAD_CREATE_JOINABLE);
  51.  
  52. f->func = start_routine;
  53.  
  54. return f;
  55. }
  56.  
  57. inline void* future_func_wrapper(void* arg) {
  58. //msg("WRAP");
  59. future_arg* f = (future_arg*) arg;
  60. void* res = f->func(f->arg);
  61. free(f);
  62. //msg("WRAPPED");
  63. pthread_exit(res);
  64. return res;
  65. }
  66.  
  67. inline void future_start(future* f, void* arg) {
  68. future_arg* farg = reinterpret_cast<future_arg*>(malloc(sizeof(future_arg)));
  69. farg->func = f->func;
  70. farg->arg = arg;
  71. pthread_create(&f->thread, &f->attr, future_func_wrapper, farg);
  72. }
  73.  
  74. inline void future_stop(future* f) {
  75. pthread_cancel(f->thread);
  76. }
  77.  
  78. inline void future_close(future* f) {
  79. void* status;
  80. // int rc = pthread_join(f->thread, &status);
  81. pthread_join(f->thread, &status);
  82. pthread_attr_destroy(&f->attr);
  83. free(f);
  84. }
  85.  
  86. inline promise* promise_create() {
  87. promise* p = reinterpret_cast<promise*>(malloc(sizeof(promise)));
  88.  
  89. pthread_mutex_init(&p->mutex, NULL);
  90. pthread_cond_init(&p->cond, NULL);
  91. #ifdef DEBUG
  92. std::random_device rd;
  93. std::mt19937 urbg(rd());
  94. std::uniform_int_distribution<> rint(std::numeric_limits<int>::min(),
  95. std::numeric_limits<int>::max());
  96. p->id = rint(urbg);
  97. #endif // DEBUG
  98. msg("P(%d) created", p->id);
  99. return p;
  100. }
  101.  
  102. inline void promise_set(promise* p, int res) {
  103. msg("P(%d) set LOCK", p->id);
  104. pthread_mutex_lock(&p->mutex);
  105. p->result = res;
  106. p->done = true;
  107. msg("P(%d) set UNLOCK", p->id);
  108. pthread_mutex_unlock(&p->mutex);
  109. pthread_cond_signal(&p->cond);
  110. }
  111.  
  112. inline int promise_get(promise* p) {
  113. msg("P(%d) get LOCK", p->id);
  114. pthread_mutex_lock(&p->mutex);
  115. while(!p->done) {
  116. msg("P(%d) get WAIT", p->id);
  117. pthread_cond_wait(&p->cond, &p->mutex);
  118. }
  119. msg("P(%d) get UNLOCK", p->id);
  120. pthread_mutex_unlock(&p->mutex);
  121. return p->result;
  122. }
  123.  
  124. inline bool promise_done(promise* p) {
  125. pthread_mutex_lock(&p->mutex);
  126. bool done = p->done;
  127. pthread_mutex_unlock(&p->mutex);
  128. return done;
  129. }
  130.  
  131. inline void promise_close(promise* p) {
  132. pthread_mutex_destroy(&p->mutex);
  133. pthread_cond_destroy(&p->cond);
  134. free(p);
  135. }
  136. } // namespace cstyle
  137. } // namespace liam
  138. #endif // CFUTURE_H_
Add Comment
Please, Sign In to add comment