1/* 2 * Copyright (C) 2017 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 "RingBuffer.h" 18 19#include <stdlib.h> 20#include <string.h> 21 22namespace android { 23 24RingBuffer::RingBuffer(size_t size) 25 : mSize(size), 26 mData((sensors_event_t *)malloc(sizeof(sensors_event_t) * mSize)), 27 mReadPos(0), 28 mWritePos(0) { 29} 30 31RingBuffer::~RingBuffer() { 32 free(mData); 33 mData = NULL; 34} 35 36ssize_t RingBuffer::write(const sensors_event_t *ev, size_t size) { 37 Mutex::Autolock autoLock(mLock); 38 39 size_t numAvailableToRead = mWritePos - mReadPos; 40 size_t numAvailableToWrite = mSize - numAvailableToRead; 41 42 if (size > numAvailableToWrite) { 43 size = numAvailableToWrite; 44 } 45 46 size_t writePos = (mWritePos % mSize); 47 size_t copy = mSize - writePos; 48 49 if (copy > size) { 50 copy = size; 51 } 52 53 memcpy(&mData[writePos], ev, copy * sizeof(sensors_event_t)); 54 55 if (size > copy) { 56 memcpy(mData, &ev[copy], (size - copy) * sizeof(sensors_event_t)); 57 } 58 59 mWritePos += size; 60 61 if (numAvailableToRead == 0 && size > 0) { 62 mNotEmptyCondition.broadcast(); 63 } 64 65 return size; 66} 67 68ssize_t RingBuffer::read(sensors_event_t *ev, size_t size) { 69 Mutex::Autolock autoLock(mLock); 70 71 size_t numAvailableToRead; 72 for (;;) { 73 numAvailableToRead = mWritePos - mReadPos; 74 if (numAvailableToRead > 0) { 75 break; 76 } 77 78 mNotEmptyCondition.wait(mLock); 79 } 80 81 if (size > numAvailableToRead) { 82 size = numAvailableToRead; 83 } 84 85 size_t readPos = (mReadPos % mSize); 86 size_t copy = mSize - readPos; 87 88 if (copy > size) { 89 copy = size; 90 } 91 92 memcpy(ev, &mData[readPos], copy * sizeof(sensors_event_t)); 93 94 if (size > copy) { 95 memcpy(&ev[copy], mData, (size - copy) * sizeof(sensors_event_t)); 96 } 97 98 mReadPos += size; 99 100 return size; 101} 102 103} // namespace android 104 105