• 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 Ti {
25 namespace Utils {
26 
27 /**
28    @brief Constructor for the semaphore class
29 
30    @param none
31    @return none
32  */
Semaphore()33 Semaphore::Semaphore()
34 {
35     ///Initialize the semaphore to NULL
36     mSemaphore = NULL;
37 }
38 
39 /**
40    @brief Destructor of the semaphore class
41 
42    @param none
43    @return none
44 
45  */
~Semaphore()46 Semaphore::~Semaphore()
47 {
48     Release();
49 }
50 
51 /**
52    @brief: Releases semaphore
53 
54    @param count >=0
55    @return NO_ERROR On Success
56    @return One of the android error codes based on semaphore de-initialization
57  */
58 
Release()59 status_t Semaphore::Release()
60 {
61     int status = 0;
62 
63     ///Destroy only if the semaphore has been created
64     if(mSemaphore)
65         {
66         status = sem_destroy(mSemaphore);
67 
68         free(mSemaphore);
69 
70         mSemaphore = NULL;
71         }
72 
73     ///Initialize the semaphore and return the status
74     return ErrorUtils::posixToAndroidError(status);
75 
76 }
77 
78 /**
79    @brief Create the semaphore with initial count value
80 
81    @param count >=0
82    @return NO_ERROR On Success
83    @return NO_MEMORY If unable to allocate memory for the semaphore
84    @return BAD_VALUE If an invalid count value is passed (<0)
85    @return One of the android error codes based on semaphore initialization
86  */
87 
Create(int count)88 status_t Semaphore::Create(int count)
89 {
90     status_t ret = NO_ERROR;
91 
92     ///count cannot be less than zero
93     if(count<0)
94         {
95         return BAD_VALUE;
96         }
97 
98     ret = Release();
99     if ( NO_ERROR != ret )
100         {
101         return ret;
102         }
103 
104     ///allocate memory for the semaphore
105     mSemaphore = (sem_t*)malloc(sizeof(sem_t)) ;
106 
107     ///if memory is unavailable, return error
108     if(!mSemaphore)
109         {
110         return NO_MEMORY;
111         }
112 
113     ///Initialize the semaphore and return the status
114     return ErrorUtils::posixToAndroidError(sem_init(mSemaphore, 0x00, count));
115 
116 }
117 
118 /**
119    @brief Wait operation
120 
121    @param none
122    @return BAD_VALUE if the semaphore is not initialized
123    @return NO_ERROR On success
124    @return One of the android error codes based on semaphore wait operation
125  */
Wait()126 status_t Semaphore::Wait()
127 {
128     ///semaphore should have been created first
129     if(!mSemaphore)
130         {
131         return BAD_VALUE;
132         }
133 
134     ///Wait and return the status after signalling
135     return ErrorUtils::posixToAndroidError(sem_wait(mSemaphore));
136 
137 
138 }
139 
140 
141 /**
142    @brief Signal operation
143 
144    @param none
145      @return BAD_VALUE if the semaphore is not initialized
146      @return NO_ERROR On success
147      @return One of the android error codes based on semaphore signal operation
148    */
149 
Signal()150 status_t Semaphore::Signal()
151 {
152     ///semaphore should have been created first
153     if(!mSemaphore)
154         {
155         return BAD_VALUE;
156         }
157 
158     ///Post to the semaphore
159     return ErrorUtils::posixToAndroidError(sem_post(mSemaphore));
160 
161 }
162 
163 /**
164    @brief Current semaphore count
165 
166    @param none
167    @return Current count value of the semaphore
168  */
Count()169 int Semaphore::Count()
170 {
171     int val;
172 
173     ///semaphore should have been created first
174     if(!mSemaphore)
175         {
176         return BAD_VALUE;
177         }
178 
179     ///get the value of the semaphore
180     sem_getvalue(mSemaphore, &val);
181 
182     return val;
183 }
184 
185 /**
186    @brief Wait operation with a timeout
187 
188      @param timeoutMicroSecs The timeout period in micro seconds
189      @return BAD_VALUE if the semaphore is not initialized
190      @return NO_ERROR On success
191      @return One of the android error codes based on semaphore wait operation
192    */
193 
WaitTimeout(int timeoutMicroSecs)194 status_t Semaphore::WaitTimeout(int timeoutMicroSecs)
195 {
196     status_t ret = NO_ERROR;
197 
198     struct timespec timeSpec;
199     struct timeval currentTime;
200 
201     ///semaphore should have been created first
202     if( NULL == mSemaphore)
203         {
204         ret = BAD_VALUE;
205         }
206 
207     if ( NO_ERROR == ret )
208         {
209 
210         ///setup the timeout values - timeout is specified in seconds and nanoseconds
211         gettimeofday(&currentTime, NULL);
212         timeSpec.tv_sec = currentTime.tv_sec;
213         timeSpec.tv_nsec = currentTime.tv_usec * 1000;
214         timeSpec.tv_sec += ( timeoutMicroSecs / 1000000 );
215         timeSpec.tv_nsec += ( timeoutMicroSecs % 1000000) * 1000;
216 
217         ///Wait for the timeout or signal and return the result based on whichever event occurred first
218         ret = sem_timedwait(mSemaphore, &timeSpec);
219         }
220 
221     if ( NO_ERROR != ret )
222       {
223         Signal();
224         Create(0);
225       }
226 
227     return ret;
228 }
229 
230 
231 } // namespace Utils
232 } // namespace Ti
233