• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&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