summaryrefslogtreecommitdiffstats
path: root/exynos4/hal/libump/os/linux/ump_osu_locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'exynos4/hal/libump/os/linux/ump_osu_locks.c')
-rw-r--r--exynos4/hal/libump/os/linux/ump_osu_locks.c537
1 files changed, 0 insertions, 537 deletions
diff --git a/exynos4/hal/libump/os/linux/ump_osu_locks.c b/exynos4/hal/libump/os/linux/ump_osu_locks.c
deleted file mode 100644
index 97ba858..0000000
--- a/exynos4/hal/libump/os/linux/ump_osu_locks.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
- *
- * 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.
- */
-
-#if ((!defined _XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 600))
-#undef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600
-#endif
-
-
-#define _POSIX_C_SOURCE 200112L
-
-#include <ump/ump_osu.h>
-#include <ump/ump_debug.h>
-
-#include <pthread.h>
-#include <time.h>
-#include <sys/time.h>
-#include <errno.h>
-
-/**
- * @file ump_osu_locks.c
- * File implements the user side of the OS interface
- */
-
-/** @opt Most of the time, we use the plain mutex type of osu_lock, and so
- * only require the flags and mutex members. This costs 2 extra DWORDS, but
- * most of the time we don't use those DWORDS.
- * Therefore, ANY_UNLOCK type osu_locks can be implemented as a second
- * structure containing the member _ump_osu_lock_t lock_t, plus the extra
- * state required. Then, we use &container->lock_t when passing out of the
- * OSU api, and CONTAINER_OF() when passing back in to recover the original
- * structure. */
-
-/** Private declaration of the OSU lock type */
-struct _ump_osu_lock_t_struct
-{
- /** At present, only two types of mutex, so we store this information as
- * the flags supplied at init time */
- _ump_osu_lock_flags_t flags;
-
- pthread_mutex_t mutex; /**< Used in both plain and ANY_UNLOCK osu_locks */
-
- /* Extra State for ANY_UNLOCK osu_locks. These are UNINITIALIZED when
- * flags does not contain _UMP_OSU_LOCKFLAG_ANYUNLOCK: */
- pthread_cond_t condition; /**< The condition object to use while blocking */
- ump_bool state; /**< The boolean which indicates the event's state */
-
- UMP_DEBUG_CODE(
- /** debug checking of locks */
- _ump_osu_lock_mode_t locked_as;
- ) /* UMP_DEBUG_CODE */
-
-};
-
-/* Provide two statically initialized locks */
-UMP_STATIC _ump_osu_lock_t _ump_osu_static_locks[] =
-{
- {
- _UMP_OSU_LOCKFLAG_STATIC,
- PTHREAD_MUTEX_INITIALIZER,
- PTHREAD_COND_INITIALIZER,
- UMP_FALSE,
- UMP_DEBUG_CODE( _UMP_OSU_LOCKMODE_UNDEF )
- },
- {
- _UMP_OSU_LOCKFLAG_STATIC,
- PTHREAD_MUTEX_INITIALIZER,
- PTHREAD_COND_INITIALIZER,
- UMP_FALSE,
- UMP_DEBUG_CODE( _UMP_OSU_LOCKMODE_UNDEF )
- },
- {
- _UMP_OSU_LOCKFLAG_STATIC,
- PTHREAD_MUTEX_INITIALIZER,
- PTHREAD_COND_INITIALIZER,
- UMP_FALSE,
- UMP_DEBUG_CODE( _UMP_OSU_LOCKMODE_UNDEF )
- },
- {
- _UMP_OSU_LOCKFLAG_STATIC,
- PTHREAD_MUTEX_INITIALIZER,
- PTHREAD_COND_INITIALIZER,
- UMP_FALSE,
- UMP_DEBUG_CODE( _UMP_OSU_LOCKMODE_UNDEF )
- },
-};
-
-/* Critical section for auto_init */
-UMP_STATIC pthread_mutex_t static_auto_init_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-_ump_osu_errcode_t _ump_osu_lock_auto_init( _ump_osu_lock_t **pplock, _ump_osu_lock_flags_t flags, u32 initial, u32 order )
-{
- int call_result;
- /* Validate parameters: */
- UMP_DEBUG_ASSERT_POINTER( pplock );
-
- /** @opt We don't lock the Critical Section or do anything if this is already non-null */
- if ( NULL != *pplock)
- {
- return _UMP_OSU_ERR_OK;
- }
-
- /* We MIGHT need to initialize it, lock the Critical Section and check again */
- call_result = pthread_mutex_lock(&static_auto_init_mutex);
- /* It would be a programming error for this to fail: */
- UMP_DEBUG_ASSERT( 0 == call_result,
- ("failed to lock critical section\n") );
-
- if ( NULL != *pplock )
- {
- /*
- We caught a race condition to initialize this osu_lock.
- The other thread won the race, so the osu_lock is now initialized.
- */
- call_result = pthread_mutex_unlock(&static_auto_init_mutex);
-
- UMP_DEBUG_ASSERT(0 == call_result,
- ("failed to unlock critical section\n"));
-
- return _UMP_OSU_ERR_OK;
- }
-
- /* We're the first thread in: initialize the osu_lock */
- *pplock = _ump_osu_lock_init( flags, initial, order );
-
- if ( NULL == *pplock )
- {
- /* osu_lock creation failed */
- call_result = pthread_mutex_unlock(&static_auto_init_mutex);
- UMP_DEBUG_ASSERT(0 == call_result,
- ("failed to unlock critical section\n"));
-
- return _UMP_OSU_ERR_FAULT;
- }
-
-
- /* osu_lock created OK */
- call_result = pthread_mutex_unlock(&static_auto_init_mutex);
-
- UMP_DEBUG_ASSERT(0 == call_result,
- ("failed to unlock critical section\n"));
-
- UMP_IGNORE( call_result );
-
- return _UMP_OSU_ERR_OK;
-}
-
-
-_ump_osu_lock_t *_ump_osu_lock_init( _ump_osu_lock_flags_t flags, u32 initial, u32 order )
-{
- _ump_osu_lock_t * lock;
- pthread_mutexattr_t mutex_attributes;
-
- /* Validate parameters: */
- /* Flags acceptable */
- UMP_DEBUG_ASSERT( 0 == ( flags & ~( _UMP_OSU_LOCKFLAG_ANYUNLOCK)),
- ("incorrect flags or trying to initialise a statically initialized lock, %.8X\n", flags) );
-
- /* Parameter initial SBZ - for future expansion */
- UMP_DEBUG_ASSERT( 0 == initial,
- ("initial must be zero\n") );
-
- if (0 != pthread_mutexattr_init(&mutex_attributes))
- {
- return NULL;
- }
-
-#if UMP_DEBUG_EXTENDED_MUTEX_LOCK_CHECKING
-#define UMP_PTHREADS_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK
-#else
-#define UMP_PTHREADS_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
-#endif
-
- if (0 != pthread_mutexattr_settype(&mutex_attributes, UMP_PTHREADS_MUTEX_TYPE))
- {
- /** Return NULL on failure */
- pthread_mutexattr_destroy(&mutex_attributes);
- return NULL;
-
- }
-
-#undef UMP_PTHREADS_MUTEX_TYPE
-
- /** @opt use containing structures for the ANY_UNLOCK type, to
- * save 2 DWORDS when not in use */
- lock = _ump_osu_malloc( sizeof(_ump_osu_lock_t) );
-
- if( NULL == lock )
- {
- /** Return NULL on failure */
- pthread_mutexattr_destroy(&mutex_attributes);
- return NULL;
- }
-
- if (0 != pthread_mutex_init( &lock->mutex, &mutex_attributes ))
- {
- pthread_mutexattr_destroy(&mutex_attributes);
- _ump_osu_free( lock );
- return NULL;
- }
-
- /* done with the mutexattr object */
- pthread_mutexattr_destroy(&mutex_attributes);
-
- /* ANY_UNLOCK type */
- if ( flags & _UMP_OSU_LOCKFLAG_ANYUNLOCK )
- {
- if (0 != pthread_cond_init( &lock->condition, NULL ))
- {
- /* cleanup */
- pthread_mutex_destroy( &lock->mutex );
- _ump_osu_free( lock );
- return NULL;
- }
- lock->state = UMP_FALSE; /* mark as unlocked by default */
- }
-
- lock->flags = flags;
-
- /** Debug lock checking */
- UMP_DEBUG_CODE( lock->locked_as = _UMP_OSU_LOCKMODE_UNDEF );
-
- return lock;
-}
-
-_ump_osu_errcode_t _ump_osu_lock_timed_wait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode, u64 timeout)
-{
- /* absolute time specifier */
- struct timespec ts;
- struct timeval tv;
-
- /* Parameter validation */
- UMP_DEBUG_ASSERT_POINTER( lock );
-
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_RW == mode,
- ("unrecognised mode, %.8X\n", mode) );
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKFLAG_ANYUNLOCK == lock->flags, ("Timed operations only implemented for ANYUNLOCK type locks"));
-
- /* calculate the realtime timeout value */
-
- if (0 != gettimeofday(&tv, NULL))
- {
- UMP_DEBUG_PRINT(1,("Could not get the current realtime value to calculate the absolute value for a timed mutex lock with a timeout"));
- return _UMP_OSU_ERR_FAULT;
- }
-
- tv.tv_usec += timeout;
-
-#define UMP_USECS_PER_SECOND 1000000ULL
-#define UMP_NANOSECS_PER_USEC 1000ULL
-
- /* did we overflow a second in the usec part? */
- while (tv.tv_usec >= UMP_USECS_PER_SECOND)
- {
- tv.tv_usec -= UMP_USECS_PER_SECOND;
- tv.tv_sec++;
- }
-
- /* copy to the correct struct */
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = (tv.tv_usec * UMP_NANOSECS_PER_USEC);
-
-#undef UMP_USECS_PER_SECOND
-#undef UMP_NANOSECS_PER_USEC
-
- /* lock the mutex protecting access to the state field */
- pthread_mutex_lock( &lock->mutex );
- /* loop while locked (state is UMP_TRUE) */
- /* pthread_cond_timedwait unlocks the mutex, wait, and locks the mutex once unblocked (either due to the event or the timeout) */
- while ( UMP_TRUE == lock->state )
- {
- int res;
- res = pthread_cond_timedwait( &lock->condition, &lock->mutex, &ts );
- if (0 == res) continue; /* test the state variable again (loop condition) */
- else if (ETIMEDOUT == res)
- {
- /* timeout, need to clean up and return the correct error code */
- pthread_mutex_unlock(&lock->mutex);
- return _UMP_OSU_ERR_TIMEOUT;
- }
- else
- {
- UMP_DEBUG_PRINT(1, ("Unexpected return from pthread_cond_timedwait 0x%08X\n", res));
-
- pthread_mutex_unlock(&lock->mutex);
- return _UMP_OSU_ERR_FAULT;
- }
-
- }
-
- /* DEBUG tracking of previously locked state - occurs while lock is obtained */
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as,
- ("This lock was already locked\n") );
- UMP_DEBUG_CODE( lock->locked_as = mode );
-
- /* the state is UMP_FALSE (unlocked), so we set it to UMP_TRUE to indicate that it's locked and can return knowing that we own the lock */
- lock->state = UMP_TRUE;
- /* final unlock of the mutex */
- pthread_mutex_unlock(&lock->mutex);
-
- return _UMP_OSU_ERR_OK;
-
-}
-
-_ump_osu_errcode_t _ump_osu_lock_wait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode)
-{
- /* Parameter validation */
- UMP_DEBUG_ASSERT_POINTER( lock );
-
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_RW == mode,
- ("unrecognised mode, %.8X\n", mode) );
-
- /** @note since only one flag can be set, we use a switch statement here.
- * Otherwise, MUST add an enum into the _ump_osu_lock_t to store the
- * implemented lock type */
- switch ( lock->flags )
- {
- case _UMP_OSU_LOCKFLAG_STATIC:
- case 0:
- /* Usual Mutex type */
- {
- int call_result;
- call_result = pthread_mutex_lock( &lock->mutex );
- UMP_DEBUG_ASSERT( 0 == call_result,
- ("pthread_mutex_lock call failed with error code %d\n", call_result));
- UMP_IGNORE( call_result );
- }
-
- /* DEBUG tracking of previously locked state - occurs while lock is obtained */
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as,
- ("This lock was already locked\n") );
- UMP_DEBUG_CODE( lock->locked_as = mode );
- break;
-
- case _UMP_OSU_LOCKFLAG_ANYUNLOCK:
- /** @note Use of bitflags in a case statement ONLY works because this
- * is the ONLY flag that is supported */
-
- /* lock the mutex protecting access to the state field */
- pthread_mutex_lock( &lock->mutex );
- /* loop while locked (state is UMP_TRUE) */
- /* pthread_cond_wait unlocks the mutex, wait, and locks the mutex once unblocked */
- while ( UMP_TRUE == lock->state ) pthread_cond_wait( &lock->condition, &lock->mutex );
-
- /* DEBUG tracking of previously locked state - occurs while lock is obtained */
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as,
- ("This lock was already locked\n") );
- UMP_DEBUG_CODE( lock->locked_as = mode );
-
- /* the state is UMP_FALSE (unlocked), so we set it to UMP_TRUE to indicate that it's locked and can return knowing that we own the lock */
- lock->state = UMP_TRUE;
- /* final unlock of the mutex */
- pthread_mutex_unlock(&lock->mutex);
- break;
-
- default:
- UMP_DEBUG_ERROR( ("lock has incorrect flags==%.8X\n", lock->flags) );
- break;
- }
-
- return _UMP_OSU_ERR_OK;
-}
-
-_ump_osu_errcode_t _ump_osu_lock_trywait( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode)
-{
- _ump_osu_errcode_t err = _UMP_OSU_ERR_FAULT;
- /* Parameter validation */
- UMP_DEBUG_ASSERT_POINTER( lock );
-
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_RW == mode,
- ("unrecognised mode, %.8X\n", mode) );
-
- /** @note since only one flag can be set, we use a switch statement here.
- * Otherwise, MUST add an enum into the _ump_osu_lock_t to store the
- * implemented lock type */
- switch ( lock->flags )
- {
- case _UMP_OSU_LOCKFLAG_STATIC:
- case 0:
- /* Usual Mutex type */
- {
- /* This is not subject to UMP_CHECK - overriding the result would cause a programming error */
- if ( 0 == pthread_mutex_trylock( &lock->mutex ) )
- {
- err = _UMP_OSU_ERR_OK;
-
- /* DEBUG tracking of previously locked state - occurs while lock is obtained */
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as
- || mode == lock->locked_as,
- ("tried as mode==%.8X, but was locked as %.8X\n", mode, lock->locked_as) );
- UMP_DEBUG_CODE( lock->locked_as = mode );
- }
- }
- break;
-
- case _UMP_OSU_LOCKFLAG_ANYUNLOCK:
- /** @note Use of bitflags in a case statement ONLY works because this
- * is the ONLY flag that is supported */
-
- /* lock the mutex protecting access to the state field */
- pthread_mutex_lock(&lock->mutex);
-
- if ( UMP_FALSE == lock->state)
- {
- /* unlocked, take the lock */
- lock->state = UMP_TRUE;
- err = _UMP_OSU_ERR_OK;
- }
-
- /* DEBUG tracking of previously locked state - occurs while lock is obtained */
- /* Can do this regardless of whether we obtained ANYUNLOCK: */
-
-
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as
- || mode == lock->locked_as,
- ("tried as mode==%.8X, but was locked as %.8X\n", mode, lock->locked_as) );
- /* If we were already locked, this does no harm, because of the above assert: */
- UMP_DEBUG_CODE( lock->locked_as = mode );
-
- pthread_mutex_unlock(&lock->mutex);
- break;
-
- default:
- UMP_DEBUG_ERROR( ("lock has incorrect flags==%.8X\n", lock->flags) );
- break;
- }
-
- return err;
-}
-
-
-void _ump_osu_lock_signal( _ump_osu_lock_t *lock, _ump_osu_lock_mode_t mode )
-{
- /* Parameter validation */
- UMP_DEBUG_ASSERT_POINTER( lock );
-
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_RW == mode,
- ("unrecognised mode, %.8X\n", mode) );
-
- /** @note since only one flag can be set, we use a switch statement here.
- * Otherwise, MUST add an enum into the _ump_osu_lock_t to store the
- * implemented lock type */
- switch ( lock->flags )
- {
- case _UMP_OSU_LOCKFLAG_STATIC:
- case 0:
- /* Usual Mutex type */
-
- /* DEBUG tracking of previously locked state - occurs while lock is obtained */
- UMP_DEBUG_ASSERT( mode == lock->locked_as,
- ("This lock was locked as==%.8X, but tried to unlock as mode==%.8X\n", lock->locked_as, mode));
- UMP_DEBUG_CODE( lock->locked_as = _UMP_OSU_LOCKMODE_UNDEF );
-
- {
- int call_result;
- call_result = pthread_mutex_unlock( &lock->mutex );
- UMP_DEBUG_ASSERT( 0 == call_result,
- ("pthread_mutex_lock call failed with error code %d\n", call_result));
- UMP_IGNORE( call_result );
- }
- break;
-
- case _UMP_OSU_LOCKFLAG_ANYUNLOCK:
- /** @note Use of bitflags in a case statement ONLY works because this
- * is the ONLY flag that is supported */
-
- pthread_mutex_lock(&lock->mutex);
- UMP_DEBUG_ASSERT( UMP_TRUE == lock->state, ("Unlocking a _ump_osu_lock_t %p which is not locked\n", lock));
-
- /* DEBUG tracking of previously locked state - occurs while lock is obtained */
- UMP_DEBUG_ASSERT( mode == lock->locked_as,
- ("This lock was locked as==%.8X, but tried to unlock as %.8X\n", lock->locked_as, mode ));
- UMP_DEBUG_CODE( lock->locked_as = _UMP_OSU_LOCKMODE_UNDEF );
-
- /* mark as unlocked */
- lock->state = UMP_FALSE;
-
- /* signal the condition, only wake a single thread */
- pthread_cond_signal(&lock->condition);
-
- pthread_mutex_unlock(&lock->mutex);
- break;
-
- default:
- UMP_DEBUG_ERROR( ("lock has incorrect flags==%.8X\n", lock->flags) );
- break;
- }
-}
-
-void _ump_osu_lock_term( _ump_osu_lock_t *lock )
-{
- int call_result;
- UMP_DEBUG_ASSERT_POINTER( lock );
-
- /** Debug lock checking: */
- /* Lock is signalled on terminate - not a guarantee, since we could be locked immediately beforehand */
- UMP_DEBUG_ASSERT( _UMP_OSU_LOCKMODE_UNDEF == lock->locked_as,
- ("cannot terminate held lock\n") );
-
- call_result = pthread_mutex_destroy( &lock->mutex );
- UMP_DEBUG_ASSERT( 0 == call_result,
- ("Incorrect mutex use detected: pthread_mutex_destroy call failed with error code %d\n", call_result) );
-
- /* Destroy extra state for ANY_UNLOCK type osu_locks */
- if ( lock->flags & _UMP_OSU_LOCKFLAG_ANYUNLOCK )
- {
- UMP_DEBUG_ASSERT( UMP_FALSE == lock->state, ("terminate called on locked object %p\n", lock));
- call_result = pthread_cond_destroy(&lock->condition);
- UMP_DEBUG_ASSERT( 0 == call_result,
- ("Incorrect condition-variable use detected: pthread_cond_destroy call failed with error code %d\n", call_result) );
- }
-
- UMP_IGNORE(call_result);
-
- _ump_osu_free( lock );
-}
-
-_ump_osu_lock_t *_ump_osu_lock_static( u32 nr )
-{
- UMP_DEBUG_ASSERT( nr < UMP_OSU_STATIC_LOCK_COUNT,
- ("provided static lock index (%d) out of bounds (0 < nr < %d)\n", nr, UMP_OSU_STATIC_LOCK_COUNT) );
- return &_ump_osu_static_locks[nr];
-}