darwin_semaphore.h 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
  3. * Copyright (c) 1996 by Silicon Graphics. All rights reserved.
  4. * Copyright (c) 1998 by Fergus Henderson. All rights reserved.
  5. * Copyright (c) 2000-2009 by Hewlett-Packard Development Company.
  6. * All rights reserved.
  7. *
  8. * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  9. * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
  10. *
  11. * Permission is hereby granted to use or copy this program
  12. * for any purpose, provided the above notices are retained on all copies.
  13. * Permission to modify the code and to distribute modified code is granted,
  14. * provided the above notices are retained, and a notice that the code was
  15. * modified is included with the above copyright notice.
  16. */
  17. #ifndef GC_DARWIN_SEMAPHORE_H
  18. #define GC_DARWIN_SEMAPHORE_H
  19. #if !defined(GC_DARWIN_THREADS)
  20. # error darwin_semaphore.h included with GC_DARWIN_THREADS not defined
  21. #endif
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. /* This is a very simple semaphore implementation for Darwin. It is */
  26. /* implemented in terms of pthread calls so it is not async signal */
  27. /* safe. But this is not a problem because signals are not used to */
  28. /* suspend threads on Darwin. */
  29. typedef struct {
  30. pthread_mutex_t mutex;
  31. pthread_cond_t cond;
  32. int value;
  33. } sem_t;
  34. GC_INLINE int sem_init(sem_t *sem, int pshared, int value) {
  35. if (pshared != 0) {
  36. errno = EPERM; /* unsupported */
  37. return -1;
  38. }
  39. sem->value = value;
  40. if (pthread_mutex_init(&sem->mutex, NULL) != 0)
  41. return -1;
  42. if (pthread_cond_init(&sem->cond, NULL) != 0) {
  43. (void)pthread_mutex_destroy(&sem->mutex);
  44. return -1;
  45. }
  46. return 0;
  47. }
  48. GC_INLINE int sem_post(sem_t *sem) {
  49. if (pthread_mutex_lock(&sem->mutex) != 0)
  50. return -1;
  51. sem->value++;
  52. if (pthread_cond_signal(&sem->cond) != 0) {
  53. (void)pthread_mutex_unlock(&sem->mutex);
  54. return -1;
  55. }
  56. return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0;
  57. }
  58. GC_INLINE int sem_wait(sem_t *sem) {
  59. if (pthread_mutex_lock(&sem->mutex) != 0)
  60. return -1;
  61. while (sem->value == 0) {
  62. if (pthread_cond_wait(&sem->cond, &sem->mutex) != 0) {
  63. (void)pthread_mutex_unlock(&sem->mutex);
  64. return -1;
  65. }
  66. }
  67. sem->value--;
  68. return pthread_mutex_unlock(&sem->mutex) != 0 ? -1 : 0;
  69. }
  70. GC_INLINE int sem_destroy(sem_t *sem) {
  71. return pthread_cond_destroy(&sem->cond) != 0
  72. || pthread_mutex_destroy(&sem->mutex) != 0 ? -1 : 0;
  73. }
  74. #ifdef __cplusplus
  75. } /* extern "C" */
  76. #endif
  77. #endif