1/*
2 * Copyright (C) 2009 The Android Open Source Project
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#include "rsSignal.h"
18
19using namespace android;
20using namespace android::renderscript;
21
22
23Signal::Signal() {
24    mSet = true;
25}
26
27Signal::~Signal() {
28    pthread_mutex_destroy(&mMutex);
29    pthread_cond_destroy(&mCondition);
30}
31
32bool Signal::init() {
33    int status = pthread_mutex_init(&mMutex, NULL);
34    if (status) {
35        ALOGE("LocklessFifo mutex init failure");
36        return false;
37    }
38
39    status = pthread_cond_init(&mCondition, NULL);
40    if (status) {
41        ALOGE("LocklessFifo condition init failure");
42        pthread_mutex_destroy(&mMutex);
43        return false;
44    }
45
46    return true;
47}
48
49void Signal::set() {
50    int status;
51
52    status = pthread_mutex_lock(&mMutex);
53    if (status) {
54        ALOGE("LocklessCommandFifo: error %i locking for set condition.", status);
55        return;
56    }
57
58    mSet = true;
59
60    status = pthread_cond_signal(&mCondition);
61    if (status) {
62        ALOGE("LocklessCommandFifo: error %i on set condition.", status);
63    }
64
65    status = pthread_mutex_unlock(&mMutex);
66    if (status) {
67        ALOGE("LocklessCommandFifo: error %i unlocking for set condition.", status);
68    }
69}
70
71bool Signal::wait(uint64_t timeout) {
72    int status;
73    bool ret = false;
74
75    status = pthread_mutex_lock(&mMutex);
76    if (status) {
77        ALOGE("LocklessCommandFifo: error %i locking for condition.", status);
78        return false;
79    }
80
81    if (!mSet) {
82        if (!timeout) {
83            status = pthread_cond_wait(&mCondition, &mMutex);
84        } else {
85#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
86            status = pthread_cond_timeout_np(&mCondition, &mMutex, timeout / 1000000);
87#else
88            // This is safe it will just make things less reponsive
89            status = pthread_cond_wait(&mCondition, &mMutex);
90#endif
91        }
92    }
93
94    if (!status) {
95        mSet = false;
96        ret = true;
97    } else {
98        if (status != ETIMEDOUT) {
99            ALOGE("LocklessCommandFifo: error %i waiting for condition.", status);
100        }
101    }
102
103    status = pthread_mutex_unlock(&mMutex);
104    if (status) {
105        ALOGE("LocklessCommandFifo: error %i unlocking for condition.", status);
106    }
107
108    return ret;
109}
110
111