00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 00002 00003 // -- BEGIN LICENSE BLOCK ---------------------------------------------- 00004 // This file is part of FZIs ic_workspace. 00005 // 00006 // This program is free software licensed under the LGPL 00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3). 00008 // You can find a copy of this license in LICENSE folder in the top 00009 // directory of the source code. 00010 // 00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany 00012 // 00013 // -- END LICENSE BLOCK ------------------------------------------------ 00014 00015 //---------------------------------------------------------------------- 00023 //---------------------------------------------------------------------- 00024 #include "icl_core_thread/RWLockImplLxrt35.h" 00025 00026 #include <icl_core/internal_raw_debug.h> 00027 #include <icl_core/os_lxrt.h> 00028 00029 #include "icl_core_thread/Common.h" 00030 00031 #undef STRICT_LXRT_CHECKS 00032 00033 00034 namespace icl_core { 00035 namespace thread { 00036 00037 RWLockImplLxrt35::RWLockImplLxrt35() 00038 : m_rwlock(NULL) 00039 { 00040 #ifdef STRICT_LXRT_CHECKS 00041 if (!icl_core::os::isThisLxrtTask()) 00042 { 00043 PRINTF("RWLockImplLxrt35::RWLockImplLxrt35: Called from a Linux task!\n"); 00044 return; 00045 } 00046 #endif 00047 m_rwlock = new pthread_rwlock_t; 00048 pthread_rwlock_init_rt(m_rwlock, NULL); 00049 } 00050 00051 RWLockImplLxrt35::~RWLockImplLxrt35() 00052 { 00053 #ifdef STRICT_LXRT_CHECKS 00054 if (!icl_core::os::isThisLxrtTask()) 00055 { 00056 PRINTF("RWLockImplLxrt35::~RWLockImplLxrt35: Called from a Linux task!\n"); 00057 return; 00058 } 00059 #endif 00060 if (m_rwlock) 00061 { 00062 pthread_rwlock_destroy_rt(m_rwlock); 00063 delete m_rwlock; 00064 m_rwlock = NULL; 00065 } 00066 } 00067 00068 bool RWLockImplLxrt35::readLock() 00069 { 00070 #ifdef STRICT_LXRT_CHECKS 00071 if (!icl_core::os::isThisLxrtTask()) 00072 { 00073 PRINTF("RWLockImplLxrt35::readLock: Called from a Linux task!\n"); 00074 return false; 00075 } 00076 #endif 00077 return pthread_rwlock_rdlock_rt(m_rwlock) == 0; 00078 } 00079 00080 bool RWLockImplLxrt35::readLock(const icl_core::TimeStamp& timeout) 00081 { 00082 #ifdef STRICT_LXRT_CHECKS 00083 if (!icl_core::os::isThisLxrtTask()) 00084 { 00085 PRINTF("RWLockImplLxrt35::readLock: Called from a Linux task!\n"); 00086 return false; 00087 } 00088 #endif 00089 struct timespec timeout_absolute_timespec = timeout.systemTimespec(); 00090 int ret = pthread_rwlock_timedrdlock_rt(m_rwlock, &timeout_absolute_timespec); 00091 return (ret == 0); 00092 } 00093 00094 bool RWLockImplLxrt35::readLock(const icl_core::TimeSpan& timeout) 00095 { 00096 #ifdef STRICT_LXRT_CHECKS 00097 if (!icl_core::os::isThisLxrtTask()) 00098 { 00099 PRINTF("RWLockImplLxrt35::readLock: Called from a Linux task!\n"); 00100 return false; 00101 } 00102 #endif 00103 return readLock(impl::getAbsoluteTimeout(timeout)); 00104 } 00105 00106 bool RWLockImplLxrt35::tryReadLock() 00107 { 00108 #ifdef STRICT_LXRT_CHECKS 00109 if (!icl_core::os::isThisLxrtTask()) 00110 { 00111 PRINTF("RWLockImplLxrt35::tryReadLock: Called from a Linux task!\n"); 00112 return false; 00113 } 00114 #endif 00115 int ret = pthread_rwlock_tryrdlock_rt(m_rwlock); 00116 return (ret == 0); 00117 } 00118 00119 bool RWLockImplLxrt35::writeLock() 00120 { 00121 #ifdef STRICT_LXRT_CHECKS 00122 if (!icl_core::os::isThisLxrtTask()) 00123 { 00124 PRINTF("RWLockImplLxrt35::writeLock: Called from a Linux task!\n"); 00125 return false; 00126 } 00127 #endif 00128 return pthread_rwlock_wrlock_rt(m_rwlock) == 0; 00129 } 00130 00131 bool RWLockImplLxrt35::writeLock(const icl_core::TimeStamp& timeout) 00132 { 00133 #ifdef STRICT_LXRT_CHECKS 00134 if (!icl_core::os::isThisLxrtTask()) 00135 { 00136 PRINTF("RWLockImplLxrt35::writeLock: Called from a Linux task!\n"); 00137 return false; 00138 } 00139 #endif 00140 struct timespec timeout_absolute_timespec = timeout.systemTimespec(); 00141 int ret = pthread_rwlock_timedwrlock_rt(m_rwlock, &timeout_absolute_timespec); 00142 return (ret == 0); 00143 } 00144 00145 bool RWLockImplLxrt35::writeLock(const icl_core::TimeSpan& timeout) 00146 { 00147 #ifdef STRICT_LXRT_CHECKS 00148 if (!icl_core::os::isThisLxrtTask()) 00149 { 00150 PRINTF("RWLockImplLxrt35::writeLock: Called from a Linux task!\n"); 00151 return false; 00152 } 00153 #endif 00154 return writeLock(impl::getAbsoluteTimeout(timeout)); 00155 } 00156 00157 bool RWLockImplLxrt35::tryWriteLock() 00158 { 00159 #ifdef STRICT_LXRT_CHECKS 00160 if (!icl_core::os::isThisLxrtTask()) 00161 { 00162 PRINTF("RWLockImplLxrt35::tryWriteLock: Called from a Linux task!\n"); 00163 return false; 00164 } 00165 #endif 00166 // ATTENTION: Calling pthread_rwlock_trywrlock_rt() while another 00167 // thread holds a read lock seems to be buggy in RTAI 3.3, so the 00168 // following does NOT work: 00169 // int ret = pthread_rwlock_trywrlock_rt(rwlock); 00170 // return (ret == 0); 00171 // Therefore we call WriteLock() with a very short timeout! 00172 static icl_core::TimeSpan try_write_lock_timeout(0, 1); 00173 return writeLock(try_write_lock_timeout); 00174 } 00175 00176 void RWLockImplLxrt35::unlock() 00177 { 00178 #ifdef STRICT_LXRT_CHECKS 00179 if (!icl_core::os::isThisLxrtTask()) 00180 { 00181 PRINTF("RWLockImplLxrt35::unlock: Called from a Linux task!\n"); 00182 return; 00183 } 00184 #endif 00185 pthread_rwlock_unlock_rt(rwlock); 00186 } 00187 00188 } 00189 }