diff options
Diffstat (limited to 'libvideoeditor/osal/src/M4OSA_Semaphore.c')
-rwxr-xr-x | libvideoeditor/osal/src/M4OSA_Semaphore.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/libvideoeditor/osal/src/M4OSA_Semaphore.c b/libvideoeditor/osal/src/M4OSA_Semaphore.c new file mode 100755 index 0000000..a99b136 --- /dev/null +++ b/libvideoeditor/osal/src/M4OSA_Semaphore.c @@ -0,0 +1,264 @@ +/* + * Copyright (C) 2004-2011 NXP Software + * Copyright (C) 2011 The Android Open Source Project + * + * 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. + */ +/** + ************************************************************************ + * @file M4OSA_Semaphore.c + * @brief Semaphore for Windows + * @note This file implements functions to manipulate semaphore + ************************************************************************ +*/ + + + +#include "M4OSA_Debug.h" +#include "M4OSA_Types.h" +#include "M4OSA_Error.h" +#include "M4OSA_Memory.h" +#include "M4OSA_Semaphore.h" + +#include <semaphore.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <time.h> + + +/* Context for the semaphore */ +typedef struct { + M4OSA_UInt32 coreID; /* semaphore context identifiant */ + sem_t semaphore; /* semaphore */ +} M4OSA_SemaphoreContext; + + + + +/** + ************************************************************************ + * @brief This method creates a new semaphore with the "initialCounter" + * value. + * @note This function creates and allocates a unique context. It's the + * OSAL real time responsibility for managing its context. It must + * be freed by the M4OSA_semaphoreClose function. The context + * parameter will be sent back to any OSAL core semaphore functions + * to allow retrieving data associated to the opened semaphore. + * @param context:(OUT) Context of the created semaphore + * @param initial_count:(IN) Initial counter of the semaphore + * @return M4NO_ERROR: there is no error + * @return M4ERR_PARAMETER: provided context is NULL + * @return M4ERR_ALLOC: there is no more available memory + * @return M4ERR_CONTEXT_FAILED: the context creation failed + ************************************************************************ +*/ +M4OSA_ERR M4OSA_semaphoreOpen(M4OSA_Context* context, + M4OSA_UInt32 initial_count) +{ + M4OSA_SemaphoreContext* semaphoreContext = M4OSA_NULL; + + M4OSA_TRACE1_2("M4OSA_semaphoreOpen\t\tM4OSA_Context* 0x%x\tM4OSA_UInt32 " + "%d", context, initial_count); + + M4OSA_DEBUG_IF2(context == M4OSA_NULL, + M4ERR_PARAMETER, "M4OSA_semaphoreOpen"); + + *context = M4OSA_NULL; + + semaphoreContext = (M4OSA_SemaphoreContext*) M4OSA_malloc( + sizeof(M4OSA_SemaphoreContext), M4OSA_SEMAPHORE, + (M4OSA_Char*)"M4OSA_semaphoreOpen: semaphore context"); + + if(semaphoreContext == M4OSA_NULL) + { + M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_semaphoreOpen"); + + return M4ERR_ALLOC; + } + + if (0 != sem_init(&semaphoreContext->semaphore, 0, initial_count)) + { + M4OSA_free((M4OSA_MemAddr32)semaphoreContext); + + M4OSA_DEBUG(M4ERR_CONTEXT_FAILED, + "M4OSA_semaphoreOpen: OS semaphore creation failed"); + + return M4ERR_CONTEXT_FAILED; + } + + semaphoreContext->coreID = M4OSA_SEMAPHORE ; + *context = (M4OSA_Context)semaphoreContext; + + return M4NO_ERROR; +} + + + + +/** + ************************************************************************ + * @brief This method decrements (one by one) the semaphore counter. The + * semaphore is identified by its context This call is not blocking + * if the semaphore counter is positive or zero (after + * decrementation). This call is blocking if the semaphore counter + * is less than zero (after decrementation), until the semaphore is + * upper than zero (see M4OSA_semaphorePost) or time_out is + * reached. + * @note If "timeout" value is M4OSA_WAIT_FOREVER, the calling thread + * will block indefinitely until the semaphore is unlocked. + * @param context:(IN/OUT) Context of the semaphore + * @param timeout:(IN) Time out in milliseconds + * @return M4NO_ERROR: there is no error + * @return M4ERR_PARAMETER: at least one parameter is NULL + * @return M4WAR_TIME_OUT: time out is elapsed before semaphore has been + * available. + * @return M4ERR_BAD_CONTEXT: provided context is not a valid one + ************************************************************************ +*/ +M4OSA_ERR M4OSA_semaphoreWait(M4OSA_Context context, M4OSA_Int32 timeout) +{ + M4OSA_SemaphoreContext* semaphoreContext = (M4OSA_SemaphoreContext*)context; + struct timespec ts; + struct timespec left; + int result; + + M4OSA_TRACE1_2("M4OSA_semaphoreWait\t\tM4OSA_Context 0x%x\tM4OSA_UInt32 %d", + context, timeout); + + M4OSA_DEBUG_IF2(context == M4OSA_NULL, + M4ERR_PARAMETER, "M4OSA_semaphoreWait"); + + M4OSA_DEBUG_IF2(semaphoreContext->coreID != M4OSA_SEMAPHORE, + M4ERR_BAD_CONTEXT, "M4OSA_semaphoreWait"); + + if ( (M4OSA_Int32)M4OSA_WAIT_FOREVER == timeout) + { + if ( 0 != sem_wait(&semaphoreContext->semaphore) ) + { + M4OSA_DEBUG(M4ERR_BAD_CONTEXT, + "M4OSA_semaphoreWait: OS semaphore wait failed"); + + return M4ERR_BAD_CONTEXT ; + } + } + else + { + result = sem_trywait(&semaphoreContext->semaphore); + while ( ((EBUSY == result) || (EAGAIN == result)) && ( 0 < timeout ) ) + { + ts.tv_sec = 0; + if (1 <= timeout) + { + ts.tv_nsec = 1000000; + timeout -= 1; + } + else + { + ts.tv_nsec = timeout * 1000000; + timeout = 0; + } + nanosleep(&ts, &left); + result = sem_trywait(&semaphoreContext->semaphore); + } + if (0 != result) + { + if ((EBUSY == result) || (EAGAIN == result)) + { + return M4WAR_TIME_OUT; + } + else + { + M4OSA_DEBUG(M4ERR_BAD_CONTEXT, "M4OSA_semaphoreWait: OS semaphore wait failed"); + return M4ERR_BAD_CONTEXT; + } + } + } + + return M4NO_ERROR; +} + + + + + +/** + ************************************************************************ + * @brief This method increments the semaphore counter. The semaphore is + * identified by its context + * @note If the semaphore counter is upper than zero (after addition), + * the M4OSA_semaphoreWait call of the thread with the highest + * priority is unblocked and made ready to run. + * @note No hypotheses can be made on which thread will be unblocked + * between threads with the same priority. + * @param context:(IN/OUT) Context of the semaphore + * @return M4NO_ERROR: there is no error + * @return M4ERR_PARAMETER: at least one parameter is NULL + * @return M4ERR_BAD_CONTEXT: provided context is not a valid one +************************************************************************ +*/ +M4OSA_ERR M4OSA_semaphorePost(M4OSA_Context context) +{ + M4OSA_SemaphoreContext* semaphoreContext = (M4OSA_SemaphoreContext*)context; + + M4OSA_TRACE1_1("M4OSA_semaphorePost\t\tM4OSA_Context 0x%x", context); + + M4OSA_DEBUG_IF2(context == M4OSA_NULL, + M4ERR_PARAMETER, "M4OSA_semaphorePost"); + + M4OSA_DEBUG_IF2(semaphoreContext->coreID != M4OSA_SEMAPHORE, + M4ERR_BAD_CONTEXT, "M4OSA_semaphorePost"); + + sem_post(&semaphoreContext->semaphore); + + return M4NO_ERROR; +} + + + + + +/** + ************************************************************************ + * @brief This method deletes a semaphore (identify by its context). + * After this call the semaphore and its context is no more + * useable. This function frees all the memory related to this + * semaphore. + * @note It is an application issue to warrant no more threads are locked + * on the deleted semaphore. + * @param context:(IN/OUT) Context of the semaphore + * @return M4NO_ERROR: there is no error + * @return M4ERR_PARAMETER: at least one parameter is NULL + * @return M4ERR_BAD_CONTEXT: provided context is not a valid one. +************************************************************************ +*/ +M4OSA_ERR M4OSA_semaphoreClose(M4OSA_Context context) +{ + M4OSA_SemaphoreContext* semaphoreContext = (M4OSA_SemaphoreContext*)context; + + M4OSA_TRACE1_1("M4OSA_semaphoreClose\t\tM4OSA_Context 0x%x", context); + + M4OSA_DEBUG_IF2(context == M4OSA_NULL, + M4ERR_PARAMETER, "M4OSA_semaphoreClose"); + + M4OSA_DEBUG_IF2(semaphoreContext->coreID != M4OSA_SEMAPHORE, + M4ERR_BAD_CONTEXT, "M4OSA_semaphoreClose"); + + sem_destroy(&semaphoreContext->semaphore); + + M4OSA_free((M4OSA_MemAddr32)semaphoreContext); + + return M4NO_ERROR; +} + |