1/******************************************************************************
2 *
3 *  Copyright (C) 2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  Encapsulate a condition variable for thread synchronization.
22 *
23 ******************************************************************************/
24#define LOG_TAG "NfcNciHal"
25#include "OverrideLog.h"
26#include "CondVar.h"
27#include <errno.h>
28
29
30/*******************************************************************************
31**
32** Function:        CondVar
33**
34** Description:     Initialize member variables.
35**
36** Returns:         None.
37**
38*******************************************************************************/
39CondVar::CondVar ()
40{
41    memset (&mCondition, 0, sizeof(mCondition));
42    int const res = pthread_cond_init (&mCondition, NULL);
43    if (res)
44    {
45        ALOGE ("CondVar::CondVar: fail init; error=0x%X", res);
46    }
47}
48
49
50/*******************************************************************************
51**
52** Function:        ~CondVar
53**
54** Description:     Cleanup all resources.
55**
56** Returns:         None.
57**
58*******************************************************************************/
59CondVar::~CondVar ()
60{
61    int const res = pthread_cond_destroy (&mCondition);
62    if (res)
63    {
64        ALOGE ("CondVar::~CondVar: fail destroy; error=0x%X", res);
65    }
66}
67
68
69/*******************************************************************************
70**
71** Function:        wait
72**
73** Description:     Block the caller and wait for a condition.
74**
75** Returns:         None.
76**
77*******************************************************************************/
78void CondVar::wait (Mutex& mutex)
79{
80    int const res = pthread_cond_wait (&mCondition, mutex.nativeHandle());
81    if (res)
82    {
83        ALOGE ("CondVar::wait: fail wait; error=0x%X", res);
84    }
85}
86
87
88/*******************************************************************************
89**
90** Function:        wait
91**
92** Description:     Block the caller and wait for a condition.
93**                  millisec: Timeout in milliseconds.
94**
95** Returns:         True if wait is successful; false if timeout occurs.
96**
97*******************************************************************************/
98bool CondVar::wait (Mutex& mutex, long millisec)
99{
100    bool retVal = false;
101    struct timespec absoluteTime;
102
103    if (clock_gettime (CLOCK_MONOTONIC, &absoluteTime) == -1)
104    {
105        ALOGE ("CondVar::wait: fail get time; errno=0x%X", errno);
106    }
107    else
108    {
109        absoluteTime.tv_sec += millisec / 1000;
110        long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000);
111        if (ns > 1000000000)
112        {
113            absoluteTime.tv_sec++;
114            absoluteTime.tv_nsec = ns - 1000000000;
115        }
116        else
117            absoluteTime.tv_nsec = ns;
118    }
119
120    //pthread_cond_timedwait_monotonic_np() is an Android-specific function
121    //declared in /development/ndk/platforms/android-9/include/pthread.h;
122    //it uses monotonic clock.
123    //the standard pthread_cond_timedwait() uses realtime clock.
124    int waitResult = pthread_cond_timedwait_monotonic_np (&mCondition, mutex.nativeHandle(), &absoluteTime);
125    if ((waitResult != 0) && (waitResult != ETIMEDOUT))
126        ALOGE ("CondVar::wait: fail timed wait; error=0x%X", waitResult);
127    retVal = (waitResult == 0); //waited successfully
128    return retVal;
129}
130
131
132/*******************************************************************************
133**
134** Function:        notifyOne
135**
136** Description:     Unblock the waiting thread.
137**
138** Returns:         None.
139**
140*******************************************************************************/
141void CondVar::notifyOne ()
142{
143    int const res = pthread_cond_signal (&mCondition);
144    if (res)
145    {
146        ALOGE ("CondVar::notifyOne: fail signal; error=0x%X", res);
147    }
148}
149
150