172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/* 272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * Copyright (C) Texas Instruments - http://www.ti.com/ 372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * 472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * Licensed under the Apache License, Version 2.0 (the "License"); 572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * you may not use this file except in compliance with the License. 672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * You may obtain a copy of the License at 772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * 872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * http://www.apache.org/licenses/LICENSE-2.0 972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * 1072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * Unless required by applicable law or agreed to in writing, software 1172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * distributed under the License is distributed on an "AS IS" BASIS, 1272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * See the License for the specific language governing permissions and 1472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng * limitations under the License. 1572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 1672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 1772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 1872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 1972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng#include "Semaphore.h" 2072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng#include "ErrorUtils.h" 2172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng#include <utils/Log.h> 2272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng#include <time.h> 2372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 24f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Ti { 25f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Utils { 2672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 2772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/** 2872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @brief Constructor for the semaphore class 2972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 3072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @param none 3172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return none 3272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 3372dbc3152137ec7b77deddede4229f73149e92c8Akwasi BoatengSemaphore::Semaphore() 3472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng{ 3572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///Initialize the semaphore to NULL 3672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng mSemaphore = NULL; 3772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng} 3872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 3972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/** 4072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @brief Destructor of the semaphore class 4172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 4272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @param none 4372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return none 4472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 4572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 4672dbc3152137ec7b77deddede4229f73149e92c8Akwasi BoatengSemaphore::~Semaphore() 4772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng{ 4872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng Release(); 4972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng} 5072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 5172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/** 5272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @brief: Releases semaphore 5372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 5472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @param count >=0 5572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return NO_ERROR On Success 5672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return One of the android error codes based on semaphore de-initialization 5772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 5872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 5972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boatengstatus_t Semaphore::Release() 6072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng{ 6172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng int status = 0; 6272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 6372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///Destroy only if the semaphore has been created 6472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if(mSemaphore) 6572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 6672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng status = sem_destroy(mSemaphore); 6772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 6872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng free(mSemaphore); 6972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 7072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng mSemaphore = NULL; 7172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 7272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 7372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///Initialize the semaphore and return the status 7472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return ErrorUtils::posixToAndroidError(status); 7572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 7672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng} 7772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 7872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/** 7972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @brief Create the semaphore with initial count value 8072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 8172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @param count >=0 8272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return NO_ERROR On Success 8372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return NO_MEMORY If unable to allocate memory for the semaphore 8472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return BAD_VALUE If an invalid count value is passed (<0) 8572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return One of the android error codes based on semaphore initialization 8672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 8772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 8872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boatengstatus_t Semaphore::Create(int count) 8972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng{ 9072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng status_t ret = NO_ERROR; 9172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 9272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///count cannot be less than zero 9372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if(count<0) 9472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 9572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return BAD_VALUE; 9672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 9772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 9872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ret = Release(); 9972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if ( NO_ERROR != ret ) 10072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 10172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return ret; 10272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 10372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 10472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///allocate memory for the semaphore 10572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng mSemaphore = (sem_t*)malloc(sizeof(sem_t)) ; 10672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 10772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///if memory is unavailable, return error 10872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if(!mSemaphore) 10972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 11072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return NO_MEMORY; 11172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 11272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 11372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///Initialize the semaphore and return the status 11472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return ErrorUtils::posixToAndroidError(sem_init(mSemaphore, 0x00, count)); 11572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 11672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng} 11772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 11872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/** 11972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @brief Wait operation 12072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 12172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @param none 12272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return BAD_VALUE if the semaphore is not initialized 12372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return NO_ERROR On success 12472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return One of the android error codes based on semaphore wait operation 12572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 12672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boatengstatus_t Semaphore::Wait() 12772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng{ 12872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///semaphore should have been created first 12972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if(!mSemaphore) 13072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 13172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return BAD_VALUE; 13272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 13372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 13472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///Wait and return the status after signalling 13572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return ErrorUtils::posixToAndroidError(sem_wait(mSemaphore)); 13672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 13772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 13872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng} 13972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 14072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 14172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/** 14272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @brief Signal operation 14372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 14472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @param none 14572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return BAD_VALUE if the semaphore is not initialized 14672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return NO_ERROR On success 14772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return One of the android error codes based on semaphore signal operation 14872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 14972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 15072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boatengstatus_t Semaphore::Signal() 15172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng{ 15272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///semaphore should have been created first 15372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if(!mSemaphore) 15472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 15572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return BAD_VALUE; 15672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 15772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 15872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///Post to the semaphore 15972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return ErrorUtils::posixToAndroidError(sem_post(mSemaphore)); 16072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 16172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng} 16272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 16372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/** 16472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @brief Current semaphore count 16572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 16672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @param none 16772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return Current count value of the semaphore 16872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 16972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boatengint Semaphore::Count() 17072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng{ 17172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng int val; 17272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 17372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///semaphore should have been created first 17472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if(!mSemaphore) 17572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 17672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return BAD_VALUE; 17772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 17872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 17972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///get the value of the semaphore 18072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng sem_getvalue(mSemaphore, &val); 18172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 18272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return val; 18372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng} 18472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 18572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng/** 18672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @brief Wait operation with a timeout 18772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 18872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @param timeoutMicroSecs The timeout period in micro seconds 18972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return BAD_VALUE if the semaphore is not initialized 19072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return NO_ERROR On success 19172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng @return One of the android error codes based on semaphore wait operation 19272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng */ 19372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 19472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boatengstatus_t Semaphore::WaitTimeout(int timeoutMicroSecs) 19572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng{ 19672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng status_t ret = NO_ERROR; 19772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 19872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng struct timespec timeSpec; 19972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng struct timeval currentTime; 20072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 20172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///semaphore should have been created first 20272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if( NULL == mSemaphore) 20372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 20472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ret = BAD_VALUE; 20572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 20672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 20772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if ( NO_ERROR == ret ) 20872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 20972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 21072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///setup the timeout values - timeout is specified in seconds and nanoseconds 21172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng gettimeofday(¤tTime, NULL); 21272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng timeSpec.tv_sec = currentTime.tv_sec; 21372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng timeSpec.tv_nsec = currentTime.tv_usec * 1000; 21472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng timeSpec.tv_sec += ( timeoutMicroSecs / 1000000 ); 21572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng timeSpec.tv_nsec += ( timeoutMicroSecs % 1000000) * 1000; 21672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 21772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ///Wait for the timeout or signal and return the result based on whichever event occurred first 21872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng ret = sem_timedwait(mSemaphore, &timeSpec); 21972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 22072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 22172dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng if ( NO_ERROR != ret ) 22272dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng { 22372dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng Signal(); 22472dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng Create(0); 22572dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng } 22672dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 22772dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng return ret; 22872dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng} 22972dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 23072dbc3152137ec7b77deddede4229f73149e92c8Akwasi Boateng 231f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Utils 232f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Ti 233