1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 #include "Semaphore.h"
18 
19 
Semaphore(int count)20 Semaphore::Semaphore(int count)
21 {
22     if (sem_init(&mSem, 0, count) != 0) {
23         ASSERT(false);
24     }
25 }
26 
~Semaphore()27 Semaphore::~Semaphore()
28 {
29     sem_destroy(&mSem);
30 }
31 
tryWait()32 void Semaphore::tryWait()
33 {
34     sem_trywait(&mSem);
35 }
36 
wait()37 bool Semaphore::wait()
38 {
39     if (sem_wait(&mSem) == 0) {
40         return true;
41     } else {
42         return false;
43     }
44 }
45 
timedWait(int timeInMSec)46 bool Semaphore::timedWait(int timeInMSec)
47 {
48     const int ONE_SEC_IN_NANOSEC = 1000000000;
49     const int ONE_MSEC_IN_NANOSEC = 1000000;
50     const int ONE_SEC_IN_MSEC = 1000;
51     struct timespec timeOld;
52     if (clock_gettime(CLOCK_REALTIME, &timeOld) != 0) {
53             return false;
54     }
55     int secToGo = timeInMSec / ONE_SEC_IN_MSEC;
56     int msecToGo = timeInMSec - (ONE_SEC_IN_MSEC * secToGo);
57     int nanoSecToGo = ONE_MSEC_IN_NANOSEC * msecToGo;
58     struct timespec timeNew = timeOld;
59     int nanoTotal = timeOld.tv_nsec + nanoSecToGo;
60     //LOGI("secToGo %d, msecToGo %d, nanoTotal %d", secToGo, msecToGo, nanoTotal);
61     if (nanoTotal > ONE_SEC_IN_NANOSEC) {
62         nanoTotal -= ONE_SEC_IN_NANOSEC;
63         secToGo += 1;
64     }
65     timeNew.tv_sec += secToGo;
66     timeNew.tv_nsec = nanoTotal;
67     //LOGV("Semaphore::timedWait now %d-%d until %d-%d for %d msecs",
68     //        timeOld.tv_sec, timeOld.tv_nsec, timeNew.tv_sec, timeNew.tv_nsec, timeInMSec);
69     if (sem_timedwait(&mSem, &timeNew) == 0) {
70         return true;
71     } else {
72         return false;
73     }
74 }
75 
post()76 void Semaphore::post()
77 {
78     sem_post(&mSem);
79 }
80