1 /* 2 * Copyright (C) Texas Instruments - http://www.ti.com/ 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 19 #include "Semaphore.h" 20 #include "ErrorUtils.h" 21 #include <utils/Log.h> 22 #include <time.h> 23 24 namespace android { 25 26 /** 27 @brief Constructor for the semaphore class 28 29 @param none 30 @return none 31 */ 32 Semaphore::Semaphore() 33 { 34 ///Initialize the semaphore to NULL 35 mSemaphore = NULL; 36 } 37 38 /** 39 @brief Destructor of the semaphore class 40 41 @param none 42 @return none 43 44 */ 45 Semaphore::~Semaphore() 46 { 47 Release(); 48 } 49 50 /** 51 @brief: Releases semaphore 52 53 @param count >=0 54 @return NO_ERROR On Success 55 @return One of the android error codes based on semaphore de-initialization 56 */ 57 58 status_t Semaphore::Release() 59 { 60 int status = 0; 61 62 ///Destroy only if the semaphore has been created 63 if(mSemaphore) 64 { 65 status = sem_destroy(mSemaphore); 66 67 free(mSemaphore); 68 69 mSemaphore = NULL; 70 } 71 72 ///Initialize the semaphore and return the status 73 return ErrorUtils::posixToAndroidError(status); 74 75 } 76 77 /** 78 @brief Create the semaphore with initial count value 79 80 @param count >=0 81 @return NO_ERROR On Success 82 @return NO_MEMORY If unable to allocate memory for the semaphore 83 @return BAD_VALUE If an invalid count value is passed (<0) 84 @return One of the android error codes based on semaphore initialization 85 */ 86 87 status_t Semaphore::Create(int count) 88 { 89 status_t ret = NO_ERROR; 90 91 ///count cannot be less than zero 92 if(count<0) 93 { 94 return BAD_VALUE; 95 } 96 97 ret = Release(); 98 if ( NO_ERROR != ret ) 99 { 100 return ret; 101 } 102 103 ///allocate memory for the semaphore 104 mSemaphore = (sem_t*)malloc(sizeof(sem_t)) ; 105 106 ///if memory is unavailable, return error 107 if(!mSemaphore) 108 { 109 return NO_MEMORY; 110 } 111 112 ///Initialize the semaphore and return the status 113 return ErrorUtils::posixToAndroidError(sem_init(mSemaphore, 0x00, count)); 114 115 } 116 117 /** 118 @brief Wait operation 119 120 @param none 121 @return BAD_VALUE if the semaphore is not initialized 122 @return NO_ERROR On success 123 @return One of the android error codes based on semaphore wait operation 124 */ 125 status_t Semaphore::Wait() 126 { 127 ///semaphore should have been created first 128 if(!mSemaphore) 129 { 130 return BAD_VALUE; 131 } 132 133 ///Wait and return the status after signalling 134 return ErrorUtils::posixToAndroidError(sem_wait(mSemaphore)); 135 136 137 } 138 139 140 /** 141 @brief Signal operation 142 143 @param none 144 @return BAD_VALUE if the semaphore is not initialized 145 @return NO_ERROR On success 146 @return One of the android error codes based on semaphore signal operation 147 */ 148 149 status_t Semaphore::Signal() 150 { 151 ///semaphore should have been created first 152 if(!mSemaphore) 153 { 154 return BAD_VALUE; 155 } 156 157 ///Post to the semaphore 158 return ErrorUtils::posixToAndroidError(sem_post(mSemaphore)); 159 160 } 161 162 /** 163 @brief Current semaphore count 164 165 @param none 166 @return Current count value of the semaphore 167 */ 168 int Semaphore::Count() 169 { 170 int val; 171 172 ///semaphore should have been created first 173 if(!mSemaphore) 174 { 175 return BAD_VALUE; 176 } 177 178 ///get the value of the semaphore 179 sem_getvalue(mSemaphore, &val); 180 181 return val; 182 } 183 184 /** 185 @brief Wait operation with a timeout 186 187 @param timeoutMicroSecs The timeout period in micro seconds 188 @return BAD_VALUE if the semaphore is not initialized 189 @return NO_ERROR On success 190 @return One of the android error codes based on semaphore wait operation 191 */ 192 193 status_t Semaphore::WaitTimeout(int timeoutMicroSecs) 194 { 195 status_t ret = NO_ERROR; 196 197 struct timespec timeSpec; 198 struct timeval currentTime; 199 200 ///semaphore should have been created first 201 if( NULL == mSemaphore) 202 { 203 ret = BAD_VALUE; 204 } 205 206 if ( NO_ERROR == ret ) 207 { 208 209 ///setup the timeout values - timeout is specified in seconds and nanoseconds 210 gettimeofday(¤tTime, NULL); 211 timeSpec.tv_sec = currentTime.tv_sec; 212 timeSpec.tv_nsec = currentTime.tv_usec * 1000; 213 timeSpec.tv_sec += ( timeoutMicroSecs / 1000000 ); 214 timeSpec.tv_nsec += ( timeoutMicroSecs % 1000000) * 1000; 215 216 ///Wait for the timeout or signal and return the result based on whichever event occurred first 217 ret = sem_timedwait(mSemaphore, &timeSpec); 218 } 219 220 if ( NO_ERROR != ret ) 221 { 222 Signal(); 223 Create(0); 224 } 225 226 return ret; 227 } 228 229 230 }; 231 232 233