PageRenderTime 27ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/edk2/AppPkg/Applications/Python/Python-2.7.2/Python/thread_pthread.h

https://gitlab.com/envieidoc/Clover
C Header | 505 lines | 341 code | 85 blank | 79 comment | 58 complexity | 2e6b6df9244df39b2ed0d55b483f4245 MD5 | raw file
  1. /* Posix threads interface */
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
  5. #define destructor xxdestructor
  6. #endif
  7. #include <pthread.h>
  8. #if defined(__APPLE__) || defined(HAVE_PTHREAD_DESTRUCTOR)
  9. #undef destructor
  10. #endif
  11. #include <signal.h>
  12. /* The POSIX spec requires that use of pthread_attr_setstacksize
  13. be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
  14. #ifdef _POSIX_THREAD_ATTR_STACKSIZE
  15. #ifndef THREAD_STACK_SIZE
  16. #define THREAD_STACK_SIZE 0 /* use default stack size */
  17. #endif
  18. #if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
  19. /* The default stack size for new threads on OSX is small enough that
  20. * we'll get hard crashes instead of 'maximum recursion depth exceeded'
  21. * exceptions.
  22. *
  23. * The default stack size below is the minimal stack size where a
  24. * simple recursive function doesn't cause a hard crash.
  25. */
  26. #undef THREAD_STACK_SIZE
  27. #define THREAD_STACK_SIZE 0x400000
  28. #endif
  29. /* for safety, ensure a viable minimum stacksize */
  30. #define THREAD_STACK_MIN 0x8000 /* 32kB */
  31. #else /* !_POSIX_THREAD_ATTR_STACKSIZE */
  32. #ifdef THREAD_STACK_SIZE
  33. #error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
  34. #endif
  35. #endif
  36. /* The POSIX spec says that implementations supporting the sem_*
  37. family of functions must indicate this by defining
  38. _POSIX_SEMAPHORES. */
  39. #ifdef _POSIX_SEMAPHORES
  40. /* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
  41. we need to add 0 to make it work there as well. */
  42. #if (_POSIX_SEMAPHORES+0) == -1
  43. #define HAVE_BROKEN_POSIX_SEMAPHORES
  44. #else
  45. #include <semaphore.h>
  46. #include <errno.h>
  47. #endif
  48. #endif
  49. /* Before FreeBSD 5.4, system scope threads was very limited resource
  50. in default setting. So the process scope is preferred to get
  51. enough number of threads to work. */
  52. #ifdef __FreeBSD__
  53. #include <osreldate.h>
  54. #if __FreeBSD_version >= 500000 && __FreeBSD_version < 504101
  55. #undef PTHREAD_SYSTEM_SCHED_SUPPORTED
  56. #endif
  57. #endif
  58. #if !defined(pthread_attr_default)
  59. # define pthread_attr_default ((pthread_attr_t *)NULL)
  60. #endif
  61. #if !defined(pthread_mutexattr_default)
  62. # define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL)
  63. #endif
  64. #if !defined(pthread_condattr_default)
  65. # define pthread_condattr_default ((pthread_condattr_t *)NULL)
  66. #endif
  67. /* Whether or not to use semaphores directly rather than emulating them with
  68. * mutexes and condition variables:
  69. */
  70. #if defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES)
  71. # define USE_SEMAPHORES
  72. #else
  73. # undef USE_SEMAPHORES
  74. #endif
  75. /* On platforms that don't use standard POSIX threads pthread_sigmask()
  76. * isn't present. DEC threads uses sigprocmask() instead as do most
  77. * other UNIX International compliant systems that don't have the full
  78. * pthread implementation.
  79. */
  80. #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
  81. # define SET_THREAD_SIGMASK pthread_sigmask
  82. #else
  83. # define SET_THREAD_SIGMASK sigprocmask
  84. #endif
  85. /* A pthread mutex isn't sufficient to model the Python lock type
  86. * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
  87. * following are undefined:
  88. * -> a thread tries to lock a mutex it already has locked
  89. * -> a thread tries to unlock a mutex locked by a different thread
  90. * pthread mutexes are designed for serializing threads over short pieces
  91. * of code anyway, so wouldn't be an appropriate implementation of
  92. * Python's locks regardless.
  93. *
  94. * The pthread_lock struct implements a Python lock as a "locked?" bit
  95. * and a <condition, mutex> pair. In general, if the bit can be acquired
  96. * instantly, it is, else the pair is used to block the thread until the
  97. * bit is cleared. 9 May 1994 tim@ksr.com
  98. */
  99. typedef struct {
  100. char locked; /* 0=unlocked, 1=locked */
  101. /* a <cond, mutex> pair to handle an acquire of a locked lock */
  102. pthread_cond_t lock_released;
  103. pthread_mutex_t mut;
  104. } pthread_lock;
  105. #define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
  106. /*
  107. * Initialization.
  108. */
  109. #ifdef _HAVE_BSDI
  110. static
  111. void _noop(void)
  112. {
  113. }
  114. static void
  115. PyThread__init_thread(void)
  116. {
  117. /* DO AN INIT BY STARTING THE THREAD */
  118. static int dummy = 0;
  119. pthread_t thread1;
  120. pthread_create(&thread1, NULL, (void *) _noop, &dummy);
  121. pthread_join(thread1, NULL);
  122. }
  123. #else /* !_HAVE_BSDI */
  124. static void
  125. PyThread__init_thread(void)
  126. {
  127. #if defined(_AIX) && defined(__GNUC__)
  128. pthread_init();
  129. #endif
  130. }
  131. #endif /* !_HAVE_BSDI */
  132. /*
  133. * Thread support.
  134. */
  135. long
  136. PyThread_start_new_thread(void (*func)(void *), void *arg)
  137. {
  138. pthread_t th;
  139. int status;
  140. #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
  141. pthread_attr_t attrs;
  142. #endif
  143. #if defined(THREAD_STACK_SIZE)
  144. size_t tss;
  145. #endif
  146. dprintf(("PyThread_start_new_thread called\n"));
  147. if (!initialized)
  148. PyThread_init_thread();
  149. #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
  150. if (pthread_attr_init(&attrs) != 0)
  151. return -1;
  152. #endif
  153. #if defined(THREAD_STACK_SIZE)
  154. tss = (_pythread_stacksize != 0) ? _pythread_stacksize
  155. : THREAD_STACK_SIZE;
  156. if (tss != 0) {
  157. if (pthread_attr_setstacksize(&attrs, tss) != 0) {
  158. pthread_attr_destroy(&attrs);
  159. return -1;
  160. }
  161. }
  162. #endif
  163. #if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
  164. pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
  165. #endif
  166. status = pthread_create(&th,
  167. #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
  168. &attrs,
  169. #else
  170. (pthread_attr_t*)NULL,
  171. #endif
  172. (void* (*)(void *))func,
  173. (void *)arg
  174. );
  175. #if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
  176. pthread_attr_destroy(&attrs);
  177. #endif
  178. if (status != 0)
  179. return -1;
  180. pthread_detach(th);
  181. #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
  182. return (long) th;
  183. #else
  184. return (long) *(long *) &th;
  185. #endif
  186. }
  187. /* XXX This implementation is considered (to quote Tim Peters) "inherently
  188. hosed" because:
  189. - It does not guarantee the promise that a non-zero integer is returned.
  190. - The cast to long is inherently unsafe.
  191. - It is not clear that the 'volatile' (for AIX?) and ugly casting in the
  192. latter return statement (for Alpha OSF/1) are any longer necessary.
  193. */
  194. long
  195. PyThread_get_thread_ident(void)
  196. {
  197. volatile pthread_t threadid;
  198. if (!initialized)
  199. PyThread_init_thread();
  200. /* Jump through some hoops for Alpha OSF/1 */
  201. threadid = pthread_self();
  202. #if SIZEOF_PTHREAD_T <= SIZEOF_LONG
  203. return (long) threadid;
  204. #else
  205. return (long) *(long *) &threadid;
  206. #endif
  207. }
  208. void
  209. PyThread_exit_thread(void)
  210. {
  211. dprintf(("PyThread_exit_thread called\n"));
  212. if (!initialized) {
  213. exit(0);
  214. }
  215. }
  216. #ifdef USE_SEMAPHORES
  217. /*
  218. * Lock support.
  219. */
  220. PyThread_type_lock
  221. PyThread_allocate_lock(void)
  222. {
  223. sem_t *lock;
  224. int status, error = 0;
  225. dprintf(("PyThread_allocate_lock called\n"));
  226. if (!initialized)
  227. PyThread_init_thread();
  228. lock = (sem_t *)malloc(sizeof(sem_t));
  229. if (lock) {
  230. status = sem_init(lock,0,1);
  231. CHECK_STATUS("sem_init");
  232. if (error) {
  233. free((void *)lock);
  234. lock = NULL;
  235. }
  236. }
  237. dprintf(("PyThread_allocate_lock() -> %p\n", lock));
  238. return (PyThread_type_lock)lock;
  239. }
  240. void
  241. PyThread_free_lock(PyThread_type_lock lock)
  242. {
  243. sem_t *thelock = (sem_t *)lock;
  244. int status, error = 0;
  245. dprintf(("PyThread_free_lock(%p) called\n", lock));
  246. if (!thelock)
  247. return;
  248. status = sem_destroy(thelock);
  249. CHECK_STATUS("sem_destroy");
  250. free((void *)thelock);
  251. }
  252. /*
  253. * As of February 2002, Cygwin thread implementations mistakenly report error
  254. * codes in the return value of the sem_ calls (like the pthread_ functions).
  255. * Correct implementations return -1 and put the code in errno. This supports
  256. * either.
  257. */
  258. static int
  259. fix_status(int status)
  260. {
  261. return (status == -1) ? errno : status;
  262. }
  263. int
  264. PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
  265. {
  266. int success;
  267. sem_t *thelock = (sem_t *)lock;
  268. int status, error = 0;
  269. dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
  270. do {
  271. if (waitflag)
  272. status = fix_status(sem_wait(thelock));
  273. else
  274. status = fix_status(sem_trywait(thelock));
  275. } while (status == EINTR); /* Retry if interrupted by a signal */
  276. if (waitflag) {
  277. CHECK_STATUS("sem_wait");
  278. } else if (status != EAGAIN) {
  279. CHECK_STATUS("sem_trywait");
  280. }
  281. success = (status == 0) ? 1 : 0;
  282. dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
  283. return success;
  284. }
  285. void
  286. PyThread_release_lock(PyThread_type_lock lock)
  287. {
  288. sem_t *thelock = (sem_t *)lock;
  289. int status, error = 0;
  290. dprintf(("PyThread_release_lock(%p) called\n", lock));
  291. status = sem_post(thelock);
  292. CHECK_STATUS("sem_post");
  293. }
  294. #else /* USE_SEMAPHORES */
  295. /*
  296. * Lock support.
  297. */
  298. PyThread_type_lock
  299. PyThread_allocate_lock(void)
  300. {
  301. pthread_lock *lock;
  302. int status, error = 0;
  303. dprintf(("PyThread_allocate_lock called\n"));
  304. if (!initialized)
  305. PyThread_init_thread();
  306. lock = (pthread_lock *) malloc(sizeof(pthread_lock));
  307. if (lock) {
  308. memset((void *)lock, '\0', sizeof(pthread_lock));
  309. lock->locked = 0;
  310. status = pthread_mutex_init(&lock->mut,
  311. pthread_mutexattr_default);
  312. CHECK_STATUS("pthread_mutex_init");
  313. status = pthread_cond_init(&lock->lock_released,
  314. pthread_condattr_default);
  315. CHECK_STATUS("pthread_cond_init");
  316. if (error) {
  317. free((void *)lock);
  318. lock = 0;
  319. }
  320. }
  321. dprintf(("PyThread_allocate_lock() -> %p\n", lock));
  322. return (PyThread_type_lock) lock;
  323. }
  324. void
  325. PyThread_free_lock(PyThread_type_lock lock)
  326. {
  327. pthread_lock *thelock = (pthread_lock *)lock;
  328. int status, error = 0;
  329. dprintf(("PyThread_free_lock(%p) called\n", lock));
  330. status = pthread_mutex_destroy( &thelock->mut );
  331. CHECK_STATUS("pthread_mutex_destroy");
  332. status = pthread_cond_destroy( &thelock->lock_released );
  333. CHECK_STATUS("pthread_cond_destroy");
  334. free((void *)thelock);
  335. }
  336. int
  337. PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
  338. {
  339. int success;
  340. pthread_lock *thelock = (pthread_lock *)lock;
  341. int status, error = 0;
  342. dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
  343. status = pthread_mutex_lock( &thelock->mut );
  344. CHECK_STATUS("pthread_mutex_lock[1]");
  345. success = thelock->locked == 0;
  346. if ( !success && waitflag ) {
  347. /* continue trying until we get the lock */
  348. /* mut must be locked by me -- part of the condition
  349. * protocol */
  350. while ( thelock->locked ) {
  351. status = pthread_cond_wait(&thelock->lock_released,
  352. &thelock->mut);
  353. CHECK_STATUS("pthread_cond_wait");
  354. }
  355. success = 1;
  356. }
  357. if (success) thelock->locked = 1;
  358. status = pthread_mutex_unlock( &thelock->mut );
  359. CHECK_STATUS("pthread_mutex_unlock[1]");
  360. if (error) success = 0;
  361. dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
  362. return success;
  363. }
  364. void
  365. PyThread_release_lock(PyThread_type_lock lock)
  366. {
  367. pthread_lock *thelock = (pthread_lock *)lock;
  368. int status, error = 0;
  369. dprintf(("PyThread_release_lock(%p) called\n", lock));
  370. status = pthread_mutex_lock( &thelock->mut );
  371. CHECK_STATUS("pthread_mutex_lock[3]");
  372. thelock->locked = 0;
  373. status = pthread_mutex_unlock( &thelock->mut );
  374. CHECK_STATUS("pthread_mutex_unlock[3]");
  375. /* wake up someone (anyone, if any) waiting on the lock */
  376. status = pthread_cond_signal( &thelock->lock_released );
  377. CHECK_STATUS("pthread_cond_signal");
  378. }
  379. #endif /* USE_SEMAPHORES */
  380. /* set the thread stack size.
  381. * Return 0 if size is valid, -1 if size is invalid,
  382. * -2 if setting stack size is not supported.
  383. */
  384. static int
  385. _pythread_pthread_set_stacksize(size_t size)
  386. {
  387. #if defined(THREAD_STACK_SIZE)
  388. pthread_attr_t attrs;
  389. size_t tss_min;
  390. int rc = 0;
  391. #endif
  392. /* set to default */
  393. if (size == 0) {
  394. _pythread_stacksize = 0;
  395. return 0;
  396. }
  397. #if defined(THREAD_STACK_SIZE)
  398. #if defined(PTHREAD_STACK_MIN)
  399. tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
  400. : THREAD_STACK_MIN;
  401. #else
  402. tss_min = THREAD_STACK_MIN;
  403. #endif
  404. if (size >= tss_min) {
  405. /* validate stack size by setting thread attribute */
  406. if (pthread_attr_init(&attrs) == 0) {
  407. rc = pthread_attr_setstacksize(&attrs, size);
  408. pthread_attr_destroy(&attrs);
  409. if (rc == 0) {
  410. _pythread_stacksize = size;
  411. return 0;
  412. }
  413. }
  414. }
  415. return -1;
  416. #else
  417. return -2;
  418. #endif
  419. }
  420. #define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)