From c322989ae6ff6769490828de1b5eda12b749cce9 Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Mon, 8 Aug 2011 11:24:41 -0700 Subject: initial commit Change-Id: I8f7a7eeece0e516efa486b77e9d97805c0e65d3e Signed-off-by: Iliyan Malchev --- libtiutils/Android.mk | 35 ++++ libtiutils/DebugUtils.h | 36 ++++ libtiutils/ErrorUtils.cpp | 141 ++++++++++++++++ libtiutils/ErrorUtils.h | 52 ++++++ libtiutils/MessageQueue.cpp | 397 ++++++++++++++++++++++++++++++++++++++++++++ libtiutils/MessageQueue.h | 105 ++++++++++++ libtiutils/Semaphore.cpp | 226 +++++++++++++++++++++++++ libtiutils/Semaphore.h | 59 +++++++ 8 files changed, 1051 insertions(+) create mode 100755 libtiutils/Android.mk create mode 100644 libtiutils/DebugUtils.h create mode 100644 libtiutils/ErrorUtils.cpp create mode 100644 libtiutils/ErrorUtils.h create mode 100755 libtiutils/MessageQueue.cpp create mode 100755 libtiutils/MessageQueue.h create mode 100644 libtiutils/Semaphore.cpp create mode 100644 libtiutils/Semaphore.h (limited to 'libtiutils') diff --git a/libtiutils/Android.mk b/libtiutils/Android.mk new file mode 100755 index 0000000..7312222 --- /dev/null +++ b/libtiutils/Android.mk @@ -0,0 +1,35 @@ +################################################ + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_PRELINK_MODULE := false + +LOCAL_SRC_FILES:= \ + MessageQueue.cpp \ + Semaphore.cpp \ + ErrorUtils.cpp + +LOCAL_SHARED_LIBRARIES:= \ + libdl \ + libui \ + libbinder \ + libutils \ + libcutils + +LOCAL_C_INCLUDES += \ + kernel/android-2.6.29/include \ + frameworks/base/include/utils \ + bionic/libc/include \ + hardware/ti/omap4xxx/domx/omx_core/inc \ + hardware/ti/omap4xxx/domx/mm_osal/inc + +LOCAL_CFLAGS += -fno-short-enums + +# LOCAL_CFLAGS += + +LOCAL_MODULE:= libtiutils +LOCAL_MODULE_TAGS:= optional + +include $(BUILD_HEAPTRACKED_SHARED_LIBRARY) diff --git a/libtiutils/DebugUtils.h b/libtiutils/DebugUtils.h new file mode 100644 index 0000000..54edfc7 --- /dev/null +++ b/libtiutils/DebugUtils.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#ifndef DEBUG_UTILS_H +#define DEBUG_UTILS_H + +///Defines for debug statements - Macro LOG_TAG needs to be defined in the respective files +#define DBGUTILS_LOGVA(str) LOGV("%s:%d %s - " str,__FILE__, __LINE__,__FUNCTION__); +#define DBGUTILS_LOGVB(str,...) LOGV("%s:%d %s - " str,__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__); +#define DBGUTILS_LOGDA(str) LOGD("%s:%d %s - " str,__FILE__, __LINE__,__FUNCTION__); +#define DBGUTILS_LOGDB(str, ...) LOGD("%s:%d %s - " str,__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__); +#define DBGUTILS_LOGEA(str) LOGE("%s:%d %s - " str,__FILE__, __LINE__, __FUNCTION__); +#define DBGUTILS_LOGEB(str, ...) LOGE("%s:%d %s - " str,__FILE__, __LINE__,__FUNCTION__, __VA_ARGS__); +#define LOG_FUNCTION_NAME LOGV("%d: %s() ENTER", __LINE__, __FUNCTION__); +#define LOG_FUNCTION_NAME_EXIT LOGV("%d: %s() EXIT", __LINE__, __FUNCTION__); + + + + +#endif //DEBUG_UTILS_H + diff --git a/libtiutils/ErrorUtils.cpp b/libtiutils/ErrorUtils.cpp new file mode 100644 index 0000000..df0e51c --- /dev/null +++ b/libtiutils/ErrorUtils.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "ErrorUtils.h" + +namespace android { + +/** + @brief Method to convert from POSIX to Android errors + + @param error Any of the standard POSIX error codes (defined in bionic/libc/kernel/common/asm-generic/errno.h) + @return Any of the standard Android error code (defined in frameworks/base/include/utils/Errors.h) + */ +status_t ErrorUtils::posixToAndroidError(int error) +{ + switch(error) + { + case 0: + return NO_ERROR; + case EINVAL: + case EFBIG: + case EMSGSIZE: + case E2BIG: + case EFAULT: + case EILSEQ: + return BAD_VALUE; + case ENOSYS: + return INVALID_OPERATION; + case EACCES: + case EPERM: + return PERMISSION_DENIED; + case EADDRINUSE: + case EAGAIN: + case EALREADY: + case EBUSY: + case EEXIST: + case EINPROGRESS: + return ALREADY_EXISTS; + case ENOMEM: + return NO_MEMORY; + default: + return UNKNOWN_ERROR; + }; + + return NO_ERROR; +} + + +/** + @brief Method to convert from TI OSAL to Android errors + + @param error Any of the standard TI OSAL error codes (defined in + hardware/ti/omx/ducati/domx/system/mm_osal/inc/timm_osal_error.h) + @return Any of the standard Android error code (defined in frameworks/base/include/utils/Errors.h) + */ +status_t ErrorUtils::osalToAndroidError(TIMM_OSAL_ERRORTYPE error) +{ + switch(error) + { + case TIMM_OSAL_ERR_NONE: + return NO_ERROR; + case TIMM_OSAL_ERR_ALLOC: + return NO_MEMORY; + default: + return UNKNOWN_ERROR; + } + + return NO_ERROR; +} + +/** + @brief Method to convert from OMX to Android errors + + @param error Any of the standard OMX error codes (defined in hardware/ti/omx/ducati/domx/system/omx_core/inc/OMX_Core.h) + @return Any of the standard Android error code (defined in frameworks/base/include/utils/Errors.h) + */ +status_t ErrorUtils::omxToAndroidError(OMX_ERRORTYPE error) +{ + switch(error) + { + case OMX_ErrorNone: + return NO_ERROR; + case OMX_ErrorBadParameter: + case OMX_ErrorInvalidComponentName: + case OMX_ErrorUndefined: + case OMX_ErrorInvalidState: + case OMX_ErrorStreamCorrupt: + case OMX_ErrorPortsNotCompatible: + case OMX_ErrorVersionMismatch: + case OMX_ErrorMbErrorsInFrame: + return BAD_VALUE; + case OMX_ErrorInsufficientResources: + return NO_MEMORY; + case OMX_ErrorComponentNotFound: + case OMX_ErrorNotImplemented: + case OMX_ErrorFormatNotDetected: + case OMX_ErrorUnsupportedSetting: + return NAME_NOT_FOUND; + case OMX_ErrorUnderflow: + case OMX_ErrorOverflow: + case OMX_ErrorUnsupportedIndex: + case OMX_ErrorBadPortIndex: + return BAD_INDEX; + case OMX_ErrorHardware: + case OMX_ErrorContentPipeCreationFailed: + case OMX_ErrorContentPipeOpenFailed: + return FAILED_TRANSACTION; + case OMX_ErrorTimeout: + return TIMED_OUT; + case OMX_ErrorSameState: + case OMX_ErrorIncorrectStateTransition: + case OMX_ErrorIncorrectStateOperation: + return PERMISSION_DENIED; + case OMX_ErrorTunnelingUnsupported: + return INVALID_OPERATION; + default: + return UNKNOWN_ERROR; + } + + return NO_ERROR; +} + + +}; + + + diff --git a/libtiutils/ErrorUtils.h b/libtiutils/ErrorUtils.h new file mode 100644 index 0000000..24dd806 --- /dev/null +++ b/libtiutils/ErrorUtils.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ERROR_UTILS_H +#define ERROR_UTILS_H + +///Header file where all the android error codes are defined +#include + +///Header file where all the OMX error codes are defined +#include "OMX_Core.h" + + +extern "C" +{ +///Header file where all the TI OSAL error codes are defined +#include "timm_osal_error.h" +}; + +namespace android { + +///Generic class with static methods to convert any standard error type to Android error type +class ErrorUtils +{ +public: + ///Method to convert from POSIX to Android errors + static status_t posixToAndroidError(int error); + + ///Method to convert from TI OSAL to Android errors + static status_t osalToAndroidError(TIMM_OSAL_ERRORTYPE error); + + ///Method to convert from OMX to Android errors + static status_t omxToAndroidError(OMX_ERRORTYPE error); + +}; + +}; + +#endif /// ERROR_UTILS_H diff --git a/libtiutils/MessageQueue.cpp b/libtiutils/MessageQueue.cpp new file mode 100755 index 0000000..1a5942a --- /dev/null +++ b/libtiutils/MessageQueue.cpp @@ -0,0 +1,397 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include +#include +#include + + + +#define LOG_TAG "MessageQueue" +#include + +#include "MessageQueue.h" + +namespace TIUTILS { + +/** + @brief Constructor for the message queue class + + @param none + @return none + */ +MessageQueue::MessageQueue() +{ + LOG_FUNCTION_NAME; + + int fds[2] = {-1,-1}; + android::status_t stat; + + stat = pipe(fds); + + if ( 0 > stat ) + { + MSGQ_LOGEB("Error while openning pipe: %s", strerror(stat) ); + this->fd_read = 0; + this->fd_write = 0; + mHasMsg = false; + } + else + { + this->fd_read = fds[0]; + this->fd_write = fds[1]; + + mHasMsg = false; + } + + LOG_FUNCTION_NAME_EXIT; +} + +/** + @brief Destructor for the semaphore class + + @param none + @return none + */ +MessageQueue::~MessageQueue() +{ + LOG_FUNCTION_NAME; + + if(this->fd_read) + { + close(this->fd_read); + } + + if(this->fd_write) + { + close(this->fd_write); + } + + LOG_FUNCTION_NAME_EXIT; +} + +/** + @brief Get a message from the queue + + @param msg Message structure to hold the message to be retrieved + @return android::NO_ERROR On success + @return android::BAD_VALUE if the message pointer is NULL + @return android::NO_INIT If the file read descriptor is not set + @return android::UNKNOWN_ERROR if the read operation fromthe file read descriptor fails + */ +android::status_t MessageQueue::get(Message* msg) +{ + LOG_FUNCTION_NAME; + + if(!msg) + { + MSGQ_LOGEA("msg is NULL"); + LOG_FUNCTION_NAME_EXIT; + return android::BAD_VALUE; + } + + if(!this->fd_read) + { + MSGQ_LOGEA("read descriptor not initialized for message queue"); + LOG_FUNCTION_NAME_EXIT; + return android::NO_INIT; + } + + char* p = (char*) msg; + size_t read_bytes = 0; + + while( read_bytes < sizeof(*msg) ) + { + int err = read(this->fd_read, p, sizeof(*msg) - read_bytes); + + if( err < 0 ) + { + MSGQ_LOGEB("read() error: %s", strerror(errno)); + return android::UNKNOWN_ERROR; + } + else + { + read_bytes += err; + } + } + + MSGQ_LOGDB("MQ.get(%d,%p,%p,%p,%p)", msg->command, msg->arg1,msg->arg2,msg->arg3,msg->arg4); + + mHasMsg = false; + + LOG_FUNCTION_NAME_EXIT; + + return 0; +} + +/** + @brief Get the input file descriptor of the message queue + + @param none + @return file read descriptor + */ + +int MessageQueue::getInFd() +{ + return this->fd_read; +} + +/** + @brief Constructor for the message queue class + + @param fd file read descriptor + @return none + */ + +void MessageQueue::setInFd(int fd) +{ + LOG_FUNCTION_NAME; + + if ( -1 != this->fd_read ) + { + close(this->fd_read); + } + + this->fd_read = fd; + + LOG_FUNCTION_NAME_EXIT; +} + +/** + @brief Queue a message + + @param msg Message structure to hold the message to be retrieved + @return android::NO_ERROR On success + @return android::BAD_VALUE if the message pointer is NULL + @return android::NO_INIT If the file write descriptor is not set + @return android::UNKNOWN_ERROR if the write operation fromthe file write descriptor fails + */ + +android::status_t MessageQueue::put(Message* msg) +{ + LOG_FUNCTION_NAME; + + char* p = (char*) msg; + size_t bytes = 0; + + if(!msg) + { + MSGQ_LOGEA("msg is NULL"); + LOG_FUNCTION_NAME_EXIT; + return android::BAD_VALUE; + } + + if(!this->fd_write) + { + MSGQ_LOGEA("write descriptor not initialized for message queue"); + LOG_FUNCTION_NAME_EXIT; + return android::NO_INIT; + } + + + MSGQ_LOGDB("MQ.put(%d,%p,%p,%p,%p)", msg->command, msg->arg1,msg->arg2,msg->arg3,msg->arg4); + + while( bytes < sizeof(msg) ) + { + int err = write(this->fd_write, p, sizeof(*msg) - bytes); + + if( err < 0 ) + { + MSGQ_LOGEB("write() error: %s", strerror(errno)); + LOG_FUNCTION_NAME_EXIT; + return android::UNKNOWN_ERROR; + } + else + { + bytes += err; + } + } + + MSGQ_LOGDA("MessageQueue::put EXIT"); + + LOG_FUNCTION_NAME_EXIT; + return 0; +} + + +/** + @brief Returns if the message queue is empty or not + + @param none + @return true If the queue is empty + @return false If the queue has at least one message + */ +bool MessageQueue::isEmpty() +{ + LOG_FUNCTION_NAME; + + struct pollfd pfd; + + pfd.fd = this->fd_read; + pfd.events = POLLIN; + pfd.revents = 0; + + if(!this->fd_read) + { + MSGQ_LOGEA("read descriptor not initialized for message queue"); + LOG_FUNCTION_NAME_EXIT; + return android::NO_INIT; + } + + + if( -1 == poll(&pfd,1,0) ) + { + MSGQ_LOGEB("poll() error: %s", strerror(errno)); + LOG_FUNCTION_NAME_EXIT; + return false; + } + + if(pfd.revents & POLLIN) + { + mHasMsg = true; + } + else + { + mHasMsg = false; + } + + LOG_FUNCTION_NAME_EXIT; + return !mHasMsg; +} + +/** + @brief Force whether the message queue has message or not + + @param hasMsg Whether the queue has a message or not + @return none + */ +void MessageQueue::setMsg(bool hasMsg) + { + mHasMsg = hasMsg; + } + + +/** + @briefWait for message in maximum three different queues with a timeout + + @param queue1 First queue. At least this should be set to a valid queue pointer + @param queue2 Second queue. Optional. + @param queue3 Third queue. Optional. + @param timeout The timeout value (in micro secs) to wait for a message in any of the queues + @return android::NO_ERROR On success + @return android::BAD_VALUE If queue1 is NULL + @return android::NO_INIT If the file read descriptor of any of the provided queues is not set + */ +android::status_t MessageQueue::waitForMsg(MessageQueue *queue1, MessageQueue *queue2, MessageQueue *queue3, int timeout) + { + LOG_FUNCTION_NAME; + + int n =1; + struct pollfd pfd[3]; + + if(!queue1) + { + MSGQ_LOGEA("queue1 pointer is NULL"); + LOG_FUNCTION_NAME_EXIT; + return android::BAD_VALUE; + } + + pfd[0].fd = queue1->getInFd(); + if(!pfd[0].fd) + { + MSGQ_LOGEA("read descriptor not initialized for message queue1"); + LOG_FUNCTION_NAME_EXIT; + return android::NO_INIT; + } + pfd[0].events = POLLIN; + pfd[0].revents = 0; + if(queue2) + { + MSGQ_LOGDA("queue2 not-null"); + pfd[1].fd = queue2->getInFd(); + if(!pfd[1].fd) + { + MSGQ_LOGEA("read descriptor not initialized for message queue2"); + LOG_FUNCTION_NAME_EXIT; + return android::NO_INIT; + } + + pfd[1].events = POLLIN; + pfd[1].revents = 0; + n++; + } + + if(queue3) + { + MSGQ_LOGDA("queue3 not-null"); + pfd[2].fd = queue3->getInFd(); + if(!pfd[2].fd) + { + MSGQ_LOGEA("read descriptor not initialized for message queue3"); + LOG_FUNCTION_NAME_EXIT; + return android::NO_INIT; + } + + pfd[2].events = POLLIN; + pfd[2].revents = 0; + n++; + } + + + int ret = poll(pfd, n, timeout); + if(ret==0) + { + LOG_FUNCTION_NAME_EXIT; + return ret; + } + + if(retsetMsg(true); + } + + if(queue2) + { + if (pfd[1].revents & POLLIN) + { + queue2->setMsg(true); + } + } + + if(queue3) + { + if (pfd[2].revents & POLLIN) + { + queue3->setMsg(true); + } + } + + LOG_FUNCTION_NAME_EXIT; + return ret; + } + +}; diff --git a/libtiutils/MessageQueue.h b/libtiutils/MessageQueue.h new file mode 100755 index 0000000..97e11a7 --- /dev/null +++ b/libtiutils/MessageQueue.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#ifndef __MESSAGEQUEUE_H__ +#define __MESSAGEQUEUE_H__ + +#include "DebugUtils.h" +#include + +///Uncomment this macro to debug the message queue implementation +//#define DEBUG_LOG + +///Camera HAL Logging Functions +#ifndef DEBUG_LOG + +#define MSGQ_LOGDA(str) +#define MSGQ_LOGDB(str, ...) + +#undef LOG_FUNCTION_NAME +#undef LOG_FUNCTION_NAME_EXIT +#define LOG_FUNCTION_NAME +#define LOG_FUNCTION_NAME_EXIT + +#else + +#define MSGQ_LOGDA DBGUTILS_LOGDA +#define MSGQ_LOGDB DBGUTILS_LOGDB + +#endif + +#define MSGQ_LOGEA DBGUTILS_LOGEA +#define MSGQ_LOGEB DBGUTILS_LOGEB + + +namespace TIUTILS { + +///Message type +struct Message +{ + unsigned int command; + void* arg1; + void* arg2; + void* arg3; + void* arg4; + int64_t id; +}; + +///Message queue implementation +class MessageQueue +{ +public: + + MessageQueue(); + ~MessageQueue(); + + ///Get a message from the queue + android::status_t get(Message*); + + ///Get the input file descriptor of the message queue + int getInFd(); + + ///Set the input file descriptor for the message queue + void setInFd(int fd); + + ///Queue a message + android::status_t put(Message*); + + ///Returns if the message queue is empty or not + bool isEmpty(); + + ///Force whether the message queue has message or not + void setMsg(bool hasMsg=false); + + ///Wait for message in maximum three different queues with a timeout + static int waitForMsg(MessageQueue *queue1, MessageQueue *queue2=0, MessageQueue *queue3=0, int timeout = 0); + + bool hasMsg() + { + return mHasMsg; + } + +private: + int fd_read; + int fd_write; + bool mHasMsg; +}; + +}; + +#endif diff --git a/libtiutils/Semaphore.cpp b/libtiutils/Semaphore.cpp new file mode 100644 index 0000000..1f46dca --- /dev/null +++ b/libtiutils/Semaphore.cpp @@ -0,0 +1,226 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#include "Semaphore.h" +#include "ErrorUtils.h" +#include +#include + +namespace android { + +/** + @brief Constructor for the semaphore class + + @param none + @return none + */ +Semaphore::Semaphore() +{ + ///Initialize the semaphore to NULL + mSemaphore = NULL; +} + +/** + @brief Destructor of the semaphore class + + @param none + @return none + + */ +Semaphore::~Semaphore() +{ + Release(); +} + +/** + @brief: Releases semaphore + + @param count >=0 + @return NO_ERROR On Success + @return One of the android error codes based on semaphore de-initialization + */ + +status_t Semaphore::Release() +{ + int status = 0; + + ///Destroy only if the semaphore has been created + if(mSemaphore) + { + status = sem_destroy(mSemaphore); + + free(mSemaphore); + + mSemaphore = NULL; + } + + ///Initialize the semaphore and return the status + return ErrorUtils::posixToAndroidError(status); + +} + +/** + @brief Create the semaphore with initial count value + + @param count >=0 + @return NO_ERROR On Success + @return NO_MEMORY If unable to allocate memory for the semaphore + @return BAD_VALUE If an invalid count value is passed (<0) + @return One of the android error codes based on semaphore initialization + */ + +status_t Semaphore::Create(int count) +{ + status_t ret = NO_ERROR; + + ///count cannot be less than zero + if(count<0) + { + return BAD_VALUE; + } + + ret = Release(); + if ( NO_ERROR != ret ) + { + return ret; + } + + ///allocate memory for the semaphore + mSemaphore = (sem_t*)malloc(sizeof(sem_t)) ; + + ///if memory is unavailable, return error + if(!mSemaphore) + { + return NO_MEMORY; + } + + ///Initialize the semaphore and return the status + return ErrorUtils::posixToAndroidError(sem_init(mSemaphore, 0x00, count)); + +} + +/** + @brief Wait operation + + @param none + @return BAD_VALUE if the semaphore is not initialized + @return NO_ERROR On success + @return One of the android error codes based on semaphore wait operation + */ +status_t Semaphore::Wait() +{ + ///semaphore should have been created first + if(!mSemaphore) + { + return BAD_VALUE; + } + + ///Wait and return the status after signalling + return ErrorUtils::posixToAndroidError(sem_wait(mSemaphore)); + + +} + + +/** + @brief Signal operation + + @param none + @return BAD_VALUE if the semaphore is not initialized + @return NO_ERROR On success + @return One of the android error codes based on semaphore signal operation + */ + +status_t Semaphore::Signal() +{ + ///semaphore should have been created first + if(!mSemaphore) + { + return BAD_VALUE; + } + + ///Post to the semaphore + return ErrorUtils::posixToAndroidError(sem_post(mSemaphore)); + +} + +/** + @brief Current semaphore count + + @param none + @return Current count value of the semaphore + */ +int Semaphore::Count() +{ + int val; + + ///semaphore should have been created first + if(!mSemaphore) + { + return BAD_VALUE; + } + + ///get the value of the semaphore + sem_getvalue(mSemaphore, &val); + + return val; +} + +/** + @brief Wait operation with a timeout + + @param timeoutMicroSecs The timeout period in micro seconds + @return BAD_VALUE if the semaphore is not initialized + @return NO_ERROR On success + @return One of the android error codes based on semaphore wait operation + */ + +status_t Semaphore::WaitTimeout(int timeoutMicroSecs) +{ + status_t ret = NO_ERROR; + + struct timespec timeSpec; + struct timeval currentTime; + + ///semaphore should have been created first + if( NULL == mSemaphore) + { + ret = BAD_VALUE; + } + + if ( NO_ERROR == ret ) + { + + ///setup the timeout values - timeout is specified in seconds and nanoseconds + gettimeofday(¤tTime, NULL); + timeSpec.tv_sec = currentTime.tv_sec; + timeSpec.tv_nsec = currentTime.tv_usec * 1000; + timeSpec.tv_sec += ( timeoutMicroSecs / 1000000 ); + timeSpec.tv_nsec += ( timeoutMicroSecs % 1000000) * 1000; + + ///Wait for the timeout or signal and return the result based on whichever event occurred first + ret = sem_timedwait(mSemaphore, &timeSpec); + } + + return ret; +} + + +}; + + diff --git a/libtiutils/Semaphore.h b/libtiutils/Semaphore.h new file mode 100644 index 0000000..466e709 --- /dev/null +++ b/libtiutils/Semaphore.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#include +#include +#include +#include +#include +#include +#include + +namespace android { + +class Semaphore +{ +public: + + Semaphore(); + ~Semaphore(); + + //Release semaphore + status_t Release(); + + ///Create the semaphore with initial count value + status_t Create(int count=0); + + ///Wait operation + status_t Wait(); + + ///Signal operation + status_t Signal(); + + ///Current semaphore count + int Count(); + + ///Wait operation with a timeout + status_t WaitTimeout(int timeoutMicroSecs); + +private: + sem_t *mSemaphore; + +}; + +}; -- cgit v1.2.3