x86UNIXThread.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platformThread.h"
  23. #include "platformX86UNIX/platformX86UNIX.h"
  24. #include "platform/platformSemaphore.h"
  25. #include <SDL/SDL.h>
  26. #include <SDL/SDL_thread.h>
  27. #include "pthread.h"
  28. //--------------------------------------------------------------------------
  29. struct x86UNIXThreadData
  30. {
  31. ThreadRunFunction mRunFunc;
  32. S32 mRunArg;
  33. Thread * mThread;
  34. void * mSemaphore;
  35. SDL_Thread *mTheThread;
  36. x86UNIXThreadData()
  37. {
  38. mRunFunc = 0;
  39. mRunArg = 0;
  40. mThread = 0;
  41. mSemaphore = 0;
  42. };
  43. };
  44. //--------------------------------------------------------------------------
  45. Thread::Thread(ThreadRunFunction func, S32 arg, bool start_thread)
  46. {
  47. x86UNIXThreadData * threadData = new x86UNIXThreadData();
  48. threadData->mRunFunc = func;
  49. threadData->mRunArg = arg;
  50. threadData->mThread = this;
  51. threadData->mSemaphore = Semaphore::createSemaphore();
  52. threadData->mTheThread = NULL;
  53. mData = reinterpret_cast<void*>(threadData);
  54. if (start_thread)
  55. start();
  56. }
  57. Thread::~Thread()
  58. {
  59. join();
  60. x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
  61. Semaphore::destroySemaphore(threadData->mSemaphore);
  62. delete threadData;
  63. }
  64. static int ThreadRunHandler(void * arg)
  65. {
  66. x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(arg);
  67. threadData->mThread->run(threadData->mRunArg);
  68. Semaphore::releaseSemaphore(threadData->mSemaphore);
  69. return 0;
  70. }
  71. void Thread::start()
  72. {
  73. if(isAlive())
  74. return;
  75. x86UNIXThreadData *threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
  76. Semaphore::acquireSemaphore(threadData->mSemaphore);
  77. threadData->mTheThread = SDL_CreateThread(ThreadRunHandler, mData);
  78. }
  79. bool Thread::join()
  80. {
  81. if(!isAlive())
  82. return(false);
  83. x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
  84. //
  85. // (SDL 1.2.7) Even after the procedure started in the thread returns, there
  86. // still exist some resources allocated to the thread. To free these
  87. // resources, use SDL_WaitThread to wait for the thread to finish and
  88. // obtain the status code of the thread. If not done so, SDL_CreateThread
  89. // will hang after about 1010 successfully created threads
  90. // (tested on GNU/Linux).
  91. //
  92. SDL_WaitThread(threadData->mTheThread, NULL);
  93. threadData->mTheThread = NULL;
  94. return (Semaphore::acquireSemaphore(threadData->mSemaphore, true));
  95. }
  96. void Thread::run(S32 arg)
  97. {
  98. x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
  99. if(threadData->mRunFunc)
  100. threadData->mRunFunc(arg);
  101. }
  102. bool Thread::isAlive()
  103. {
  104. x86UNIXThreadData * threadData = reinterpret_cast<x86UNIXThreadData*>(mData);
  105. if (threadData->mTheThread)
  106. {
  107. bool signal = Semaphore::acquireSemaphore(threadData->mSemaphore, false);
  108. if (signal)
  109. Semaphore::releaseSemaphore(threadData->mSemaphore);
  110. return (!signal);
  111. }
  112. return false;
  113. }
  114. ThreadIdent Thread::getCurrentThreadId()
  115. {
  116. return SDL_ThreadID();
  117. }
  118. class PlatformThreadStorage
  119. {
  120. public:
  121. pthread_key_t mThreadKey;
  122. };
  123. /*ThreadStorage::ThreadStorage()
  124. {
  125. mThreadStorage = (PlatformThreadStorage *) mStorage;
  126. constructInPlace(mThreadStorage);
  127. pthread_key_create(&mThreadStorage->mThreadKey, NULL);
  128. }
  129. ThreadStorage::~ThreadStorage()
  130. {
  131. pthread_key_delete(mThreadStorage->mThreadKey);
  132. }
  133. void *ThreadStorage::get()
  134. {
  135. return pthread_getspecific(mThreadStorage->mThreadKey);
  136. }
  137. void ThreadStorage::set(void *value)
  138. {
  139. pthread_setspecific(mThreadStorage->mThreadKey, value);
  140. }
  141. */