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 */
Semaphore()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 */
~Semaphore()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
Release()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
Create(int count)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 */
Wait()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
Signal()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 */
Count()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
WaitTimeout(int timeoutMicroSecs)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