Home | History | Annotate | Download | only in libtiutils
      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(&currentTime, 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