PThreadCondition.c++
上传用户:chinafayin
上传日期:2022-04-05
资源大小:153k
文件大小:4k
源码类别:

并行计算

开发平台:

Visual C++

  1. //
  2. // OpenThread library, Copyright (C) 2002 - 2003  The Open Thread Group
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License, or (at your option) any later version.
  8. //
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. // Lesser General Public License for more details.
  13. // 
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. //
  18. //
  19. // PThreadCondition.c++ - C++ Condition class built on top of posix threads.
  20. // ~~~~~~~~~~~~~~~~~~~~
  21. //
  22. #include <sys/time.h>
  23. #include <assert.h>
  24. #include "../Condition"
  25. #include "PThreadConditionPrivateData.h"
  26. #include "PThreadMutexPrivateData.h"
  27. using namespace OpenThreads;
  28. //----------------------------------------------------------------------------
  29. // This cancel cleanup handler is necessary to ensure that the barrier's
  30. // mutex gets unlocked on cancel. Otherwise deadlocks could occur with 
  31. // later joins.
  32. //
  33. void condition_cleanup_handler(void *arg) {
  34.     pthread_mutex_t *mutex = static_cast<pthread_mutex_t *>(arg);
  35.     
  36.     pthread_mutex_unlock(mutex);
  37. }
  38. //----------------------------------------------------------------------------
  39. //
  40. // Decription: Constructor
  41. //
  42. // Use: public.
  43. //
  44. Condition::Condition() {
  45.     PThreadConditionPrivateData *pd =
  46.         new PThreadConditionPrivateData();
  47.     int status = pthread_cond_init( &pd->condition, NULL );
  48.     assert(status == 0);
  49.     _prvData = static_cast<void *>(pd);
  50. }
  51. //----------------------------------------------------------------------------
  52. //
  53. // Decription: Destructor
  54. //
  55. // Use: public.
  56. //
  57. Condition::~Condition() {
  58.     PThreadConditionPrivateData *pd =
  59.         static_cast<PThreadConditionPrivateData *>(_prvData);
  60.     int status = pthread_cond_destroy( &pd->condition );
  61.     assert(status == 0);
  62.     delete pd;
  63. }
  64. //----------------------------------------------------------------------------
  65. //
  66. // Decription: wait on a condition
  67. //
  68. // Use: public.
  69. //
  70. int Condition::wait(Mutex *mutex) {
  71.     PThreadConditionPrivateData *pd =
  72.         static_cast<PThreadConditionPrivateData *>(_prvData);
  73.     PThreadMutexPrivateData *mpd =
  74.         static_cast<PThreadMutexPrivateData *>(mutex->_prvData);
  75.     int status;
  76.     
  77.     pthread_cleanup_push(condition_cleanup_handler, &mpd->mutex);
  78.     status = pthread_cond_wait( &pd->condition, &mpd->mutex );
  79.     pthread_cleanup_pop(0);
  80.     return status;
  81. }
  82. //----------------------------------------------------------------------------
  83. //
  84. // Decription: wait on a condition, for a specified period of time
  85. //
  86. // Use: public.
  87. //
  88. int Condition::wait(Mutex *mutex, unsigned long int ms) {
  89.     PThreadConditionPrivateData *pd =
  90.         static_cast<PThreadConditionPrivateData *>(_prvData);
  91.     PThreadMutexPrivateData *mpd =
  92.         static_cast<PThreadMutexPrivateData *>(mutex->_prvData);
  93.     struct ::timeval now;
  94.     ::gettimeofday( &now, 0 );
  95.     // Wait time is now + ms milliseconds
  96.     unsigned int sec = ms / 1000;
  97.     unsigned int nsec = (ms % 1000) * 1000;
  98.     struct timespec abstime;
  99.     abstime.tv_sec = now.tv_sec + sec;
  100.     abstime.tv_nsec = now.tv_usec*1000 + nsec;
  101.     int status;
  102.     pthread_cleanup_push(condition_cleanup_handler, &mpd->mutex);
  103.     status = pthread_cond_timedwait( &pd->condition, &mpd->mutex, &abstime );
  104.     pthread_cleanup_pop(0);
  105.     return status;
  106. }
  107. //----------------------------------------------------------------------------
  108. //
  109. // Decription: signal a thread to wake up.
  110. //
  111. // Use: public.
  112. //
  113. int Condition::signal() {
  114.     PThreadConditionPrivateData *pd =
  115.         static_cast<PThreadConditionPrivateData *>(_prvData);
  116.     return pthread_cond_signal( &pd->condition );
  117. }
  118. //----------------------------------------------------------------------------
  119. //
  120. // Decription: signal many threads to wake up.
  121. //
  122. // Use: public.
  123. //
  124. int Condition::broadcast() {
  125.     PThreadConditionPrivateData *pd =
  126.         static_cast<PThreadConditionPrivateData *>(_prvData);
  127.     return pthread_cond_broadcast( &pd->condition );
  128. }