threads.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /**
  2. * Copyright (c) 2006-2011 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "threads.h"
  21. namespace love
  22. {
  23. namespace thread
  24. {
  25. Mutex::Mutex()
  26. {
  27. pthread_create_mutex(&mutex, NULL);
  28. }
  29. Mutex::~Mutex()
  30. {
  31. pthread_mutex_destroy(&mutex);
  32. }
  33. void Mutex::lock()
  34. {
  35. pthread_mutex_lock(&mutex);
  36. }
  37. void Mutex::unlock()
  38. {
  39. pthread_mutex_unlock(&mutex);
  40. }
  41. void* ThreadBase::thread_runner(void* param)
  42. {
  43. ThreadBase* thread = (ThreadBase*)param;
  44. thread->main();
  45. return NULL;
  46. }
  47. ThreadBase::ThreadBase()
  48. : running(false)
  49. {
  50. pthread_t thread;
  51. }
  52. ThreadBase::~ThreadBase()
  53. {
  54. if (running)
  55. {
  56. wait();
  57. }
  58. }
  59. bool ThreadBase::start()
  60. {
  61. if (pthread_create(&thread, NULL, thread_runner, this))
  62. return false;
  63. return (running = true);
  64. }
  65. void ThreadBase::wait()
  66. {
  67. pthread_join(thread, NULL);
  68. running = false;
  69. }
  70. void ThreadBase::kill()
  71. {
  72. pthread_kill(thread, 9);
  73. running = false;
  74. }
  75. unsigned int ThreadBase::threadId()
  76. {
  77. return (unsigned int)((size_t)pthread_self());
  78. }
  79. Semaphore::Semaphore(unsigned int initial_value)
  80. {
  81. sem_init(&sem, 0, initial_value);
  82. }
  83. Semaphore::~Semaphore()
  84. {
  85. sem_destroy(&sem);
  86. }
  87. unsigned int Semaphore::value()
  88. {
  89. int val = 0;
  90. if (sem_getvalue(&sem, &val)) {
  91. return 0;
  92. } else {
  93. return val;
  94. }
  95. }
  96. void Semaphore::post()
  97. {
  98. sem_post(&sem);
  99. }
  100. bool Semaphore::wait(int timeout)
  101. {
  102. if (timeout < 0)
  103. return !sem_wait(&sem);
  104. else if (timeout == 0)
  105. return !sem_trywait(&sem);
  106. else
  107. {
  108. struct timespec ts;
  109. ts.tv_sec = timeout/1000;
  110. ts.tv_nsec = (timeout % 1000) * 1000000;
  111. return !sem_timedwait(&sem, &ts);
  112. }
  113. }
  114. bool Semaphore::tryWait()
  115. {
  116. return !sem_trywait(&sem);
  117. }
  118. Conditional::Conditional()
  119. {
  120. pthread_cond_init(&cond, NULL);
  121. }
  122. Conditional::~Conditional()
  123. {
  124. pthread_cond_destroy(&cond);
  125. }
  126. void Conditional::signal()
  127. {
  128. pthread_cond_signal(&cond);
  129. }
  130. void Conditional::broadcast()
  131. {
  132. pthread_cond_broadcast(&cond);
  133. }
  134. bool Conditional::wait(Mutex* mutex, int timeout)
  135. {
  136. if (timeout < 0)
  137. return !pthread_cond_wait(cond, mutex->mutex);
  138. else
  139. {
  140. struct timespec ts;
  141. int ret;
  142. ts.tv_sec = timeout / 1000;
  143. ts.tv_nsec = (timeout % 1000) * 1000000;
  144. ret = pthread_cond_timedwait(&cond, mutex->mutex, &ts);
  145. return (ret == 0);
  146. }
  147. }
  148. } // thread
  149. } // love