1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 19 // -*- c++ -*- 20 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 21 22 // O S C L _ M U T E X 23 24 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 25 26 /** 27 * @file oscl_mutex.h 28 * @brief This file provides implementation of mutex 29 * 30 */ 31 32 #ifndef OSCL_MUTEX_H_INCLUDED 33 #define OSCL_MUTEX_H_INCLUDED 34 35 #ifndef OSCLCONFIG_PROC_H_INCLUDED 36 #include "osclconfig_proc.h" 37 #endif 38 #ifndef OSCL_TYPES_H_INCLUDED 39 #include "oscl_types.h" 40 #endif 41 #ifndef OSCL_BASE_H_INCLUDED 42 #include "oscl_base.h" 43 #endif 44 #ifndef OSCL_THREAD_H_INCLUDED 45 #include "oscl_thread.h" 46 #endif 47 #ifndef OSCL_LOCK_BASE_H_INCLUDED 48 #include "oscl_lock_base.h" 49 #endif 50 51 52 /** 53 * Class OsclMutex 54 */ 55 class OsclMutex : public OsclLockBase 56 { 57 public: 58 59 /** 60 * Class constructor 61 */ 62 OSCL_IMPORT_REF OsclMutex(); 63 64 /** 65 * Class destructor 66 */ 67 OSCL_IMPORT_REF virtual ~OsclMutex(); 68 69 /** 70 * Creates the Mutex 71 * 72 * @param No input arguments 73 * 74 * @return Returns the Error whether it is success or failure. 75 * Incase of failure it will return what is the specific error 76 */ 77 OSCL_IMPORT_REF OsclProcStatus::eOsclProcError Create(void); 78 79 80 /** 81 * Locks the Mutex 82 * 83 * @param It wont take any parameters 84 * 85 * @return Returns nothing 86 */ 87 OSCL_IMPORT_REF void Lock(); 88 89 /** 90 * Try to lock the mutex,if the Mutex is already locked calling thread 91 * immediately returns with out blocking 92 * @param It wont take any parameters 93 * 94 * @return Returns SUCCESS_ERROR if the mutex was acquired, 95 * MUTEX_LOCKED_ERROR if the mutex cannot be acquired without waiting, 96 * or an error code if the operation failed. 97 * Note: this function may not be supported on all platforms, and 98 * may return NOT_IMPLEMENTED. 99 */ 100 OSCL_IMPORT_REF OsclProcStatus::eOsclProcError TryLock(); 101 102 103 /** 104 * Releases the Mutex 105 * 106 * @param It wont take any parameters 107 * 108 * @return Returns nothing 109 */ 110 OSCL_IMPORT_REF void Unlock(); 111 112 113 /** 114 * Closes the Mutex 115 * 116 * @param It wont take any prameters 117 * 118 * @return Returns the Error whether it is success or failure. 119 * Incase of failure it will return what is the specific error 120 */ 121 OSCL_IMPORT_REF OsclProcStatus::eOsclProcError Close(void); 122 123 private: 124 125 /** 126 * Error Mapping 127 * 128 * @param It will take error returned by OS specific API 129 * 130 * @return Returns specific error 131 */ 132 OsclProcStatus::eOsclProcError ErrorMapping(int32 Error); 133 134 TOsclMutexObject ObjMutex; 135 bool bCreated; 136 137 }; 138 139 /** 140 * Class OsclNoYieldMutex can be used in use cases where there will be 141 * no CPU-yielding operation done while the Mutex is locked. 142 * 143 * CPU-yielding operations include OsclMutex::Lock, OsclSemphore::Wait, 144 * OsclThread::Sleep, and OsclBrewThreadUtil::BThreadYield. 145 * 146 * The behavior of OsclNoYieldMutex depends on whether the threading model 147 * is pre-emptive or not. When threading is pre-emptive, it is identical 148 * to OsclMutex. When threading is non-pre-emptive, it is a NO-OP. 149 * 150 * An example of this type of use case is for simple data protection. 151 * 152 */ 153 #if !OSCL_HAS_NON_PREEMPTIVE_THREAD_SUPPORT 154 //In pre-emptive threading, OsclNoYieldMutex is identical to OsclMutex 155 typedef OsclMutex OsclNoYieldMutex; 156 #else 157 //In non-pre-emptive threading, OsclNoYieldMutex is a NO-OP. 158 class OsclNoYieldMutex : public OsclLockBase 159 { 160 public: 161 162 /** 163 * Class constructor 164 */ OsclNoYieldMutex()165 OsclNoYieldMutex() 166 { 167 #ifndef NDEBUG 168 iNumLock = 0; 169 bCreated = false; 170 #endif 171 } 172 173 /** 174 * Class destructor 175 */ ~OsclNoYieldMutex()176 virtual ~OsclNoYieldMutex() 177 {} 178 179 /** 180 * Creates the Mutex 181 * 182 * @param No input arguments 183 * 184 * @return Returns the Error whether it is success or failure. 185 * Incase of failure it will return what is the specific error 186 */ Create(void)187 OsclProcStatus::eOsclProcError Create(void) 188 { 189 #ifndef NDEBUG 190 if (bCreated) 191 return OsclProcStatus::INVALID_OPERATION_ERROR; 192 bCreated = true; 193 #endif 194 return OsclProcStatus::SUCCESS_ERROR; 195 } 196 197 198 /** 199 * Locks the Mutex 200 * 201 * @param It wont take any parameters 202 * 203 * @return Returns nothing 204 */ Lock()205 void Lock() 206 { 207 #ifndef NDEBUG 208 OSCL_ASSERT(bCreated); 209 OSCL_ASSERT(iNumLock == 0);//detect deadlock condition. 210 iNumLock++; 211 #endif 212 } 213 214 /** 215 * Try to lock the mutex,if the Mutex is already locked calling thread 216 * immediately returns with out blocking 217 * @param It wont take any parameters 218 * 219 * @return Returns SUCCESS_ERROR if the mutex was acquired, 220 * MUTEX_LOCKED_ERROR if the mutex cannot be acquired without waiting, 221 * or an error code if the operation failed. 222 * Note: this function may not be supported on all platforms, and 223 * may return NOT_IMPLEMENTED. 224 */ TryLock()225 OsclProcStatus::eOsclProcError TryLock() 226 { 227 #ifndef NDEBUG 228 if (!bCreated) 229 return OsclProcStatus::INVALID_OPERATION_ERROR; 230 if (iNumLock) 231 return OsclProcStatus::MUTEX_LOCKED_ERROR; 232 else 233 Lock(); 234 return OsclProcStatus::SUCCESS_ERROR; 235 #endif 236 } 237 238 239 /** 240 * Releases the Mutex 241 * 242 * @param It wont take any parameters 243 * 244 * @return Returns nothing 245 */ Unlock()246 void Unlock() 247 { 248 #ifndef NDEBUG 249 OSCL_ASSERT(bCreated); 250 OSCL_ASSERT(iNumLock); 251 if (iNumLock > 0) 252 iNumLock--; 253 #endif 254 } 255 256 257 /** 258 * Closes the Mutex 259 * 260 * @param It wont take any prameters 261 * 262 * @return Returns the Error whether it is success or failure. 263 * Incase of failure it will return what is the specific error 264 */ Close(void)265 OsclProcStatus::eOsclProcError Close(void) 266 { 267 #ifndef NDEBUG 268 if (!bCreated) 269 return OsclProcStatus::INVALID_OPERATION_ERROR; 270 bCreated = false; 271 #endif 272 return OsclProcStatus::SUCCESS_ERROR; 273 } 274 275 private: 276 277 #ifndef NDEBUG 278 uint32 iNumLock; 279 bool bCreated; 280 #endif 281 282 }; 283 #endif //OSCL_HAS_NON_PREEMPTIVE_THREAD_SUPPORT 284 285 /** 286 ** An implementation of OsclLockBase using a mutex 287 **/ 288 class OsclThreadLock: public OsclLockBase 289 { 290 public: 291 OSCL_IMPORT_REF OsclThreadLock(); 292 OSCL_IMPORT_REF virtual ~OsclThreadLock(); 293 OSCL_IMPORT_REF void Lock(); 294 OSCL_IMPORT_REF void Unlock(); 295 private: 296 OsclMutex iMutex; 297 }; 298 299 #endif 300 301 302 303