pte_reuse.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * pte_threadReuse.c
  3. *
  4. * Description:
  5. * This translation unit implements miscellaneous thread functions.
  6. *
  7. * --------------------------------------------------------------------------
  8. *
  9. * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
  10. * Copyright(C) 2008 Jason Schmidlapp
  11. *
  12. * Contact Email: [email protected]
  13. *
  14. *
  15. * Based upon Pthreads-win32 - POSIX Threads Library for Win32
  16. * Copyright(C) 1998 John E. Bossom
  17. * Copyright(C) 1999,2005 Pthreads-win32 contributors
  18. *
  19. * Contact Email: [email protected]
  20. *
  21. * The original list of contributors to the Pthreads-win32 project
  22. * is contained in the file CONTRIBUTORS.ptw32 included with the
  23. * source code distribution. The list can also be seen at the
  24. * following World Wide Web location:
  25. * http://sources.redhat.com/pthreads-win32/contributors.html
  26. *
  27. * This library is free software; you can redistribute it and/or
  28. * modify it under the terms of the GNU Lesser General Public
  29. * License as published by the Free Software Foundation; either
  30. * version 2 of the License, or (at your option) any later version.
  31. *
  32. * This library is distributed in the hope that it will be useful,
  33. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  34. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  35. * Lesser General Public License for more details.
  36. *
  37. * You should have received a copy of the GNU Lesser General Public
  38. * License along with this library in the file COPYING.LIB;
  39. * if not, write to the Free Software Foundation, Inc.,
  40. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  41. */
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include "pthread.h"
  46. #include "implement.h"
  47. /*
  48. * How it works:
  49. * A pthread_t is a struct which is normally passed/returned by
  50. * value to/from pthreads routines. Applications are therefore storing
  51. * a copy of the struct as it is at that time.
  52. *
  53. * The original pthread_t struct plus all copies of it contain the address of
  54. * the thread state struct pte_thread_t_ (p), plus a reuse counter (x). Each
  55. * pte_thread_t contains the original copy of it's pthread_t.
  56. * Once malloced, a pte_thread_t_ struct is not freed until the process exits.
  57. *
  58. * The thread reuse stack is a simple LILO stack managed through a singly
  59. * linked list element in the pte_thread_t.
  60. *
  61. * Each time a thread is destroyed, the pte_thread_t address is pushed onto the
  62. * reuse stack after it's ptHandle's reuse counter has been incremented.
  63. *
  64. * The following can now be said from this:
  65. * - two pthread_t's are identical if their pte_thread_t reference pointers
  66. * are equal and their reuse counters are equal. That is,
  67. *
  68. * equal = (a.p == b.p && a.x == b.x)
  69. *
  70. * - a pthread_t copy refers to a destroyed thread if the reuse counter in
  71. * the copy is not equal to the reuse counter in the original.
  72. *
  73. * threadDestroyed = (copy.x != ((pte_thread_t *)copy.p)->ptHandle.x)
  74. *
  75. */
  76. /*
  77. * Pop a clean pthread_t struct off the reuse stack.
  78. */
  79. pthread_t
  80. pte_threadReusePop (void)
  81. {
  82. pthread_t t = NULL;
  83. pte_osMutexLock (pte_thread_reuse_lock);
  84. if (PTE_THREAD_REUSE_EMPTY != pte_threadReuseTop)
  85. {
  86. pte_thread_t * tp;
  87. tp = pte_threadReuseTop;
  88. pte_threadReuseTop = tp->prevReuse;
  89. if (PTE_THREAD_REUSE_EMPTY == pte_threadReuseTop)
  90. {
  91. pte_threadReuseBottom = PTE_THREAD_REUSE_EMPTY;
  92. }
  93. tp->prevReuse = NULL;
  94. t = tp->ptHandle;
  95. }
  96. pte_osMutexUnlock(pte_thread_reuse_lock);
  97. return t;
  98. }
  99. /*
  100. * Push a clean pthread_t struct onto the reuse stack.
  101. * Must be re-initialised when reused.
  102. * All object elements (mutexes, events etc) must have been either
  103. * detroyed before this, or never initialised.
  104. */
  105. void
  106. pte_threadReusePush (pthread_t thread)
  107. {
  108. pte_thread_t * tp = (pte_thread_t *) thread;
  109. pthread_t t;
  110. pte_osMutexLock (pte_thread_reuse_lock);
  111. t = tp->ptHandle;
  112. memset(tp, 0, sizeof(pte_thread_t));
  113. /* Must restore the original POSIX handle that we just wiped. */
  114. tp->ptHandle = t;
  115. tp->prevReuse = PTE_THREAD_REUSE_EMPTY;
  116. if (PTE_THREAD_REUSE_EMPTY != pte_threadReuseBottom)
  117. {
  118. pte_threadReuseBottom->prevReuse = tp;
  119. }
  120. else
  121. {
  122. pte_threadReuseTop = tp;
  123. }
  124. pte_threadReuseBottom = tp;
  125. pte_osMutexUnlock(pte_thread_reuse_lock);
  126. }