PThreadMutex.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. // PThreadMutex.c++ - C++ Mutex class built on top of posix threads.
  20. // ~~~~~~~~~~~~~~~~
  21. //
  22. #include <unistd.h>
  23. #include <pthread.h>
  24. #include "../Mutex"
  25. #include "PThreadMutexPrivateData.h"
  26. using namespace OpenThreads;
  27. //----------------------------------------------------------------------------
  28. //
  29. // Decription: Constructor
  30. //
  31. // Use: public.
  32. //
  33. Mutex::Mutex() {
  34.     pthread_mutexattr_t mutex_attr;
  35.     pthread_mutexattr_init( &mutex_attr );
  36.     
  37.     PThreadMutexPrivateData *pd = new PThreadMutexPrivateData();
  38. #ifndef __linux__ // (not available until NPTL) [
  39.     pthread_mutexattr_settype( &mutex_attr, PTHREAD_MUTEX_ERRORCHECK );
  40. #endif // ] __linux__
  41. #ifdef ALLOW_PRIORITY_SCHEDULING // [
  42. #ifdef __sun // [
  43.     pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_NONE);
  44. #endif // ] __sun
  45.     //-------------------------------------------------------------------------
  46.     // Initialization is a bit tricky, since we have to be able to be aware
  47.     // that on many-to-many execution vehicle systems, we may run into
  48.     // priority inversion deadlocks if a mutex is shared between threads
  49.     // of differing priorities.  Systems that do this should provide the 
  50.     // following protocol attributes to prevent deadlocks.  Check at runtime.
  51.     //
  52.     //  PRIO_INHERIT causes any thread locking the mutex to temporarily become
  53.     //  the same priority as the highest thread also blocked on the mutex. 
  54.     //  Although more expensive, this is the prefered method.
  55.     //
  56.     //  PRIO_PROTECT causes any thread locking the mutex to assume the priority
  57.     //  specified by setprioceiling.  pthread_mutex_lock will fail if
  58.     //  the priority ceiling is lower than the thread's priority.  Therefore,
  59.     //  the priority ceiling must be set to the max priority in order to 
  60.     //  garantee no deadlocks will occur.
  61.     //
  62. #if defined (_POSIX_THREAD_PRIO_INHERIT) || defined (_POSIX_THREAD_PRIO_PROTECT) // [
  63.     if(sysconf(_POSIX_THREAD_PRIO_INHERIT)) {
  64. pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT);
  65.     } else if (sysconf(_POSIX_THREAD_PRIO_PROTECT)) {
  66. int th_policy;
  67. struct sched_param th_param;
  68. pthread_getschedparam(pthread_self(), &th_policy, &th_param);
  69. pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_PROTECT);
  70. pthread_mutexattr_setprioceiling(&mutex_attr, 
  71.  sched_get_priority_max(th_policy));
  72.     }
  73. #endif // ] Priority Scheduling.
  74. #endif // ] ALLOW_PRIORITY_SCHEDULING
  75.     pthread_mutex_init(&pd->mutex, &mutex_attr);
  76.     _prvData = static_cast<void *>(pd);
  77. }
  78. //----------------------------------------------------------------------------
  79. //
  80. // Decription: Destructor
  81. //
  82. // Use: public.
  83. //
  84. Mutex::~Mutex() {
  85.     PThreadMutexPrivateData *pd =
  86.         static_cast<PThreadMutexPrivateData*>(_prvData);
  87.     pthread_mutex_destroy(&pd->mutex);
  88.     delete pd;
  89. }
  90. //----------------------------------------------------------------------------
  91. //
  92. // Decription: lock the mutex
  93. //
  94. // Use: public.
  95. //
  96. int Mutex::lock() {
  97.     PThreadMutexPrivateData *pd =
  98.         static_cast<PThreadMutexPrivateData*>(_prvData);
  99.     return pthread_mutex_lock(&pd->mutex);
  100. }
  101. //----------------------------------------------------------------------------
  102. //
  103. // Decription: unlock the mutex
  104. //
  105. // Use: public.
  106. //
  107. int Mutex::unlock() {
  108.     PThreadMutexPrivateData *pd =
  109.         static_cast<PThreadMutexPrivateData*>(_prvData);
  110.     return pthread_mutex_unlock(&pd->mutex);
  111. }
  112. //----------------------------------------------------------------------------
  113. //
  114. // Decription: test if the mutex may be locked
  115. //
  116. // Use: public.
  117. //
  118. int Mutex::trylock() {
  119.     PThreadMutexPrivateData *pd =
  120.         static_cast<PThreadMutexPrivateData*>(_prvData);
  121.     return pthread_mutex_trylock(&pd->mutex);
  122. }