Semaphore.cpp revision 72dbc3152137ec7b77deddede4229f73149e92c8
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
24namespace android {
25
26/**
27   @brief Constructor for the semaphore class
28
29   @param none
30   @return none
31 */
32Semaphore::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 */
45Semaphore::~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
58status_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
87status_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 */
125status_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
149status_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 */
168int 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
193status_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