You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
5.8 KiB
199 lines
5.8 KiB
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <hardware/sensors.h> |
|
#include <pthread.h> |
|
#include <cutils/atomic.h> |
|
|
|
#include "SensorEventQueue.cpp" |
|
|
|
// Unit tests for the SensorEventQueue. |
|
|
|
// Run it like this: |
|
// |
|
// make sensorstests -j32 && \ |
|
// out/host/linux-x86/obj/EXECUTABLES/sensorstests_intermediates/sensorstests |
|
|
|
bool checkWritableBufferSize(SensorEventQueue* queue, int requested, int expected) { |
|
sensors_event_t* buffer; |
|
int actual = queue->getWritableRegion(requested, &buffer); |
|
if (actual != expected) { |
|
printf("Expected buffer size was %d; actual was %d\n", expected, actual); |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
bool checkSize(SensorEventQueue* queue, int expected) { |
|
int actual = queue->getSize(); |
|
if (actual != expected) { |
|
printf("Expected queue size was %d; actual was %d\n", expected, actual); |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
bool checkInt(const char* msg, int expected, int actual) { |
|
if (actual != expected) { |
|
printf("%s; expected %d; actual was %d\n", msg, expected, actual); |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
bool testSimpleWriteSizeCounts() { |
|
printf("testSimpleWriteSizeCounts\n"); |
|
SensorEventQueue* queue = new SensorEventQueue(10); |
|
if (!checkSize(queue, 0)) return false; |
|
if (!checkWritableBufferSize(queue, 11, 10)) return false; |
|
if (!checkWritableBufferSize(queue, 10, 10)) return false; |
|
if (!checkWritableBufferSize(queue, 9, 9)) return false; |
|
|
|
queue->markAsWritten(7); |
|
if (!checkSize(queue, 7)) return false; |
|
if (!checkWritableBufferSize(queue, 4, 3)) return false; |
|
if (!checkWritableBufferSize(queue, 3, 3)) return false; |
|
if (!checkWritableBufferSize(queue, 2, 2)) return false; |
|
|
|
queue->markAsWritten(3); |
|
if (!checkSize(queue, 10)) return false; |
|
if (!checkWritableBufferSize(queue, 1, 0)) return false; |
|
|
|
printf("passed\n"); |
|
return true; |
|
} |
|
|
|
bool testWrappingWriteSizeCounts() { |
|
printf("testWrappingWriteSizeCounts\n"); |
|
SensorEventQueue* queue = new SensorEventQueue(10); |
|
queue->markAsWritten(9); |
|
if (!checkSize(queue, 9)) return false; |
|
|
|
// dequeue from the front |
|
queue->dequeue(); |
|
queue->dequeue(); |
|
if (!checkSize(queue, 7)) return false; |
|
if (!checkWritableBufferSize(queue, 100, 1)) return false; |
|
|
|
// Write all the way to the end. |
|
queue->markAsWritten(1); |
|
if (!checkSize(queue, 8)) return false; |
|
// Now the two free spots in the front are available. |
|
if (!checkWritableBufferSize(queue, 100, 2)) return false; |
|
|
|
// Fill the queue again |
|
queue->markAsWritten(2); |
|
if (!checkSize(queue, 10)) return false; |
|
|
|
printf("passed\n"); |
|
return true; |
|
} |
|
|
|
|
|
|
|
struct TaskContext { |
|
bool success; |
|
SensorEventQueue* queue; |
|
}; |
|
|
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
|
static pthread_cond_t dataAvailableCond = PTHREAD_COND_INITIALIZER; |
|
|
|
int FULL_QUEUE_CAPACITY = 5; |
|
int FULL_QUEUE_EVENT_COUNT = 31; |
|
|
|
void *fullQueueWriterTask(void* ptr) { |
|
TaskContext* ctx = (TaskContext*)ptr; |
|
SensorEventQueue* queue = ctx->queue; |
|
ctx->success = true; |
|
int totalWaits = 0; |
|
int totalWrites = 0; |
|
sensors_event_t* buffer; |
|
|
|
while (totalWrites < FULL_QUEUE_EVENT_COUNT) { |
|
pthread_mutex_lock(&mutex); |
|
if (queue->waitForSpace(&mutex)) { |
|
totalWaits++; |
|
printf("."); |
|
} |
|
int writableSize = queue->getWritableRegion(FULL_QUEUE_CAPACITY, &buffer); |
|
queue->markAsWritten(writableSize); |
|
totalWrites += writableSize; |
|
for (int i = 0; i < writableSize; i++) { |
|
printf("w"); |
|
} |
|
pthread_cond_broadcast(&dataAvailableCond); |
|
pthread_mutex_unlock(&mutex); |
|
} |
|
printf("\n"); |
|
|
|
ctx->success = |
|
checkInt("totalWrites", FULL_QUEUE_EVENT_COUNT, totalWrites) && |
|
checkInt("totalWaits", FULL_QUEUE_EVENT_COUNT - FULL_QUEUE_CAPACITY, totalWaits); |
|
return NULL; |
|
} |
|
|
|
bool fullQueueReaderShouldRead(int queueSize, int totalReads) { |
|
if (queueSize == 0) { |
|
return false; |
|
} |
|
int totalWrites = totalReads + queueSize; |
|
return queueSize == FULL_QUEUE_CAPACITY || totalWrites == FULL_QUEUE_EVENT_COUNT; |
|
} |
|
|
|
void* fullQueueReaderTask(void* ptr) { |
|
TaskContext* ctx = (TaskContext*)ptr; |
|
SensorEventQueue* queue = ctx->queue; |
|
int totalReads = 0; |
|
while (totalReads < FULL_QUEUE_EVENT_COUNT) { |
|
pthread_mutex_lock(&mutex); |
|
// Only read if there are events, |
|
// and either the queue is full, or if we're reading the last few events. |
|
while (!fullQueueReaderShouldRead(queue->getSize(), totalReads)) { |
|
pthread_cond_wait(&dataAvailableCond, &mutex); |
|
} |
|
queue->dequeue(); |
|
totalReads++; |
|
printf("r"); |
|
pthread_mutex_unlock(&mutex); |
|
} |
|
printf("\n"); |
|
ctx->success = ctx->success && checkInt("totalreads", FULL_QUEUE_EVENT_COUNT, totalReads); |
|
return NULL; |
|
} |
|
|
|
// Test internal queue-full waiting and broadcasting. |
|
bool testFullQueueIo() { |
|
printf("testFullQueueIo\n"); |
|
SensorEventQueue* queue = new SensorEventQueue(FULL_QUEUE_CAPACITY); |
|
|
|
TaskContext readerCtx; |
|
readerCtx.success = true; |
|
readerCtx.queue = queue; |
|
|
|
TaskContext writerCtx; |
|
writerCtx.success = true; |
|
writerCtx.queue = queue; |
|
|
|
pthread_t writer, reader; |
|
pthread_create(&reader, NULL, fullQueueReaderTask, &readerCtx); |
|
pthread_create(&writer, NULL, fullQueueWriterTask, &writerCtx); |
|
|
|
pthread_join(writer, NULL); |
|
pthread_join(reader, NULL); |
|
|
|
if (!readerCtx.success || !writerCtx.success) return false; |
|
printf("passed\n"); |
|
return true; |
|
} |
|
|
|
|
|
int main(int argc __attribute((unused)), char **argv __attribute((unused))) { |
|
if (testSimpleWriteSizeCounts() && |
|
testWrappingWriteSizeCounts() && |
|
testFullQueueIo()) { |
|
printf("ALL PASSED\n"); |
|
} else { |
|
printf("SOMETHING FAILED\n"); |
|
} |
|
return EXIT_SUCCESS; |
|
}
|
|
|