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 //---------------------------------------------------------------------- 00022 //---------------------------------------------------------------------- 00023 #include "icl_core_thread/RWLockImplLxrt33.h" 00024 00025 #include <icl_core/internal_raw_debug.h> 00026 #include <icl_core/os_lxrt.h> 00027 00028 #include "icl_core_thread/Common.h" 00029 00030 #undef STRICT_LXRT_CHECKS 00031 00032 00033 namespace icl_core { 00034 namespace thread { 00035 00036 RWLockImplLxrt33::RWLockImplLxrt33() 00037 : m_rwlock(NULL) 00038 { 00039 #ifdef STRICT_LXRT_CHECKS 00040 if (!icl_core::os::isThisLxrtTask()) 00041 { 00042 PRINTF("RWLockImplLxrt33::RWLockImplLxrt33: Called from a Linux task!\n"); 00043 return; 00044 } 00045 #endif 00046 m_rwlock = new pthread_rwlock_t; 00047 pthread_rwlock_init_rt(m_rwlock, NULL); 00048 } 00049 00050 RWLockImplLxrt33::~RWLockImplLxrt33() 00051 { 00052 #ifdef STRICT_LXRT_CHECKS 00053 if (!icl_core::os::isThisLxrtTask()) 00054 { 00055 PRINTF("RWLockImplLxrt33::~RWLockImplLxrt33: Called from a Linux task!\n"); 00056 return; 00057 } 00058 #endif 00059 if (m_rwlock) 00060 { 00061 pthread_rwlock_destroy_rt(m_rwlock); 00062 delete m_rwlock; 00063 m_rwlock = NULL; 00064 } 00065 } 00066 00067 bool RWLockImplLxrt33::readLock() 00068 { 00069 #ifdef STRICT_LXRT_CHECKS 00070 if (!icl_core::os::isThisLxrtTask()) 00071 { 00072 PRINTF("RWLockImplLxrt33::readLock: Called from a Linux task!\n"); 00073 return false; 00074 } 00075 #endif 00076 return pthread_rwlock_rdlock_rt(m_rwlock) == 0; 00077 } 00078 00079 bool RWLockImplLxrt33::readLock(const icl_core::TimeStamp& timeout) 00080 { 00081 #ifdef STRICT_LXRT_CHECKS 00082 if (!icl_core::os::isThisLxrtTask()) 00083 { 00084 PRINTF("RWLockImplLxrt33::readLock: Called from a Linux task!\n"); 00085 return false; 00086 } 00087 #endif 00088 struct timespec timeout_absolute_timespec = timeout.systemTimespec(); 00089 int ret = pthread_rwlock_timedrdlock_rt(m_rwlock, &timeout_absolute_timespec); 00090 return (ret == 0); 00091 } 00092 00093 bool RWLockImplLxrt33::readLock(const icl_core::TimeSpan& timeout) 00094 { 00095 #ifdef STRICT_LXRT_CHECKS 00096 if (!icl_core::os::isThisLxrtTask()) 00097 { 00098 PRINTF("RWLockImplLxrt33::readLock: Called from a Linux task!\n"); 00099 return false; 00100 } 00101 #endif 00102 return readLock(impl::getAbsoluteTimeout(timeout)); 00103 } 00104 00105 bool RWLockImplLxrt33::tryReadLock() 00106 { 00107 #ifdef STRICT_LXRT_CHECKS 00108 if (!icl_core::os::isThisLxrtTask()) 00109 { 00110 PRINTF("RWLockImplLxrt33::tryReadLock: Called from a Linux task!\n"); 00111 return false; 00112 } 00113 #endif 00114 int ret = pthread_rwlock_tryrdlock_rt(m_rwlock); 00115 return (ret == 0); 00116 } 00117 00118 bool RWLockImplLxrt33::writeLock() 00119 { 00120 #ifdef STRICT_LXRT_CHECKS 00121 if (!icl_core::os::isThisLxrtTask()) 00122 { 00123 PRINTF("RWLockImplLxrt33::writeLock: Called from a Linux task!\n"); 00124 return false; 00125 } 00126 #endif 00127 return pthread_rwlock_wrlock_rt(m_rwlock) == 0; 00128 } 00129 00130 bool RWLockImplLxrt33::writeLock(const icl_core::TimeStamp& timeout) 00131 { 00132 #ifdef STRICT_LXRT_CHECKS 00133 if (!icl_core::os::isThisLxrtTask()) 00134 { 00135 PRINTF("RWLockImplLxrt33::writeLock: Called from a Linux task!\n"); 00136 return false; 00137 } 00138 #endif 00139 struct timespec timeout_absolute_timespec = timeout.systemTimespec(); 00140 int ret = pthread_rwlock_timedwrlock_rt(m_rwlock, &timeout_absolute_timespec); 00141 return (ret == 0); 00142 } 00143 00144 bool RWLockImplLxrt33::writeLock(const icl_core::TimeSpan& timeout) 00145 { 00146 #ifdef STRICT_LXRT_CHECKS 00147 if (!icl_core::os::isThisLxrtTask()) 00148 { 00149 PRINTF("RWLockImplLxrt33::writeLock: Called from a Linux task!\n"); 00150 return false; 00151 } 00152 #endif 00153 return writeLock(impl::getAbsoluteTimeout(timeout)); 00154 } 00155 00156 bool RWLockImplLxrt33::tryWriteLock() 00157 { 00158 #ifdef STRICT_LXRT_CHECKS 00159 if (!icl_core::os::isThisLxrtTask()) 00160 { 00161 PRINTF("RWLockImplLxrt33::tryWriteLock: Called from a Linux task!\n"); 00162 return false; 00163 } 00164 #endif 00165 // ATTENTION: Calling pthread_rwlock_trywrlock_rt() while another 00166 // thread holds a read lock seems to be buggy in RTAI 3.3, so the 00167 // following does NOT work: 00168 // int ret = pthread_rwlock_trywrlock_rt(rwlock); 00169 // return (ret == 0); 00170 // Therefore we call WriteLock() with a very short timeout! 00171 static icl_core::TimeSpan try_write_lock_timeout(0, 1); 00172 return writeLock(try_write_lock_timeout); 00173 } 00174 00175 void RWLockImplLxrt33::unlock() 00176 { 00177 #ifdef STRICT_LXRT_CHECKS 00178 if (!icl_core::os::isThisLxrtTask()) 00179 { 00180 PRINTF("RWLockImplLxrt33::unlock: Called from a Linux task!\n"); 00181 return; 00182 } 00183 #endif 00184 pthread_rwlock_unlock_rt(m_rwlock); 00185 } 00186 00187 } 00188 }