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