1ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte/*
2ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * Copyright (C) 2013 The Android Open Source Project
3ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte *
4ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * Licensed under the Apache License, Version 2.0 (the "License");
5ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * you may not use this file except in compliance with the License.
6ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * You may obtain a copy of the License at
7ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte *
8ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte *      http://www.apache.org/licenses/LICENSE-2.0
9ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte *
10ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * Unless required by applicable law or agreed to in writing, software
11ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * distributed under the License is distributed on an "AS IS" BASIS,
12ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * See the License for the specific language governing permissions and
14ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte * limitations under the License.
15ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte */
16ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
17ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte#include <pthread.h>
18ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
19d88dfe8607af019186a309674d9081a056ed3daaMark Salyzyn#include <algorithm>
20d88dfe8607af019186a309674d9081a056ed3daaMark Salyzyn
21d88dfe8607af019186a309674d9081a056ed3daaMark Salyzyn#include <log/log.h>
22d88dfe8607af019186a309674d9081a056ed3daaMark Salyzyn
23d88dfe8607af019186a309674d9081a056ed3daaMark Salyzyn#include <hardware/sensors.h>
24ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte#include "SensorEventQueue.h"
25ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
26ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron WhyteSensorEventQueue::SensorEventQueue(int capacity) {
27ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    mCapacity = capacity;
2892863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte
29ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    mStart = 0;
30ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    mSize = 0;
31ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    mData = new sensors_event_t[mCapacity];
32ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    pthread_cond_init(&mSpaceAvailableCondition, NULL);
33ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte}
34ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
35ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron WhyteSensorEventQueue::~SensorEventQueue() {
36ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    delete[] mData;
37ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    mData = NULL;
38ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    pthread_cond_destroy(&mSpaceAvailableCondition);
39ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte}
40ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
41ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyteint SensorEventQueue::getWritableRegion(int requestedLength, sensors_event_t** out) {
4292863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte    if (mSize == mCapacity || requestedLength <= 0) {
43ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte        *out = NULL;
44ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte        return 0;
45ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    }
46ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    // Start writing after the last readable record.
47ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    int firstWritable = (mStart + mSize) % mCapacity;
48ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
49ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    int lastWritable = firstWritable + requestedLength - 1;
50ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
51ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    // Don't go past the end of the data array.
52ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    if (lastWritable > mCapacity - 1) {
53ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte        lastWritable = mCapacity - 1;
54ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    }
55ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    // Don't go into the readable region.
56ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    if (firstWritable < mStart && lastWritable >= mStart) {
57ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte        lastWritable = mStart - 1;
58ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    }
59ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    *out = &mData[firstWritable];
60ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    return lastWritable - firstWritable + 1;
61ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte}
62ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
63ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whytevoid SensorEventQueue::markAsWritten(int count) {
64ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    mSize += count;
65ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte}
66ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
67ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyteint SensorEventQueue::getSize() {
68ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    return mSize;
69ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte}
70ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
71ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whytesensors_event_t* SensorEventQueue::peek() {
7292863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte    if (mSize == 0) return NULL;
73ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    return &mData[mStart];
74ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte}
75ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte
76ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whytevoid SensorEventQueue::dequeue() {
7792863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte    if (mSize == 0) return;
7892863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte    if (mSize == mCapacity) {
7992863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte        pthread_cond_broadcast(&mSpaceAvailableCondition);
8092863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte    }
81ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    mSize--;
82ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte    mStart = (mStart + 1) % mCapacity;
8392863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte}
8492863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte
85c69f3a70ecbc4303cdfdea961f7a2a4a8f58fa05Aaron Whyte// returns true if it waited, or false if it was a no-op.
86c69f3a70ecbc4303cdfdea961f7a2a4a8f58fa05Aaron Whytebool SensorEventQueue::waitForSpace(pthread_mutex_t* mutex) {
87c69f3a70ecbc4303cdfdea961f7a2a4a8f58fa05Aaron Whyte    bool waited = false;
8892863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte    while (mSize == mCapacity) {
89c69f3a70ecbc4303cdfdea961f7a2a4a8f58fa05Aaron Whyte        waited = true;
9092863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte        pthread_cond_wait(&mSpaceAvailableCondition, mutex);
9192863c14b7d36f74ec715b45ca6adc8bf95dc87cAaron Whyte    }
92c69f3a70ecbc4303cdfdea961f7a2a4a8f58fa05Aaron Whyte    return waited;
93ab6ec384c456022f37a9c6183d3afbcefcb436a9Aaron Whyte}
94