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