summaryrefslogtreecommitdiffstats
path: root/libvideoeditor/osal/src/M4OSA_Semaphore.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvideoeditor/osal/src/M4OSA_Semaphore.c')
-rwxr-xr-xlibvideoeditor/osal/src/M4OSA_Semaphore.c264
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;
+}
+