thread.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2010, 2012-2013 Université de Bordeaux 1
  4. * Copyright (C) 2010, 2011, 2012, 2013 Centre National de la Recherche Scientifique
  5. *
  6. * StarPU is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation; either version 2.1 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * StarPU is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. *
  15. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  16. */
  17. #include <starpu.h>
  18. #include <common/thread.h>
  19. #include <core/simgrid.h>
  20. #ifdef STARPU_SIMGRID
  21. #include <xbt/synchro_core.h>
  22. #endif
  23. #ifdef STARPU_SIMGRID
  24. extern int _starpu_simgrid_thread_start(int argc, char *argv[]);
  25. int starpu_pthread_create_on(char *name, starpu_pthread_t *thread, const starpu_pthread_attr_t *attr, void *(*start_routine) (void *), void *arg, int where)
  26. {
  27. struct _starpu_pthread_args *_args = malloc(sizeof(*_args));
  28. xbt_dynar_t _hosts;
  29. _args->f = start_routine;
  30. _args->arg = arg;
  31. _hosts = MSG_hosts_as_dynar();
  32. MSG_process_create(name, _starpu_simgrid_thread_start, _args,
  33. xbt_dynar_get_as(_hosts, (where), msg_host_t));
  34. xbt_dynar_free(&_hosts);
  35. return 0;
  36. }
  37. int starpu_pthread_create(starpu_pthread_t *thread, const starpu_pthread_attr_t *attr, void *(*start_routine) (void *), void *arg)
  38. {
  39. return starpu_pthread_create_on("", thread, attr, start_routine, arg, 0);
  40. }
  41. int starpu_pthread_join(starpu_pthread_t thread, void **retval)
  42. {
  43. #ifdef STARPU_DEVEL
  44. #warning TODO: use a simgrid_join when it becomes available
  45. #endif
  46. MSG_process_sleep(1);
  47. return 0;
  48. }
  49. int starpu_pthread_attr_init(starpu_pthread_attr_t *attr)
  50. {
  51. return 0;
  52. }
  53. int starpu_pthread_attr_destroy(starpu_pthread_attr_t *attr)
  54. {
  55. return 0;
  56. }
  57. int starpu_pthread_attr_setdetachstate(starpu_pthread_attr_t *attr, int detachstate)
  58. {
  59. return 0;
  60. }
  61. int starpu_pthread_mutex_init(starpu_pthread_mutex_t *mutex, const starpu_pthread_mutexattr_t *mutexattr)
  62. {
  63. *mutex = xbt_mutex_init();
  64. return 0;
  65. }
  66. int starpu_pthread_mutex_destroy(starpu_pthread_mutex_t *mutex)
  67. {
  68. if (*mutex)
  69. xbt_mutex_destroy(*mutex);
  70. return 0;
  71. }
  72. int starpu_pthread_mutex_lock(starpu_pthread_mutex_t *mutex)
  73. {
  74. const char *file;
  75. file = strrchr(__FILE__,'/');
  76. file += sizeof(char);
  77. _STARPU_TRACE_LOCKING_MUTEX(file,__LINE__);
  78. if (!*mutex) STARPU_PTHREAD_MUTEX_INIT(mutex, NULL);
  79. xbt_mutex_acquire(*mutex);
  80. file = strrchr(__FILE__,'/');
  81. file += sizeof(char);
  82. _STARPU_TRACE_MUTEX_LOCKED(file,__LINE__);
  83. return 0;
  84. }
  85. int starpu_pthread_mutex_unlock(starpu_pthread_mutex_t *mutex)
  86. {
  87. const char *file;
  88. file = strrchr(__FILE__,'/');
  89. file += sizeof(char);
  90. _STARPU_TRACE_UNLOCKING_MUTEX(file,__LINE__);
  91. xbt_mutex_release(*mutex);
  92. file = strrchr(__FILE__,'/');
  93. file += sizeof(char);
  94. _STARPU_TRACE_MUTEX_UNLOCKED(file,__LINE__);
  95. return 0;
  96. }
  97. int starpu_pthread_mutex_trylock(starpu_pthread_mutex_t *mutex)
  98. {
  99. const char *file;
  100. file = strrchr(__FILE__,'/');
  101. file += sizeof(char);
  102. _STARPU_TRACE_TRYLOCK_MUTEX(file,__LINE__);
  103. xbt_mutex_acquire(*mutex);
  104. return 0;
  105. }
  106. static int used_key[MAX_TSD];
  107. int starpu_pthread_key_create(starpu_pthread_key_t *key, void (*destr_function) (void *))
  108. {
  109. unsigned i;
  110. /* Note: no synchronization here, we are actually monothreaded anyway. */
  111. for (i = 0; i < MAX_TSD; i++)
  112. if (!used_key[i])
  113. {
  114. used_key[i] = 1;
  115. break;
  116. }
  117. STARPU_ASSERT(i < MAX_TSD);
  118. *key = i;
  119. return 0;
  120. }
  121. int starpu_pthread_key_delete(starpu_pthread_key_t key)
  122. {
  123. used_key[key] = 0;
  124. return 0;
  125. }
  126. int starpu_pthread_setspecific(starpu_pthread_key_t key, const void *pointer)
  127. {
  128. void **array = MSG_host_get_data(MSG_host_self());
  129. array[key] = pointer;
  130. return 0;
  131. }
  132. void* starpu_pthread_getspecific(starpu_pthread_key_t key)
  133. {
  134. void **array = MSG_host_get_data(MSG_host_self());
  135. return array[key];
  136. }
  137. int starpu_pthread_cond_init(starpu_pthread_cond_t *cond, starpu_pthread_condattr_t *cond_attr)
  138. {
  139. *cond = xbt_cond_init();
  140. return 0;
  141. }
  142. int starpu_pthread_cond_signal(starpu_pthread_cond_t *cond)
  143. {
  144. if (!*cond)
  145. STARPU_PTHREAD_COND_INIT(cond, NULL);
  146. xbt_cond_signal(*cond);
  147. return 0;
  148. }
  149. int starpu_pthread_cond_broadcast(starpu_pthread_cond_t *cond)
  150. {
  151. if (!*cond)
  152. STARPU_PTHREAD_COND_INIT(cond, NULL);
  153. xbt_cond_broadcast(*cond);
  154. return 0;
  155. }
  156. int starpu_pthread_cond_wait(starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex)
  157. {
  158. const char* file;
  159. file = strrchr(__FILE__,'/');
  160. file += sizeof(char);
  161. _STARPU_TRACE_COND_WAIT_BEGIN(file,__LINE__);
  162. if (!*cond)
  163. STARPU_PTHREAD_COND_INIT(cond, NULL);
  164. xbt_cond_wait(*cond, *mutex);
  165. file = strrchr(__FILE__,'/');
  166. file += sizeof(char);
  167. _STARPU_TRACE_COND_WAIT_END(file,__LINE__);
  168. return 0;
  169. }
  170. int starpu_pthread_cond_destroy(starpu_pthread_cond_t *cond)
  171. {
  172. if (*cond)
  173. xbt_cond_destroy(*cond);
  174. return 0;
  175. }
  176. int starpu_pthread_rwlock_init(starpu_pthread_rwlock_t *restrict rwlock, const starpu_pthread_rwlockattr_t *restrict attr)
  177. {
  178. return starpu_pthread_mutex_init(rwlock, attr);
  179. }
  180. int starpu_pthread_rwlock_destroy(starpu_pthread_rwlock_t *rwlock)
  181. {
  182. return starpu_pthread_mutex_destroy(rwlock);
  183. }
  184. int starpu_pthread_rwlock_rdlock(starpu_pthread_rwlock_t *rwlock)
  185. {
  186. const char* file;
  187. file = strrchr(__FILE__,'/');
  188. file += sizeof(char);
  189. _STARPU_TRACE_RDLOCKING_RWLOCK(file,__LINE__);
  190. int p_ret = starpu_pthread_mutex_lock(rwlock);
  191. file = strrchr(__FILE__,'/');
  192. file += sizeof(char);
  193. _STARPU_TRACE_RWLOCK_RDLOCKED(file,__LINE__);
  194. return p_ret;
  195. }
  196. int starpu_pthread_rwlock_wrlock(starpu_pthread_rwlock_t *rwlock)
  197. {
  198. const char* file;
  199. file = strrchr(__FILE__,'/');
  200. file += sizeof(char);
  201. _STARPU_TRACE_WRLOCKING_RWLOCK(file,__LINE__);
  202. int p_ret = starpu_pthread_mutex_lock(rwlock);
  203. file = strrchr(__FILE__,'/');
  204. file += sizeof(char);
  205. _STARPU_TRACE_RWLOCK_WRLOCKED(file,__LINE__);
  206. return p_ret;
  207. }
  208. int starpu_pthread_rwlock_unlock(starpu_pthread_rwlock_t *rwlock)
  209. {
  210. const char* file;
  211. file = strrchr(__FILE__,'/');
  212. file += sizeof(char);
  213. _STARPU_TRACE_UNLOCKING_RWLOCK(file,__LINE__);
  214. int p_ret = starpu_pthread_mutex_unlock(rwlock);
  215. file = strrchr(__FILE__,'/');
  216. file += sizeof(char);
  217. _STARPU_TRACE_RWLOCK_UNLOCKED(file,__LINE__);
  218. return p_ret;
  219. }
  220. #elif !defined(_MSC_VER) /* !STARPU_SIMGRID */
  221. int starpu_pthread_mutex_lock(starpu_pthread_mutex_t *mutex)
  222. {
  223. const char *file;
  224. file = strrchr(__FILE__,'/');
  225. file += sizeof(char);
  226. _STARPU_TRACE_LOCKING_MUTEX(file,__LINE__);
  227. int p_ret = pthread_mutex_lock(mutex);
  228. file = strrchr(__FILE__,'/');
  229. file += sizeof(char);
  230. _STARPU_TRACE_MUTEX_LOCKED(file,__LINE__);
  231. return p_ret;
  232. }
  233. int starpu_pthread_mutex_unlock(starpu_pthread_mutex_t *mutex)
  234. {
  235. const char *file;
  236. file = strrchr(__FILE__,'/');
  237. file += sizeof(char);
  238. _STARPU_TRACE_UNLOCKING_MUTEX(file,__LINE__);
  239. int p_ret = pthread_mutex_unlock(mutex);
  240. file = strrchr(__FILE__,'/');
  241. file += sizeof(char);
  242. _STARPU_TRACE_MUTEX_UNLOCKED(file,__LINE__);
  243. return p_ret;
  244. }
  245. int starpu_pthread_mutex_trylock(starpu_pthread_mutex_t *mutex)
  246. {
  247. const char *file;
  248. file = strrchr(__FILE__,'/');
  249. file += sizeof(char);
  250. _STARPU_TRACE_LOCKING_MUTEX(file,__LINE__);
  251. return pthread_mutex_trylock(mutex);
  252. }
  253. int starpu_pthread_cond_wait(starpu_pthread_cond_t *cond, starpu_pthread_mutex_t *mutex)
  254. {
  255. const char* file;
  256. file = strrchr(__FILE__,'/');
  257. file += sizeof(char);
  258. _STARPU_TRACE_COND_WAIT_BEGIN(file,__LINE__);
  259. int p_ret = pthread_cond_wait(cond, mutex);
  260. file = strrchr(__FILE__,'/');
  261. file += sizeof(char);
  262. _STARPU_TRACE_COND_WAIT_END(file,__LINE__);
  263. return p_ret;
  264. }
  265. int starpu_pthread_rwlock_rdlock(starpu_pthread_rwlock_t *rwlock)
  266. {
  267. const char* file;
  268. file = strrchr(__FILE__,'/');
  269. file += sizeof(char);
  270. _STARPU_TRACE_RDLOCKING_RWLOCK(file,__LINE__);
  271. int p_ret = pthread_rwlock_rdlock(rwlock);
  272. file = strrchr(__FILE__,'/');
  273. file += sizeof(char);
  274. _STARPU_TRACE_RWLOCK_RDLOCKED(file,__LINE__);
  275. return p_ret;
  276. }
  277. int starpu_pthread_rwlock_wrlock(starpu_pthread_rwlock_t *rwlock)
  278. {
  279. const char* file;
  280. file = strrchr(__FILE__,'/');
  281. file += sizeof(char);
  282. _STARPU_TRACE_WRLOCKING_RWLOCK(file,__LINE__);
  283. int p_ret = pthread_rwlock_wrlock(rwlock);
  284. file = strrchr(__FILE__,'/');
  285. file += sizeof(char);
  286. _STARPU_TRACE_RWLOCK_WRLOCKED(file,__LINE__);
  287. return p_ret;
  288. }
  289. int starpu_pthread_rwlock_unlock(starpu_pthread_rwlock_t *rwlock)
  290. {
  291. const char* file;
  292. file = strrchr(__FILE__,'/');
  293. file += sizeof(char);
  294. _STARPU_TRACE_UNLOCKING_RWLOCK(file,__LINE__);
  295. int p_ret = pthread_rwlock_unlock(rwlock);
  296. file = strrchr(__FILE__,'/');
  297. file += sizeof(char);
  298. _STARPU_TRACE_RWLOCK_UNLOCKED(file,__LINE__);
  299. return p_ret;
  300. }
  301. #endif /* STARPU_SIMGRID, _MSC_VER */