From c42be504c92d76d2e06d0fc8ebd05fc913376d2d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 16 Nov 2016 14:50:09 +0100 Subject: posix: Add self-contained pthread spinlock Turn pthread_spinlock_t into a self-contained object. On uni-processor configurations, interrupts are disabled in the lock/trylock operations and the previous interrupt status is restored in the corresponding unlock operations. On SMP configurations, a ticket lock is a acquired and released in addition. The self-contained pthread_spinlock_t object is defined by Newlib in . typedef struct { struct _Ticket_lock_Control _lock; __uint32_t _interrupt_state; } pthread_spinlock_t; This implementation is simple and efficient. However, this test case of the Linux Test Project would fail due to call of printf() and sleep() during spin lock ownership: https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/pthread_spin_lock/1-2.c There is only limited support for profiling on SMP configurations. Delete CORE spinlock implementation. Update #2674. --- cpukit/posix/include/rtems/posix/spinlockimpl.h | 81 ++++++++++++------------- 1 file changed, 38 insertions(+), 43 deletions(-) (limited to 'cpukit/posix/include/rtems/posix/spinlockimpl.h') diff --git a/cpukit/posix/include/rtems/posix/spinlockimpl.h b/cpukit/posix/include/rtems/posix/spinlockimpl.h index f1b5639bd1..36ef6677a0 100644 --- a/cpukit/posix/include/rtems/posix/spinlockimpl.h +++ b/cpukit/posix/include/rtems/posix/spinlockimpl.h @@ -11,6 +11,8 @@ * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * + * Copyright (c) 2016 embedded brains GmbH + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. @@ -19,62 +21,55 @@ #ifndef _RTEMS_POSIX_SPINLOCKIMPL_H #define _RTEMS_POSIX_SPINLOCKIMPL_H -#include -#include -#include - #include +#include + +#if defined(RTEMS_SMP) +#include +#include +#endif + #ifdef __cplusplus extern "C" { #endif -/** - * The following defines the information control block used to manage - * this class of objects. - */ +#if SIZEOF_PTHREAD_SPINLOCK_T > 4 +#define POSIX_SPINLOCKS_ARE_SELF_CONTAINED +#endif -extern Objects_Information _POSIX_Spinlock_Information; +typedef struct { +#if defined(RTEMS_SMP) + SMP_ticket_lock_Control Lock; +#else + unsigned int reserved[ 2 ]; +#endif + ISR_Level interrupt_state; +} POSIX_Spinlock_Control; -/** - * @brief Allocate a spinlock control block. - * - * This function allocates a spinlock control block from - * the inactive chain of free spinlock control blocks. - */ -RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Allocate( void ) -{ - return (POSIX_Spinlock_Control *) - _Objects_Allocate( &_POSIX_Spinlock_Information ); -} +#if !defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) +#if defined(RTEMS_SMP) +extern POSIX_Spinlock_Control _POSIX_Spinlock_Global; -/** - * @brief Free a spinlock control block. - * - * This routine frees a spinlock control block to the - * inactive chain of free spinlock control blocks. - */ -RTEMS_INLINE_ROUTINE void _POSIX_Spinlock_Free ( - POSIX_Spinlock_Control *the_spinlock -) -{ - _Objects_Free( &_POSIX_Spinlock_Information, &the_spinlock->Object ); -} +extern uint32_t _POSIX_Spinlock_Owner; +#endif + +extern int _POSIX_Spinlock_Nest_level; +#endif RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Get( - pthread_spinlock_t *spinlock, - ISR_lock_Context *lock_context + pthread_spinlock_t *lock ) { - if ( spinlock == NULL ) { - return NULL; - } - - return (POSIX_Spinlock_Control *) _Objects_Get( - *spinlock, - lock_context, - &_POSIX_Spinlock_Information - ); +#if defined(POSIX_SPINLOCKS_ARE_SELF_CONTAINED) + return (POSIX_Spinlock_Control *) lock; +#elif defined(RTEMS_SMP) + (void) lock; + return &_POSIX_Spinlock_Global; +#else + (void) lock; + return NULL; +#endif } #ifdef __cplusplus -- cgit v1.2.3