posix_partition.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * posix_partition.c
  3. */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <assert.h>
  7. #include <string.h>
  8. #include "private.h"
  9. extern void sysheap_suppress_leak_detection(void);
  10. extern void sysheap_restore_leak_detection(void);
  11. typedef struct _key_data key_data_t;
  12. struct _key_data
  13. {
  14. lub_partition_t *partition;
  15. lub_heap_t *local_heap;
  16. };
  17. /*-------------------------------------------------------- */
  18. static void
  19. lub_posix_partition_destroy_key(void *arg)
  20. {
  21. key_data_t *key_data = arg;
  22. lub_partition_destroy_local_heap(key_data->partition,key_data->local_heap);
  23. lub_partition_global_realloc(key_data->partition,(char**)key_data,0,LUB_HEAP_ALIGN_NATIVE);
  24. }
  25. /*-------------------------------------------------------- */
  26. lub_partition_t *
  27. lub_partition_create(const lub_partition_spec_t *spec)
  28. {
  29. lub_posix_partition_t *this;
  30. lub_partition_sysalloc_fn *alloc_fn = spec->sysalloc;
  31. if(!alloc_fn)
  32. {
  33. alloc_fn = malloc;
  34. }
  35. this = alloc_fn(sizeof(lub_posix_partition_t));
  36. if(this)
  37. {
  38. lub_posix_partition_init(this,spec);
  39. }
  40. return &this->m_base;
  41. }
  42. /*-------------------------------------------------------- */
  43. void
  44. lub_posix_partition_init(lub_posix_partition_t *this,
  45. const lub_partition_spec_t *spec)
  46. {
  47. memset(this,sizeof(*this),0);
  48. /* initialise the base class */
  49. lub_partition_init(&this->m_base,spec);
  50. /* initialise the global mutex */
  51. if(0 != pthread_mutex_init(&this->m_mutex,0))
  52. {
  53. perror("pthread_mutex_init() failed!");
  54. }
  55. /* initialise the local key */
  56. if(0 != pthread_key_create(&this->m_key,
  57. lub_posix_partition_destroy_key))
  58. {
  59. perror("pthread_key_create() failed!");
  60. }
  61. }
  62. /*-------------------------------------------------------- */
  63. void
  64. lub_partition_destroy(lub_partition_t *instance)
  65. {
  66. lub_posix_partition_t *this = (void*)instance;
  67. /* finalise the base class */
  68. lub_partition_fini(&this->m_base);
  69. /* now clean up the global mutex */
  70. if(0 != pthread_mutex_destroy(&this->m_mutex))
  71. {
  72. perror("pthread_mutex_destroy() failed!");
  73. }
  74. /* now clean up the local key */
  75. if(0 != pthread_key_delete(this->m_key))
  76. {
  77. perror("pthread_key_delete() failed!");
  78. }
  79. free(this);
  80. }
  81. /*-------------------------------------------------------- */
  82. lub_heap_t *
  83. lub_partition__get_local_heap(lub_partition_t *instance)
  84. {
  85. lub_heap_t *result = 0;
  86. lub_posix_partition_t *this = (void*)instance;
  87. key_data_t *key_data = pthread_getspecific(this->m_key);
  88. if(key_data)
  89. {
  90. result = key_data->local_heap;
  91. }
  92. return result;
  93. }
  94. /*-------------------------------------------------------- */
  95. void
  96. lub_partition__set_local_heap(lub_partition_t *instance,
  97. lub_heap_t *heap)
  98. {
  99. lub_posix_partition_t *this = (void*)instance;
  100. key_data_t *key_data = 0;
  101. #if defined(__CYGWIN__)
  102. /* cygwin seems to leak key_data!!! so we ignore this for the time being... */
  103. lub_heap_leak_suppress_detection(instance->m_global_heap);
  104. #endif /* __CYGWIN__*/
  105. lub_partition_global_realloc(instance,(char**)&key_data,sizeof(key_data_t),LUB_HEAP_ALIGN_NATIVE);
  106. #if defined(__CYGWIN__)
  107. /* cygwin seems to leak key_data!!! so we ignore this for the time being... */
  108. lub_heap_leak_restore_detection(instance->m_global_heap);
  109. #endif /* __CYGWIN__*/
  110. assert(key_data);
  111. key_data->partition = instance;
  112. key_data->local_heap = heap;
  113. if(0 != pthread_getspecific(this->m_key))
  114. {
  115. assert(NULL == "Local heap already exists!");
  116. }
  117. if(0 != pthread_setspecific(this->m_key,key_data))
  118. {
  119. perror("pthread_setspecific() failed!");
  120. }
  121. }
  122. /*-------------------------------------------------------- */
  123. void
  124. lub_partition_lock(lub_partition_t *instance)
  125. {
  126. lub_posix_partition_t *this = (void*)instance;
  127. if(0 != pthread_mutex_lock(&this->m_mutex))
  128. {
  129. perror("pthread_mutex_lock() failed!");
  130. }
  131. }
  132. /*-------------------------------------------------------- */
  133. void
  134. lub_partition_unlock(lub_partition_t *instance)
  135. {
  136. lub_posix_partition_t *this = (void*)instance;
  137. if(0 != pthread_mutex_unlock(&this->m_mutex))
  138. {
  139. perror("pthread_mutex_unlock() failed!");
  140. }
  141. }
  142. /*-------------------------------------------------------- */