diff options
Diffstat (limited to 'cpukit/include/rtems/posix')
28 files changed, 3388 insertions, 0 deletions
diff --git a/cpukit/include/rtems/posix/aio_misc.h b/cpukit/include/rtems/posix/aio_misc.h new file mode 100644 index 0000000000..aeccbad98f --- /dev/null +++ b/cpukit/include/rtems/posix/aio_misc.h @@ -0,0 +1,113 @@ +/** + * @file + * + * @brief POSIX Asynchronous Input and Output Private Support + * + * This defines private information for the AIO implementation. + */ + +/* + * Copyright 2010, Alin Rus <alin.codejunkie@gmail.com> + * + * 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. + */ + +#ifndef _AIO_MISC_H +#define _AIO_MISC_H + +#include <stdio.h> +#include <string.h> +#include <aio.h> +#include <pthread.h> +#include <rtems.h> +#include <rtems/chain.h> +#include <rtems/system.h> +#include <rtems/seterr.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Actual request being processed */ + typedef struct + { + rtems_chain_node next_prio; /* chain requests in order of priority */ + int policy; /* If _POSIX_PRIORITIZED_IO and + _POSIX_PRIORITY_SCHEDULING are defined */ + int priority; /* see above */ + pthread_t caller_thread; /* used for notification */ + struct aiocb *aiocbp; /* aio control block */ + } rtems_aio_request; + + typedef struct + { + rtems_chain_node next_fd; /* order fd chains in queue */ + rtems_chain_control perfd; /* chain of requests for this fd */ + int fildes; /* file descriptor to be processed */ + int new_fd; /* if this is a newly created chain */ + pthread_mutex_t mutex; + pthread_cond_t cond; + + } rtems_aio_request_chain; + + typedef struct + { + pthread_mutex_t mutex; + pthread_cond_t new_req; + pthread_attr_t attr; + + rtems_chain_control work_req; /* chains being worked by active threads */ + rtems_chain_control idle_req; /* fd chains waiting to be processed */ + unsigned int initialized; /* specific value if queue is initialized */ + int active_threads; /* the number of active threads */ + int idle_threads; /* number of idle threads */ + + } rtems_aio_queue; + +extern rtems_aio_queue aio_request_queue; + +#define AIO_QUEUE_INITIALIZED 0xB00B + +#ifndef AIO_MAX_THREADS +#define AIO_MAX_THREADS 5 +#endif + +#ifndef AIO_MAX_QUEUE_SIZE +#define AIO_MAX_QUEUE_SIZE 30 +#endif + +int rtems_aio_init (void); +int rtems_aio_enqueue (rtems_aio_request *req); +rtems_aio_request_chain *rtems_aio_search_fd +( + rtems_chain_control *chain, + int fildes, + int create +); +void rtems_aio_remove_fd (rtems_aio_request_chain *r_chain); +int rtems_aio_remove_req (rtems_chain_control *chain, + struct aiocb *aiocbp); + +#ifdef RTEMS_DEBUG +#include <assert.h> + +#define AIO_assert(_x) assert(_x) +#define AIO_printf(_x) printf(_x) +#else +#define AIO_assert(_x) +#define AIO_printf(_x) +#endif + +#define rtems_aio_set_errno_return_minus_one( _error, _aiocbp ) \ + do { (_aiocbp)->error_code = (_error); \ + (_aiocbp)->return_value = -1; \ + rtems_set_errno_and_return_minus_one (_error);} while(0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/include/rtems/posix/barrierimpl.h b/cpukit/include/rtems/posix/barrierimpl.h new file mode 100644 index 0000000000..a1794b82fd --- /dev/null +++ b/cpukit/include/rtems/posix/barrierimpl.h @@ -0,0 +1,99 @@ +/** + * @file + * + * @brief Inlined Routines from the POSIX Barrier Manager + * + * This file contains the static inlin implementation of the inlined + * routines from the POSIX Barrier Manager. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * Copyright (c) 2017 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. + */ + +#ifndef _RTEMS_POSIX_BARRIERIMPL_H +#define _RTEMS_POSIX_BARRIERIMPL_H + +#include <errno.h> +#include <pthread.h> + +#include <rtems/score/percpu.h> +#include <rtems/score/threadqimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define POSIX_BARRIER_MAGIC 0x1cf03773UL + +#define POSIX_BARRIER_TQ_OPERATIONS &_Thread_queue_Operations_FIFO + +typedef struct { + unsigned long flags; + Thread_queue_Syslock_queue Queue; + unsigned int count; + unsigned int waiting_threads; +} POSIX_Barrier_Control; + +static inline POSIX_Barrier_Control *_POSIX_Barrier_Get( + pthread_barrier_t *_barrier +) +{ + return (POSIX_Barrier_Control *) _barrier; +} + +static inline Thread_Control *_POSIX_Barrier_Queue_acquire( + POSIX_Barrier_Control *barrier, + Thread_queue_Context *queue_context +) +{ + ISR_Level level; + Thread_Control *executing; + + _Thread_queue_Context_initialize( queue_context ); + _Thread_queue_Context_ISR_disable( queue_context, level ); + _Thread_queue_Context_set_ISR_level( queue_context, level ); + executing = _Thread_Executing; + _Thread_queue_Queue_acquire_critical( + &barrier->Queue.Queue, + &executing->Potpourri_stats, + &queue_context->Lock_context.Lock_context + ); + + return executing; +} + +static inline void _POSIX_Barrier_Queue_release( + POSIX_Barrier_Control *barrier, + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Queue_release( + &barrier->Queue.Queue, + &queue_context->Lock_context.Lock_context + ); +} + +#define POSIX_BARRIER_VALIDATE_OBJECT( bar ) \ + do { \ + if ( \ + ( bar ) == NULL \ + || ( (uintptr_t) ( bar ) ^ POSIX_BARRIER_MAGIC ) != ( bar )->_flags \ + ) { \ + return EINVAL; \ + } \ + } while ( 0 ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/condimpl.h b/cpukit/include/rtems/posix/condimpl.h new file mode 100644 index 0000000000..66e09bf6d8 --- /dev/null +++ b/cpukit/include/rtems/posix/condimpl.h @@ -0,0 +1,184 @@ +/** + * @file + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX condition variables. + */ + +/* + * COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_CONDIMPL_H +#define _RTEMS_POSIX_CONDIMPL_H + +#include <errno.h> +#include <pthread.h> + +#include <rtems/score/percpu.h> +#include <rtems/score/threadqimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + unsigned long flags; + Thread_queue_Syslock_queue Queue; + pthread_mutex_t *mutex; +} POSIX_Condition_variables_Control; + +#define POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC 0x1UL + +#define POSIX_CONDITION_VARIABLES_FLAGS_MASK 0x1UL + +#define POSIX_CONDITION_VARIABLES_MAGIC 0x18dfb1feUL + +/** + * Constant to indicate condition variable does not currently have + * a mutex assigned to it. + */ +#define POSIX_CONDITION_VARIABLES_NO_MUTEX NULL + +#define POSIX_CONDITION_VARIABLES_TQ_OPERATIONS &_Thread_queue_Operations_FIFO + +#define POSIX_CONDITION_VARIABLE_OF_THREAD_QUEUE_QUEUE( queue ) \ + RTEMS_CONTAINER_OF( \ + queue, POSIX_Condition_variables_Control, Queue.Queue ) + +/** + * The default condition variable attributes structure. + */ +extern const pthread_condattr_t _POSIX_Condition_variables_Default_attributes; + +static inline POSIX_Condition_variables_Control *_POSIX_Condition_variables_Get( + pthread_cond_t *cond +) +{ + return (POSIX_Condition_variables_Control *) cond; +} + +RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Initialize( + POSIX_Condition_variables_Control *the_cond, + const pthread_condattr_t *the_attr +) +{ + unsigned long flags; + + _Thread_queue_Queue_initialize( &the_cond->Queue.Queue, NULL ); + the_cond->mutex = POSIX_CONDITION_VARIABLES_NO_MUTEX; + + flags = (uintptr_t) the_cond ^ POSIX_CONDITION_VARIABLES_MAGIC; + flags &= ~POSIX_CONDITION_VARIABLES_FLAGS_MASK; + + if ( the_attr->clock == CLOCK_MONOTONIC ) { + flags |= POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC; + } + + the_cond->flags = flags; +} + +RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Destroy( + POSIX_Condition_variables_Control *the_cond +) +{ + the_cond->flags = ~the_cond->flags; +} + +RTEMS_INLINE_ROUTINE clockid_t _POSIX_Condition_variables_Get_clock( + unsigned long flags +) +{ + if ( ( flags & POSIX_CONDITION_VARIABLES_CLOCK_MONOTONIC ) != 0 ) { + return CLOCK_MONOTONIC; + } + + return CLOCK_REALTIME; +} + +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Condition_variables_Acquire( + POSIX_Condition_variables_Control *the_cond, + Thread_queue_Context *queue_context +) +{ + ISR_Level level; + Thread_Control *executing; + + _Thread_queue_Context_ISR_disable( queue_context, level ); + _Thread_queue_Context_set_ISR_level( queue_context, level ); + executing = _Thread_Executing; + _Thread_queue_Queue_acquire_critical( + &the_cond->Queue.Queue, + &executing->Potpourri_stats, + &queue_context->Lock_context.Lock_context + ); + + return executing; +} + +RTEMS_INLINE_ROUTINE void _POSIX_Condition_variables_Release( + POSIX_Condition_variables_Control *the_cond, + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Queue_release( + &the_cond->Queue.Queue, + &queue_context->Lock_context.Lock_context + ); +} + +/** + * @brief Implements wake up version of the "signal" operation. + * + * A support routine which implements guts of the broadcast and single task + * wake up version of the "signal" operation. + */ +int _POSIX_Condition_variables_Signal_support( + pthread_cond_t *cond, + bool is_broadcast +); + +/** + * @brief POSIX condition variables wait support. + * + * A support routine which implements guts of the blocking, non-blocking, and + * timed wait version of condition variable wait routines. + */ +int _POSIX_Condition_variables_Wait_support( + pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime +); + +bool _POSIX_Condition_variables_Auto_initialization( + POSIX_Condition_variables_Control *the_cond +); + +#define POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags ) \ + do { \ + if ( ( the_cond ) == NULL ) { \ + return EINVAL; \ + } \ + flags = ( the_cond )->flags; \ + if ( \ + ( ( (uintptr_t) ( the_cond ) ^ POSIX_CONDITION_VARIABLES_MAGIC ) \ + & ~POSIX_CONDITION_VARIABLES_FLAGS_MASK ) \ + != ( flags & ~POSIX_CONDITION_VARIABLES_FLAGS_MASK ) \ + ) { \ + if ( !_POSIX_Condition_variables_Auto_initialization( the_cond ) ) { \ + return EINVAL; \ + } \ + } \ + } while ( 0 ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/config.h b/cpukit/include/rtems/posix/config.h new file mode 100644 index 0000000000..e90dc27011 --- /dev/null +++ b/cpukit/include/rtems/posix/config.h @@ -0,0 +1,120 @@ +/** + * @file + * + * @brief User Defined Configuration Parameters Specific For The POSIX API + * + * This include file contains the table of user defined configuration + * parameters specific for the POSIX API. + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_CONFIG_H +#define _RTEMS_POSIX_CONFIG_H + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicConfig Configuration + * + * @ingroup ClassicRTEMS + * + * This encapsulates functionality related to the application's configuration + * of the Classic API including the maximum number of each class of objects. + */ +/**@{*/ + +/** + * For now, we are only allowing the user to specify the entry point + * and stack size for POSIX initialization threads. + */ +typedef struct { + /** This is the entry point for a POSIX initialization thread. */ + void *(*thread_entry)(void *); + /** This is the stack size for a POSIX initialization thread. */ + int stack_size; +} posix_initialization_threads_table; + +/** + * The following records define the POSIX Configuration Table. + * The information contained in this table is required in all + * RTEMS systems which include POSIX threads support, whether + * single or multiprocessor. This table primarily defines the + * following: + * + * + required number of each object type + */ +typedef struct { + /** + * This field contains the maximum number of POSIX API + * threads which are configured for this application. + */ + uint32_t maximum_threads; + + /** + * This field contains the maximum number of POSIX API + * timers which are configured for this application. + */ + uint32_t maximum_timers; + + /** + * This field contains the maximum number of POSIX API + * queued signals which are configured for this application. + */ + uint32_t maximum_queued_signals; + + /** + * This field contains the maximum number of POSIX API + * message queues which are configured for this application. + */ + uint32_t maximum_message_queues; + + /** + * This field contains the maximum number of POSIX API + * semaphores which are configured for this application. + */ + uint32_t maximum_semaphores; + + /** + * Maximum configured number of POSIX Shared memory objects. + */ + uint32_t maximum_shms; + + /** + * This field contains the number of POSIX API Initialization + * threads listed in @a User_initialization_thread_table. + */ + uint32_t number_of_initialization_threads; + + /** + * This field contains the list of POSIX API Initialization threads. + */ + posix_initialization_threads_table *User_initialization_threads_table; +} posix_api_configuration_table; + +/** + * @brief POSIX API configuration table. + * + * This is the POSIX API Configuration Table expected to be generated + * by confdefs.h. + */ +extern posix_api_configuration_table Configuration_POSIX_API; + +/**@}*/ +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/key.h b/cpukit/include/rtems/posix/key.h new file mode 100644 index 0000000000..1f09916f06 --- /dev/null +++ b/cpukit/include/rtems/posix/key.h @@ -0,0 +1,95 @@ +/** + * @file + * + * @brief POSIX Key Private Support + * + * This include file contains all the private support information for + * POSIX key. + */ + +/* + * Copyright (c) 2012 Zhongwei Yao. + * 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. + */ + +#ifndef _RTEMS_POSIX_KEY_H +#define _RTEMS_POSIX_KEY_H + +#include <pthread.h> + +#include <rtems/score/chain.h> +#include <rtems/score/object.h> +#include <rtems/score/rbtree.h> +#include <rtems/score/thread.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup POSIX_KEY POSIX Key + * + * @ingroup POSIXAPI + * + */ +/**@{**/ + +/** + * @brief Represents POSIX key and value pair. + */ +typedef struct { + /** + * @brief The chain node for the key value pairs chain in POSIX_Keys_Control. + */ + Chain_Node Key_node; + + /** + * @brief The tree node for the lookup tree in Thread_Keys_information. + */ + RBTree_Node Lookup_node; + + /** + * @brief The POSIX key identifier used as the tree key. + */ + pthread_key_t key; + + /** + * @brief The corresponding thread. + */ + Thread_Control *thread; + + /** + * @brief The thread specific POSIX key value. + */ + void *value; +} POSIX_Keys_Key_value_pair; + +/** + * @brief The data structure used to manage a POSIX key. + */ +typedef struct { + /** This field is the Object control structure. */ + Objects_Control Object; + /** This field is the data destructor. */ + void (*destructor) (void *); + + /** + * @brief Key value pairs of this key. + */ + Chain_Control Key_value_pairs; + } POSIX_Keys_Control; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/keyimpl.h b/cpukit/include/rtems/posix/keyimpl.h new file mode 100644 index 0000000000..1148123638 --- /dev/null +++ b/cpukit/include/rtems/posix/keyimpl.h @@ -0,0 +1,177 @@ +/** + * @file + * + * @brief Private Inlined Routines for POSIX Key's + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX key's. + */ + +/* + * COPYRIGHT (c) 1989-1999. + * 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. + */ + +#include <rtems/posix/key.h> +#include <rtems/score/chainimpl.h> +#include <rtems/score/freechain.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/percpu.h> + +#ifndef _RTEMS_POSIX_KEYIMPL_H +#define _RTEMS_POSIX_KEYIMPL_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup POSIX_KEY + * + * @{ + */ + +/** + * @brief The information control block used to manage this class of objects. + */ +extern Objects_Information _POSIX_Keys_Information; + +/** + * @brief This freechain is used as a memory pool for POSIX_Keys_Key_value_pair. + */ +extern Freechain_Control _POSIX_Keys_Keypool; + +#define POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node ) \ + RTEMS_CONTAINER_OF( node, POSIX_Keys_Key_value_pair, Lookup_node ) + +/** + * @brief Allocate a keys control block. + * + * This function allocates a keys control block from + * the inactive chain of free keys control blocks. + */ + +RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Allocate( void ) +{ + return (POSIX_Keys_Control *) _Objects_Allocate( &_POSIX_Keys_Information ); +} + +/** + * @brief Free a keys control block. + * + * This routine frees a keys control block to the + * inactive chain of free keys control blocks. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Keys_Free( + POSIX_Keys_Control *the_key +) +{ + _Objects_Free( &_POSIX_Keys_Information, &the_key->Object ); +} + +RTEMS_INLINE_ROUTINE POSIX_Keys_Control *_POSIX_Keys_Get( pthread_key_t key ) +{ + return (POSIX_Keys_Control *) + _Objects_Get_no_protection( (Objects_Id) key, &_POSIX_Keys_Information ); +} + +RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_acquire( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_ISR_disable_and_acquire( &the_thread->Keys.Lock, lock_context ); +} + +RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_release( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Release_and_ISR_enable( &the_thread->Keys.Lock, lock_context ); +} + +POSIX_Keys_Key_value_pair * _POSIX_Keys_Key_value_allocate( void ); + +RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_free( + POSIX_Keys_Key_value_pair *key_value_pair +) +{ + _Chain_Extract_unprotected( &key_value_pair->Key_node ); + _Freechain_Put( &_POSIX_Keys_Keypool, key_value_pair ); +} + +RTEMS_INLINE_ROUTINE bool _POSIX_Keys_Key_value_equal( + const void *left, + const RBTree_Node *right +) +{ + const pthread_key_t *the_left; + const POSIX_Keys_Key_value_pair *the_right; + + the_left = left; + the_right = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( right ); + + return *the_left == the_right->key; +} + +RTEMS_INLINE_ROUTINE bool _POSIX_Keys_Key_value_less( + const void *left, + const RBTree_Node *right +) +{ + const pthread_key_t *the_left; + const POSIX_Keys_Key_value_pair *the_right; + + the_left = left; + the_right = POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( right ); + + return *the_left < the_right->key; +} + +RTEMS_INLINE_ROUTINE void *_POSIX_Keys_Key_value_map( RBTree_Node *node ) +{ + return POSIX_KEYS_RBTREE_NODE_TO_KEY_VALUE_PAIR( node ); +} + +RTEMS_INLINE_ROUTINE POSIX_Keys_Key_value_pair *_POSIX_Keys_Key_value_find( + pthread_key_t key, + const Thread_Control *the_thread +) +{ + return _RBTree_Find_inline( + &the_thread->Keys.Key_value_pairs, + &key, + _POSIX_Keys_Key_value_equal, + _POSIX_Keys_Key_value_less, + _POSIX_Keys_Key_value_map + ); +} + +RTEMS_INLINE_ROUTINE void _POSIX_Keys_Key_value_insert( + pthread_key_t key, + POSIX_Keys_Key_value_pair *key_value_pair, + Thread_Control *the_thread +) +{ + _RBTree_Insert_inline( + &the_thread->Keys.Key_value_pairs, + &key_value_pair->Lookup_node, + &key, + _POSIX_Keys_Key_value_less + ); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/mmanimpl.h b/cpukit/include/rtems/posix/mmanimpl.h new file mode 100644 index 0000000000..e1cc672331 --- /dev/null +++ b/cpukit/include/rtems/posix/mmanimpl.h @@ -0,0 +1,56 @@ +/** + * @file + * + * @brief Internal Support for POSIX 1003.1b 6.3.1 - map pages of memory + * + */ + +/* + * Copyright (c) 2012 Chris Johns + * + * 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. + */ + +#ifndef _RTEMS_POSIX_MMANIMPL_H +#define _RTEMS_POSIX_MMANIMPL_H + +#include <rtems/libio_.h> +#include <rtems/chain.h> /* FIXME: use score chains for proper layering? */ +#include <rtems/posix/shm.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* FIXME: add Doxygen */ + +/** + * Every mmap'ed region has a mapping. + */ +typedef struct mmap_mappings_s { + rtems_chain_node node; /**< The mapping chain's node */ + void* addr; /**< The address of the mapped memory */ + size_t len; /**< The length of memory mapped */ + int flags; /**< The mapping flags */ + POSIX_Shm_Control *shm; /**< The shared memory object or NULL */ +} mmap_mapping; + +extern rtems_chain_control mmap_mappings; + +static inline void mmap_mappings_lock_obtain( void ) +{ + rtems_libio_lock(); +} + +static inline void mmap_mappings_lock_release( void ) +{ + rtems_libio_unlock(); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/include/rtems/posix/mqueue.h b/cpukit/include/rtems/posix/mqueue.h new file mode 100644 index 0000000000..cdf94514af --- /dev/null +++ b/cpukit/include/rtems/posix/mqueue.h @@ -0,0 +1,71 @@ +/** + * @file + * + * @brief POSIX Message Queues Private Private Support + * + * This include file contains all the private support information for + * POSIX Message Queues. + * + * The structure of the routines is identical to that of POSIX + * Message_queues to leave the option of having unnamed message + * queues at a future date. They are currently not part of the + * POSIX standard but unnamed message_queues are. This is also + * the reason for the apparently unnecessary tracking of + * the process_shared attribute. [In addition to the fact that + * it would be trivial to add pshared to the mq_attr structure + * and have process private message queues.] + * + * This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open + * time. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_MQUEUE_H +#define _RTEMS_POSIX_MQUEUE_H + +#include <signal.h> +#include <mqueue.h> /* struct mq_attr */ +#include <rtems/score/coremsg.h> +#include <rtems/score/object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup POSIX_MQUEUE_P Message Queues Private Support + * + * @ingroup POSIXAPI + * + */ +/**@{**/ + +/* + * Data Structure used to manage a POSIX message queue + */ + +typedef struct { + Objects_Control Object; + CORE_message_queue_Control Message_queue; + bool linked; + uint32_t open_count; + struct sigevent notification; + int oflag; +} POSIX_Message_queue_Control; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/mqueueimpl.h b/cpukit/include/rtems/posix/mqueueimpl.h new file mode 100644 index 0000000000..6813a3ef88 --- /dev/null +++ b/cpukit/include/rtems/posix/mqueueimpl.h @@ -0,0 +1,183 @@ +/** + * @file + * + * @brief Private Inlined Routines for POSIX Message Queue + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX Message Queue. + */ + +/* + * COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_MQUEUE_INL +#define _RTEMS_POSIX_MQUEUE_INL + +#include <rtems/posix/mqueue.h> +#include <rtems/posix/posixapi.h> +#include <rtems/score/coremsgimpl.h> +#include <rtems/score/threadqimpl.h> + +#include <rtems/seterr.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This defines the information control block used to manage + * this class of objects. + */ +extern Objects_Information _POSIX_Message_queue_Information; + +/** + * @brief Delete a POSIX Message Queue + * + * This routine supports the mq_unlink and mq_close routines by + * doing most of the work involved with removing a message queue. + */ +void _POSIX_Message_queue_Delete( + POSIX_Message_queue_Control *the_mq, + Thread_queue_Context *queue_context +); + +/*@ + * @brief POSIX Message Queue Receive Support + * + * This routine supports the various flavors of receiving a message. + * + * @note The structure of the routines is identical to that of POSIX + * Message_queues to leave the option of having unnamed message + * queues at a future date. They are currently not part of the + * POSIX standard but unnamed message_queues are. This is also + * the reason for the apparently unnecessary tracking of + * the process_shared attribute. [In addition to the fact that + * it would be trivial to add pshared to the mq_attr structure + * and have process private message queues.] + * + * @note This code ignores the O_RDONLY/O_WRONLY/O_RDWR flag at open time. + */ +ssize_t _POSIX_Message_queue_Receive_support( + mqd_t mqdes, + char *msg_ptr, + size_t msg_len, + unsigned int *msg_prio, + const struct timespec *abstime, + Thread_queue_Enqueue_callout enqueue_callout +); + +/** + * @brief POSIX Message Queue Send Support + * + * This routine posts a message to a specified message queue. + */ +int _POSIX_Message_queue_Send_support( + mqd_t mqdes, + const char *msg_ptr, + size_t msg_len, + unsigned int msg_prio, + const struct timespec *abstime, + Thread_queue_Enqueue_callout enqueue_callout +); + +RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control * + _POSIX_Message_queue_Allocate_unprotected( void ) +{ + return (POSIX_Message_queue_Control *) + _Objects_Allocate_unprotected( &_POSIX_Message_queue_Information ); +} + +/** + * @brief POSIX Message Queue Free + * + * This routine frees a message queue control block to the + * inactive chain of free message queue control blocks. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Free( + POSIX_Message_queue_Control *the_mq +) +{ + _Objects_Free( &_POSIX_Message_queue_Information, &the_mq->Object ); +} + + +RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control *_POSIX_Message_queue_Get( + Objects_Id id, + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Context_initialize( queue_context ); + return (POSIX_Message_queue_Control *) _Objects_Get( + id, + &queue_context->Lock_context.Lock_context, + &_POSIX_Message_queue_Information + ); +} + +/* + * @brief POSIX Message Queue Convert Message Priority to Score + * + * This method converts a POSIX message priority to the priorities used + * by the Score. + */ +RTEMS_INLINE_ROUTINE CORE_message_queue_Submit_types + _POSIX_Message_queue_Priority_to_core( + unsigned int priority +) +{ + return (CORE_message_queue_Submit_types) priority * -1; +} + + +/* + * @brief POSIX Message Queue Convert Message Priority from Score + * + * This method converts a POSIX message priority from the priorities used + * by the Score. + */ +RTEMS_INLINE_ROUTINE unsigned int _POSIX_Message_queue_Priority_from_core( + CORE_message_queue_Submit_types priority +) +{ + /* absolute value without a library dependency */ + return (unsigned int) ((priority >= 0) ? priority : -priority); +} + +/** + * @brief POSIX Message Queue Remove from Namespace + */ +RTEMS_INLINE_ROUTINE void _POSIX_Message_queue_Namespace_remove ( + POSIX_Message_queue_Control *the_mq +) +{ + _Objects_Namespace_remove( + &_POSIX_Message_queue_Information, &the_mq->Object ); +} + +RTEMS_INLINE_ROUTINE POSIX_Message_queue_Control * +_POSIX_Message_queue_Get_by_name( + const char *name, + size_t *name_length_p, + Objects_Get_by_name_error *error +) +{ + return (POSIX_Message_queue_Control *) _Objects_Get_by_name( + &_POSIX_Message_queue_Information, + name, + name_length_p, + error + ); +} + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/muteximpl.h b/cpukit/include/rtems/posix/muteximpl.h new file mode 100644 index 0000000000..435b43634d --- /dev/null +++ b/cpukit/include/rtems/posix/muteximpl.h @@ -0,0 +1,487 @@ +/** + * @file + * + * @brief Private Inlined Routines for POSIX Mutex's. + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX mutex's. + */ + +/* COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_MUTEXIMPL_H +#define _RTEMS_POSIX_MUTEXIMPL_H + +#include <errno.h> +#include <pthread.h> + +#include <rtems/score/percpu.h> +#include <rtems/score/muteximpl.h> +#include <rtems/score/threadimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + unsigned long flags; + Mutex_recursive_Control Recursive; + Priority_Node Priority_ceiling; + const Scheduler_Control *scheduler; +} POSIX_Mutex_Control; + +#define POSIX_MUTEX_PROTOCOL_MASK 0x3UL + +#define POSIX_MUTEX_RECURSIVE 0x4UL + +#define POSIX_MUTEX_FLAGS_MASK 0x7UL + +#define POSIX_MUTEX_MAGIC 0x961c13b8UL + +#define POSIX_MUTEX_NO_PROTOCOL_TQ_OPERATIONS &_Thread_queue_Operations_FIFO + +#define POSIX_MUTEX_PRIORITY_INHERIT_TQ_OPERATIONS \ + &_Thread_queue_Operations_priority_inherit + +#define POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS \ + &_Thread_queue_Operations_priority + +/** + * @brief Supported POSIX mutex protocols. + * + * Must be in synchronization with POSIX_Mutex_Control::protocol. + */ +typedef enum { + POSIX_MUTEX_NO_PROTOCOL, + POSIX_MUTEX_PRIORITY_INHERIT, + POSIX_MUTEX_PRIORITY_CEILING +} POSIX_Mutex_Protocol; + +/** + * The default mutex attributes structure. + */ +extern const pthread_mutexattr_t _POSIX_Mutex_Default_attributes; + +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Mutex_Acquire( + POSIX_Mutex_Control *the_mutex, + Thread_queue_Context *queue_context +) +{ + ISR_Level level; + Thread_Control *executing; + + _Thread_queue_Context_initialize( queue_context ); + _Thread_queue_Context_ISR_disable( queue_context, level ); + _Thread_queue_Context_set_ISR_level( queue_context, level ); + executing = _Thread_Executing; + _Thread_queue_Queue_acquire_critical( + &the_mutex->Recursive.Mutex.Queue.Queue, + &executing->Potpourri_stats, + &queue_context->Lock_context.Lock_context + ); + + return executing; +} + +RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Release( + POSIX_Mutex_Control *the_mutex, + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Queue_release( + &the_mutex->Recursive.Mutex.Queue.Queue, + &queue_context->Lock_context.Lock_context + ); +} + +RTEMS_INLINE_ROUTINE POSIX_Mutex_Protocol _POSIX_Mutex_Get_protocol( + unsigned long flags +) +{ + return flags & POSIX_MUTEX_PROTOCOL_MASK; +} + +RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_recursive( + unsigned long flags +) +{ + return ( flags & POSIX_MUTEX_RECURSIVE ) != 0; +} + +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Mutex_Get_owner( + const POSIX_Mutex_Control *the_mutex +) +{ + return the_mutex->Recursive.Mutex.Queue.Queue.owner; +} + +RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_locked( + const POSIX_Mutex_Control *the_mutex +) +{ + return _POSIX_Mutex_Get_owner( the_mutex ) != NULL; +} + +Status_Control _POSIX_Mutex_Seize_slow( + POSIX_Mutex_Control *the_mutex, + const Thread_queue_Operations *operations, + Thread_Control *executing, + const struct timespec *abstime, + Thread_queue_Context *queue_context +); + +RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Set_owner( + POSIX_Mutex_Control *the_mutex, + Thread_Control *owner +) +{ + the_mutex->Recursive.Mutex.Queue.Queue.owner = owner; +} + +RTEMS_INLINE_ROUTINE bool _POSIX_Mutex_Is_owner( + const POSIX_Mutex_Control *the_mutex, + const Thread_Control *the_thread +) +{ + return _POSIX_Mutex_Get_owner( the_mutex ) == the_thread; +} + +static Status_Control _POSIX_Mutex_Lock_nested( + POSIX_Mutex_Control *the_mutex, + unsigned long flags +) +{ + + if ( _POSIX_Mutex_Is_recursive( flags ) ) { + ++the_mutex->Recursive.nest_level; + return STATUS_SUCCESSFUL; + } else { + return STATUS_NESTING_NOT_ALLOWED; + } +} + +RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Seize( + POSIX_Mutex_Control *the_mutex, + unsigned long flags, + const Thread_queue_Operations *operations, + Thread_Control *executing, + const struct timespec *abstime, + Thread_queue_Context *queue_context +) +{ + Thread_Control *owner; + + owner = _POSIX_Mutex_Get_owner( the_mutex ); + + if ( owner == NULL ) { + _POSIX_Mutex_Set_owner( the_mutex, executing ); + _Thread_Resource_count_increment( executing ); + _POSIX_Mutex_Release( the_mutex, queue_context ); + return STATUS_SUCCESSFUL; + } + + if ( owner == executing ) { + Status_Control status; + + status = _POSIX_Mutex_Lock_nested( the_mutex, flags ); + _POSIX_Mutex_Release( the_mutex, queue_context ); + return status; + } + + return _POSIX_Mutex_Seize_slow( + the_mutex, + operations, + executing, + abstime, + queue_context + ); +} + +RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Surrender( + POSIX_Mutex_Control *the_mutex, + const Thread_queue_Operations *operations, + Thread_Control *executing, + Thread_queue_Context *queue_context +) +{ + unsigned int nest_level; + Thread_queue_Heads *heads; + + if ( !_POSIX_Mutex_Is_owner( the_mutex, executing ) ) { + _POSIX_Mutex_Release( the_mutex, queue_context ); + return STATUS_NOT_OWNER; + } + + nest_level = the_mutex->Recursive.nest_level; + + if ( nest_level > 0 ) { + the_mutex->Recursive.nest_level = nest_level - 1; + _POSIX_Mutex_Release( the_mutex, queue_context ); + return STATUS_SUCCESSFUL; + } + + _Thread_Resource_count_decrement( executing ); + _POSIX_Mutex_Set_owner( the_mutex, NULL ); + + heads = the_mutex->Recursive.Mutex.Queue.Queue.heads; + + if ( heads == NULL ) { + _POSIX_Mutex_Release( the_mutex, queue_context ); + return STATUS_SUCCESSFUL; + } + + _Thread_queue_Surrender( + &the_mutex->Recursive.Mutex.Queue.Queue, + heads, + executing, + queue_context, + operations + ); + return STATUS_SUCCESSFUL; +} + +RTEMS_INLINE_ROUTINE const Scheduler_Control *_POSIX_Mutex_Get_scheduler( + const POSIX_Mutex_Control *the_mutex +) +{ +#if defined(RTEMS_SMP) + return the_mutex->scheduler; +#else + return &_Scheduler_Table[ 0 ]; +#endif +} + +RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Set_priority( + POSIX_Mutex_Control *the_mutex, + Priority_Control priority_ceiling, + Thread_queue_Context *queue_context +) +{ + Thread_Control *owner; + + owner = _POSIX_Mutex_Get_owner( the_mutex ); + + if ( owner != NULL ) { + _Thread_Wait_acquire( owner, queue_context ); + _Thread_Priority_change( + owner, + &the_mutex->Priority_ceiling, + priority_ceiling, + false, + queue_context + ); + _Thread_Wait_release( owner, queue_context ); + } else { + the_mutex->Priority_ceiling.priority = priority_ceiling; + } +} + +RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Mutex_Get_priority( + const POSIX_Mutex_Control *the_mutex +) +{ + return the_mutex->Priority_ceiling.priority; +} + +RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_set_owner( + POSIX_Mutex_Control *the_mutex, + Thread_Control *owner, + Thread_queue_Context *queue_context +) +{ + ISR_lock_Context lock_context; + Scheduler_Node *scheduler_node; + Per_CPU_Control *cpu_self; + + _Thread_Wait_acquire_default_critical( owner, &lock_context ); + + scheduler_node = _Thread_Scheduler_get_home_node( owner ); + + if ( + _Priority_Get_priority( &scheduler_node->Wait.Priority ) + < the_mutex->Priority_ceiling.priority + ) { + _Thread_Wait_release_default_critical( owner, &lock_context ); + _POSIX_Mutex_Release( the_mutex, queue_context ); + return STATUS_MUTEX_CEILING_VIOLATED; + } + + _POSIX_Mutex_Set_owner( the_mutex, owner ); + _Thread_Resource_count_increment( owner ); + _Thread_Priority_add( + owner, + &the_mutex->Priority_ceiling, + queue_context + ); + _Thread_Wait_release_default_critical( owner, &lock_context ); + + cpu_self = _Thread_queue_Dispatch_disable( queue_context ); + _POSIX_Mutex_Release( the_mutex, queue_context ); + _Thread_Priority_update( queue_context ); + _Thread_Dispatch_enable( cpu_self ); + return STATUS_SUCCESSFUL; +} + +RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_seize( + POSIX_Mutex_Control *the_mutex, + unsigned long flags, + Thread_Control *executing, + const struct timespec *abstime, + Thread_queue_Context *queue_context +) +{ + Thread_Control *owner; + + owner = _POSIX_Mutex_Get_owner( the_mutex ); + + if ( owner == NULL ) { +#if defined(RTEMS_SMP) + if ( + _Thread_Scheduler_get_home( executing ) + != _POSIX_Mutex_Get_scheduler( the_mutex ) + ) { + _POSIX_Mutex_Release( the_mutex, queue_context ); + return STATUS_NOT_DEFINED; + } +#endif + + _Thread_queue_Context_clear_priority_updates( queue_context ); + return _POSIX_Mutex_Ceiling_set_owner( + the_mutex, + executing, + queue_context + ); + } + + if ( owner == executing ) { + Status_Control status; + + status = _POSIX_Mutex_Lock_nested( the_mutex, flags ); + _POSIX_Mutex_Release( the_mutex, queue_context ); + return status; + } + + return _POSIX_Mutex_Seize_slow( + the_mutex, + POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS, + executing, + abstime, + queue_context + ); +} + +RTEMS_INLINE_ROUTINE Status_Control _POSIX_Mutex_Ceiling_surrender( + POSIX_Mutex_Control *the_mutex, + Thread_Control *executing, + Thread_queue_Context *queue_context +) +{ + unsigned int nest_level; + ISR_lock_Context lock_context; + Per_CPU_Control *cpu_self; + Thread_queue_Heads *heads; + + if ( !_POSIX_Mutex_Is_owner( the_mutex, executing ) ) { + _POSIX_Mutex_Release( the_mutex, queue_context ); + return STATUS_NOT_OWNER; + } + + nest_level = the_mutex->Recursive.nest_level; + + if ( nest_level > 0 ) { + the_mutex->Recursive.nest_level = nest_level - 1; + _POSIX_Mutex_Release( the_mutex, queue_context ); + return STATUS_SUCCESSFUL; + } + + _Thread_Resource_count_decrement( executing ); + + _Thread_queue_Context_clear_priority_updates( queue_context ); + _Thread_Wait_acquire_default_critical( executing, &lock_context ); + _Thread_Priority_remove( + executing, + &the_mutex->Priority_ceiling, + queue_context + ); + _Thread_Wait_release_default_critical( executing, &lock_context ); + + cpu_self = _Thread_queue_Dispatch_disable( queue_context ); + + heads = the_mutex->Recursive.Mutex.Queue.Queue.heads; + + if ( heads != NULL ) { + const Thread_queue_Operations *operations; + Thread_Control *new_owner; + + operations = POSIX_MUTEX_PRIORITY_CEILING_TQ_OPERATIONS; + new_owner = ( *operations->first )( heads ); + _POSIX_Mutex_Set_owner( the_mutex, new_owner ); + _Thread_Resource_count_increment( new_owner ); + _Thread_Priority_add( + new_owner, + &the_mutex->Priority_ceiling, + queue_context + ); + _Thread_queue_Extract_critical( + &the_mutex->Recursive.Mutex.Queue.Queue, + operations, + new_owner, + queue_context + ); + } else { + _POSIX_Mutex_Set_owner( the_mutex, NULL ); + _POSIX_Mutex_Release( the_mutex, queue_context ); + } + + _Thread_Priority_update( queue_context ); + _Thread_Dispatch_enable( cpu_self ); + return STATUS_SUCCESSFUL; +} + +#define POSIX_MUTEX_ABSTIME_TRY_LOCK ((uintptr_t) 1) + +int _POSIX_Mutex_Lock_support( + pthread_mutex_t *mutex, + const struct timespec *abstime, + Thread_queue_Enqueue_callout enqueue_callout +); + +static inline POSIX_Mutex_Control *_POSIX_Mutex_Get( + pthread_mutex_t *mutex +) +{ + return (POSIX_Mutex_Control *) mutex; +} + +bool _POSIX_Mutex_Auto_initialization( POSIX_Mutex_Control *the_mutex ); + +#define POSIX_MUTEX_VALIDATE_OBJECT( the_mutex, flags ) \ + do { \ + if ( ( the_mutex ) == NULL ) { \ + return EINVAL; \ + } \ + flags = ( the_mutex )->flags; \ + if ( \ + ( ( (uintptr_t) ( the_mutex ) ^ POSIX_MUTEX_MAGIC ) \ + & ~POSIX_MUTEX_FLAGS_MASK ) \ + != ( flags & ~POSIX_MUTEX_FLAGS_MASK ) \ + ) { \ + if ( !_POSIX_Mutex_Auto_initialization( the_mutex ) ) { \ + return EINVAL; \ + } \ + } \ + } while ( 0 ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/cpukit/include/rtems/posix/posixapi.h b/cpukit/include/rtems/posix/posixapi.h new file mode 100644 index 0000000000..29394ab94e --- /dev/null +++ b/cpukit/include/rtems/posix/posixapi.h @@ -0,0 +1,146 @@ +/** + * @file + * + * @brief POSIX API Implementation + * + * This include file defines the top level interface to the POSIX API + * implementation in RTEMS. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_POSIXAPI_H +#define _RTEMS_POSIX_POSIXAPI_H + +#include <rtems/config.h> +#include <rtems/score/assert.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/onceimpl.h> +#include <rtems/score/threadimpl.h> +#include <rtems/seterr.h> + +#include <pthread.h> + +/** + * @defgroup POSIXAPI RTEMS POSIX API + * + * RTEMS POSIX API definitions and modules. + * + */ +/**@{**/ + +/** + * @brief POSIX API Fatal domains. + */ +typedef enum { + POSIX_FD_PTHREAD, /**< A pthread thread error. */ + POSIX_FD_PTHREAD_ONCE /**< A pthread once error. */ +} POSIX_Fatal_domain; + +/** + * @brief POSIX API Fatal error. + * + * A common method of rasing a POSIX API fatal error. + * + * @param[in] domain The POSIX error domain. + * @param[in] eno The error number as defined in errno.h. + */ +void _POSIX_Fatal_error( POSIX_Fatal_domain domain, int eno ); + +extern const int _POSIX_Get_by_name_error_table[ 3 ]; + +RTEMS_INLINE_ROUTINE int _POSIX_Get_by_name_error( + Objects_Get_by_name_error error +) +{ + _Assert( (size_t) error < RTEMS_ARRAY_SIZE( _POSIX_Get_by_name_error_table ) ); + return _POSIX_Get_by_name_error_table[ error ]; +} + +RTEMS_INLINE_ROUTINE int _POSIX_Get_error( Status_Control status ) +{ + return STATUS_GET_POSIX( status ); +} + +RTEMS_INLINE_ROUTINE int _POSIX_Get_error_after_wait( + const Thread_Control *executing +) +{ + return _POSIX_Get_error( _Thread_Wait_get_status( executing ) ); +} + +RTEMS_INLINE_ROUTINE int _POSIX_Zero_or_minus_one_plus_errno( + Status_Control status +) +{ + if ( status == STATUS_SUCCESSFUL ) { + return 0; + } + + rtems_set_errno_and_return_minus_one( _POSIX_Get_error( status ) ); +} + +/** + * @brief Macro to generate a function body to get a POSIX object by + * identifier. + * + * Generates a function body to get the object for the specified identifier. + * Performs automatic initialization if requested and necessary. This is an + * ugly macro, since C lacks support for templates. + */ +#define _POSIX_Get_object_body( \ + type, \ + id, \ + queue_context, \ + info, \ + initializer, \ + init \ +) \ + Objects_Control *the_object; \ + if ( id == NULL ) { \ + return NULL; \ + } \ + _Thread_queue_Context_initialize( queue_context ); \ + the_object = _Objects_Get( \ + (Objects_Id) *id, \ + &queue_context->Lock_context.Lock_context, \ + info \ + ); \ + if ( the_object == NULL ) { \ + _Once_Lock(); \ + if ( *id == initializer ) { \ + init( id, NULL ); \ + } \ + _Once_Unlock(); \ + the_object = _Objects_Get( \ + (Objects_Id) *id, \ + &queue_context->Lock_context.Lock_context, \ + info \ + ); \ + } \ + return (type *) the_object + +/* + * See also The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008, + * 2016 Edition, subsection 2.9.9, Synchronization Object Copies and + * Alternative Mappings. + * + * http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_09 + */ +RTEMS_INLINE_ROUTINE bool _POSIX_Is_valid_pshared( int pshared ) +{ + return pshared == PTHREAD_PROCESS_PRIVATE || + pshared == PTHREAD_PROCESS_SHARED; +} + +/** @} */ + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/priorityimpl.h b/cpukit/include/rtems/posix/priorityimpl.h new file mode 100644 index 0000000000..eb2e3e059f --- /dev/null +++ b/cpukit/include/rtems/posix/priorityimpl.h @@ -0,0 +1,109 @@ +/** + * @file + * + * @brief POSIX Priority Support + * + * This include file defines the interface to the POSIX priority + * implementation. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_PRIORITYIMPL_H +#define _RTEMS_POSIX_PRIORITYIMPL_H + +#include <rtems/score/scheduler.h> +#include <rtems/score/assert.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup POSIX_PRIORITY POSIX Priority Support + * + * @ingroup POSIXAPI + * + * @brief Interface to the POSIX Priority Implementation. + * + * @{ + */ + +/** + * This is the numerically least important POSIX priority. + */ +#define POSIX_SCHEDULER_MINIMUM_PRIORITY (1) + +/** + * @brief Gets the maximum POSIX API priority for this scheduler instance. + * + * Such a priority is valid. A scheduler instance may support priority values + * that are not representable as an integer. + * + * @return The maximum POSIX API priority for this scheduler instance. + */ +RTEMS_INLINE_ROUTINE int _POSIX_Priority_Get_maximum( + const Scheduler_Control *scheduler +) +{ + _Assert( (int) scheduler->maximum_priority > 1 ); + return (int) scheduler->maximum_priority - 1; +} + +/** + * @brief Converts the POSIX API priority to the corresponding SuperCore + * priority and validates it. + * + * According to POSIX, numerically higher values represent higher priorities. + * Thus, SuperCore has priorities run in the opposite sense of the POSIX API. + * + * Let N be the maximum priority of this scheduler instance. The SuperCore + * priority zero is system reserved (PRIORITY_PSEUDO_ISR). There are only + * N - 1 POSIX API priority levels since a thread at SuperCore priority N would + * never run because of the idle threads. This is necessary because GNAT maps + * the lowest Ada task priority to the lowest thread priority. The lowest + * priority Ada task should get to run, so there is a fundamental conflict with + * having N priorities. + * + * @param[in] scheduler The scheduler instance. + * @param[in] priority The POSIX API priority to convert and validate. + * @param[out] valid Indicates if the POSIX API priority is valid and a + * corresponding SuperCore priority in the specified scheduler instance + * exists. + * + * @return The corresponding SuperCore priority. + */ +Priority_Control _POSIX_Priority_To_core( + const Scheduler_Control *scheduler, + int priority, + bool *valid +); + +/** + * @brief Converts the SuperCore priority to the corresponding POSIX API + * priority. + * + * @param[in] scheduler The scheduler instance. + * @param[in] priority The SuperCore priority to convert. + * + * @return The corresponding POSIX API priority. + */ +int _POSIX_Priority_From_core( + const Scheduler_Control *scheduler, + Priority_Control priority +); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/include/rtems/posix/psignal.h b/cpukit/include/rtems/posix/psignal.h new file mode 100644 index 0000000000..ed98442e32 --- /dev/null +++ b/cpukit/include/rtems/posix/psignal.h @@ -0,0 +1,35 @@ +/** + * @file + * + * @brief Internal Information about POSIX Signals + * + * This include file defines internal information about POSIX signals. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_PSIGNAL_H +#define _RTEMS_POSIX_PSIGNAL_H + +#include <sys/signal.h> + +#include <rtems/score/chain.h> + +/* + * POSIX internal siginfo structure + */ + +typedef struct { + Chain_Node Node; + siginfo_t Info; +} POSIX_signals_Siginfo_node; + +#endif +/* end of file */ diff --git a/cpukit/include/rtems/posix/psignalimpl.h b/cpukit/include/rtems/posix/psignalimpl.h new file mode 100644 index 0000000000..cccc3dafc9 --- /dev/null +++ b/cpukit/include/rtems/posix/psignalimpl.h @@ -0,0 +1,140 @@ +/** + * @file + * + * @brief POSIX Signals Support + * + * This include file defines internal information about POSIX signals. + */ + +/* + * COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_PSIGNALIMPL_H +#define _RTEMS_POSIX_PSIGNALIMPL_H + +/** + * @defgroup POSIX_SIGNALS POSIX Signals Support + * + * @ingroup POSIXAPI + * + * @brief Internal Information about POSIX Signals + * + */ +/**@{**/ + +#include <rtems/posix/psignal.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/sigset.h> +#include <rtems/score/isrlock.h> +#include <rtems/score/percpu.h> +#include <rtems/score/threadqimpl.h> + +#define POSIX_SIGNALS_TQ_OPERATIONS &_Thread_queue_Operations_FIFO + +#define _States_Is_interruptible_signal( _states ) \ + ( ((_states) & \ + (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) == \ + (STATES_WAITING_FOR_SIGNAL|STATES_INTERRUPTIBLE_BY_SIGNAL)) + +#define SIGACTION_TERMINATE \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Abnormal_termination_handler} } +#define SIGACTION_IGNORE \ + { 0, SIGNAL_ALL_MASK, {SIG_IGN} } +#define SIGACTION_STOP \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Stop_handler} } +#define SIGACTION_CONTINUE \ + { 0, SIGNAL_ALL_MASK, {_POSIX_signals_Continue_handler} } + +#define SIG_ARRAY_MAX (SIGRTMAX + 1) + +/* + * Variables + */ + +extern sigset_t _POSIX_signals_Pending; + +extern const struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ]; + +extern struct sigaction _POSIX_signals_Vectors[ SIG_ARRAY_MAX ]; + +extern Thread_queue_Control _POSIX_signals_Wait_queue; + +extern Chain_Control _POSIX_signals_Inactive_siginfo; + +extern Chain_Control _POSIX_signals_Siginfo[ SIG_ARRAY_MAX ]; + +/* + * Internal routines + */ + +RTEMS_INLINE_ROUTINE void _POSIX_signals_Acquire( + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Acquire( &_POSIX_signals_Wait_queue, queue_context ); +} + +RTEMS_INLINE_ROUTINE void _POSIX_signals_Release( + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Release( &_POSIX_signals_Wait_queue, queue_context ); +} + +/** + * @brief Unlock POSIX signals thread. + */ +bool _POSIX_signals_Unblock_thread( + Thread_Control *the_thread, + int signo, + siginfo_t *info +); + +/** + * @brief Clear POSIX signals. + */ +bool _POSIX_signals_Clear_signals( + POSIX_API_Control *api, + int signo, + siginfo_t *info, + bool is_global, + bool check_blocked, + bool do_signals_acquire_release +); + +int _POSIX_signals_Send( + pid_t pid, + int sig, + const union sigval *value +); + +/** + * @brief Set POSIX process signals. + */ +void _POSIX_signals_Set_process_signals( + sigset_t mask +); + +void _POSIX_signals_Clear_process_signals( + int signo +); + +/* + * Default signal handlers + */ + +#define _POSIX_signals_Stop_handler NULL +#define _POSIX_signals_Continue_handler NULL + +void _POSIX_signals_Abnormal_termination_handler( int signo ); + +/** @} */ + +#endif +/* end of file */ diff --git a/cpukit/include/rtems/posix/pthread.h b/cpukit/include/rtems/posix/pthread.h new file mode 100644 index 0000000000..05783ff4ad --- /dev/null +++ b/cpukit/include/rtems/posix/pthread.h @@ -0,0 +1,55 @@ +/** + * @file + * + * @brief POSIX Threads Private Support + * + * This include file contains all the private support information for + * POSIX threads. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_PTHREAD_H +#define _RTEMS_POSIX_PTHREAD_H + +#include <rtems/posix/config.h> +#include <rtems/posix/threadsup.h> +#include <rtems/score/thread.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup POSIX_PTHREAD POSIX Threads Support + * + * @ingroup POSIXAPI + * + * @brief Private Support Information for POSIX Threads + * + */ +/**@{**/ + +/** + * @brief POSIX threads initialize user threads body. + * + * This routine creates and starts all configured user + * initialization threads. + */ +extern void _POSIX_Threads_Initialize_user_threads_body(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/pthreadattrimpl.h b/cpukit/include/rtems/posix/pthreadattrimpl.h new file mode 100644 index 0000000000..12b8559181 --- /dev/null +++ b/cpukit/include/rtems/posix/pthreadattrimpl.h @@ -0,0 +1,95 @@ +/** + * @file + * + * @brief POSIX Threads Private Support + * + * This include file contains all the private support information for + * POSIX threads. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_PTHREADATTRIMPL_H +#define _RTEMS_POSIX_PTHREADATTRIMPL_H + +#include <errno.h> +#include <pthread.h> + +#include <rtems/score/basedefs.h> +#include <rtems/score/assert.h> +#include <rtems/posix/priorityimpl.h> +#if defined(RTEMS_POSIX_API) +#include <rtems/posix/threadsup.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup POSIX_PTHREAD + */ +/**@{**/ + +/** + * This variable contains the default POSIX Thread attributes. + */ +extern const pthread_attr_t _POSIX_Threads_Default_attributes; + +RTEMS_INLINE_ROUTINE void _POSIX_Threads_Copy_attributes( + pthread_attr_t *dst_attr, + const pthread_attr_t *src_attr +) +{ + *dst_attr = *src_attr; + _Assert( + dst_attr->affinitysetsize == sizeof(dst_attr->affinitysetpreallocated) + ); + dst_attr->affinityset = &dst_attr->affinitysetpreallocated; +} + +RTEMS_INLINE_ROUTINE void _POSIX_Threads_Initialize_attributes( + pthread_attr_t *attr +) +{ + _POSIX_Threads_Copy_attributes( + attr, + &_POSIX_Threads_Default_attributes + ); +} + +#if defined(RTEMS_POSIX_API) +RTEMS_INLINE_ROUTINE void _POSIX_Threads_Get_sched_param_sporadic( + const Thread_Control *the_thread, + const Scheduler_Control *scheduler, + struct sched_param *param +) +{ + const POSIX_API_Control *api; + + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + param->sched_ss_low_priority = _POSIX_Priority_From_core( + scheduler, + api->Sporadic.Low_priority.priority + ); + param->sched_ss_repl_period = api->Sporadic.sched_ss_repl_period; + param->sched_ss_init_budget = api->Sporadic.sched_ss_init_budget; + param->sched_ss_max_repl = api->Sporadic.sched_ss_max_repl; +} +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/pthreadimpl.h b/cpukit/include/rtems/posix/pthreadimpl.h new file mode 100644 index 0000000000..3e2351e57e --- /dev/null +++ b/cpukit/include/rtems/posix/pthreadimpl.h @@ -0,0 +1,129 @@ +/** + * @file + * + * @brief POSIX Threads Private Support + * + * This include file contains all the private support information for + * POSIX threads. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_PTHREADIMPL_H +#define _RTEMS_POSIX_PTHREADIMPL_H + +#include <rtems/posix/pthread.h> +#include <rtems/posix/config.h> +#include <rtems/posix/threadsup.h> +#include <rtems/score/assert.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/timespec.h> +#include <rtems/score/threadimpl.h> +#include <rtems/score/watchdogimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup POSIX_PTHREAD + */ +/**@{**/ + +/** + * The following sets the minimum stack size for POSIX threads. + */ +#define PTHREAD_MINIMUM_STACK_SIZE (_Stack_Minimum() * 2) + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +extern Thread_Information _POSIX_Threads_Information; + +RTEMS_INLINE_ROUTINE void _POSIX_Threads_Sporadic_timer_insert( + Thread_Control *the_thread, + POSIX_API_Control *api +) +{ + the_thread->cpu_time_budget = + _Timespec_To_ticks( &api->Sporadic.sched_ss_init_budget ); + + _Watchdog_Per_CPU_insert_ticks( + &api->Sporadic.Timer, + _Per_CPU_Get(), + _Timespec_To_ticks( &api->Sporadic.sched_ss_repl_period ) + ); +} + +void _POSIX_Threads_Sporadic_timer( Watchdog_Control *watchdog ); + +/** + * @brief POSIX threads sporadic budget callout. + * + * This routine handles the sporadic scheduling algorithm. + * + * @param[in] the_thread is a pointer to the thread whose budget + * has been exceeded. + */ +void _POSIX_Threads_Sporadic_budget_callout( + Thread_Control *the_thread +); + +int _POSIX_Thread_Translate_to_sched_policy( + Thread_CPU_budget_algorithms budget_algorithm +); + +/** + * @brief Translate sched_param into SuperCore terms. + * + * This method translates the POSIX API sched_param into the corresponding + * SuperCore settings. + * + * @param[in] policy is the POSIX scheduling policy + * @param[in] param points to the scheduling parameter structure + * @param[in] budget_algorithm points to the output CPU Budget algorithm + * @param[in] budget_callout points to the output CPU Callout + * + * @retval 0 Indicates success. + * @retval error_code POSIX error code indicating failure. + */ +int _POSIX_Thread_Translate_sched_param( + int policy, + struct sched_param *param, + Thread_CPU_budget_algorithms *budget_algorithm, + Thread_CPU_budget_algorithm_callout *budget_callout +); + +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate(void) +{ + _Objects_Allocator_lock(); + + _Thread_Kill_zombies(); + + return (Thread_Control *) + _Objects_Allocate_unprotected( &_POSIX_Threads_Information.Objects ); +} + +RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free ( + Thread_Control *the_pthread +) +{ + _Objects_Free( &_POSIX_Threads_Information.Objects, &the_pthread->Object ); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/ptimer.h b/cpukit/include/rtems/posix/ptimer.h new file mode 100644 index 0000000000..f6de4ccb57 --- /dev/null +++ b/cpukit/include/rtems/posix/ptimer.h @@ -0,0 +1,88 @@ +/** + * @file + * + * @brief POSIX Timers Private Support + * + * This include file contains all the private support information for + * POSIX timers. + */ + +/* + * Initial Implementation: + * COPYRIGHT (c) 1998. Alfonso Escalera PiƱa + * Largely rewritten by Joel Sherrill (1999). + * + * COPYRIGHT (c) 1999-2013. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_PTIMER_H +#define _RTEMS_POSIX_PTIMER_H + +/** + * @defgroup POSIX_PRIV_TIMERS POSIX Timers + * + * @ingroup POSIXAPI + */ +/**@{**/ +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems/posix/config.h> + +/** + * @brief Create a Per-Process Timer + */ +int timer_create( + clockid_t clock_id, + struct sigevent *evp, + timer_t *timerid +); + +/** + * @brief Delete a Per-Process Timer + */ +int timer_delete( + timer_t timerid +); + +/** + * @brief Set a Per-Process Timer + */ +int timer_settime( + timer_t timerid, + int flags, + const struct itimerspec *value, + struct itimerspec *ovalue +); + +/** + * @brief Set a Per-Process Timer + */ +int timer_gettime( + timer_t timerid, + struct itimerspec *value +); + +/** + * @brief Get overrun count for a Per-Process Timer + * + * The expiration of a timer must increase by one a counter. + * After the signal handler associated to the timer finishes + * its execution, _POSIX_Timer_TSR will have to set this counter to 0. + */ +int timer_getoverrun( + timer_t timerid +); + +#ifdef __cplusplus +} +#endif +/** @} */ + +#endif /* _RTEMS_POSIX_PTIMER_H */ diff --git a/cpukit/include/rtems/posix/rwlockimpl.h b/cpukit/include/rtems/posix/rwlockimpl.h new file mode 100644 index 0000000000..b92ca9d04c --- /dev/null +++ b/cpukit/include/rtems/posix/rwlockimpl.h @@ -0,0 +1,64 @@ +/** + * @file + * + * @brief Inlined Routines from the POSIX RWLock Manager + * + * This file contains the static inlin implementation of the inlined + * routines from the POSIX RWLock Manager. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_RWLOCKIMPL_H +#define _RTEMS_POSIX_RWLOCKIMPL_H + +#include <rtems/score/corerwlockimpl.h> + +#include <errno.h> +#include <pthread.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define POSIX_RWLOCK_MAGIC 0x9621dabdUL + +typedef struct { + unsigned long flags; + CORE_RWLock_Control RWLock; +} POSIX_RWLock_Control; + +RTEMS_INLINE_ROUTINE POSIX_RWLock_Control *_POSIX_RWLock_Get( + pthread_rwlock_t *rwlock +) +{ + return (POSIX_RWLock_Control *) rwlock; +} + +bool _POSIX_RWLock_Auto_initialization( POSIX_RWLock_Control *the_rwlock ); + +#define POSIX_RWLOCK_VALIDATE_OBJECT( rw ) \ + do { \ + if ( ( rw ) == NULL ) { \ + return EINVAL; \ + } \ + if ( ( (uintptr_t) ( rw ) ^ POSIX_RWLOCK_MAGIC ) != ( rw )->flags ) { \ + if ( !_POSIX_RWLock_Auto_initialization( rw ) ) { \ + return EINVAL; \ + } \ + } \ + } while ( 0 ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/semaphore.h b/cpukit/include/rtems/posix/semaphore.h new file mode 100644 index 0000000000..9133db22be --- /dev/null +++ b/cpukit/include/rtems/posix/semaphore.h @@ -0,0 +1,56 @@ +/** + * @file + * + * @brief Private Support Information for POSIX Semaphores + * + * This include file contains all the private support information for + * POSIX Semaphores. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_SEMAPHORE_H +#define _RTEMS_POSIX_SEMAPHORE_H + +#include <semaphore.h> +#include <rtems/score/object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup POSIXSemaphorePrivate POSIX Semaphore Private Support + * + * @ingroup POSIXAPI + * + * This defines the internal implementation support for POSIX semaphores. + */ +/**@{*/ + +/* + * Data Structure used to manage a POSIX semaphore + */ + +typedef struct { + Objects_Control Object; + sem_t Semaphore; + bool linked; + uint32_t open_count; +} POSIX_Semaphore_Control; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/semaphoreimpl.h b/cpukit/include/rtems/posix/semaphoreimpl.h new file mode 100644 index 0000000000..fd17743699 --- /dev/null +++ b/cpukit/include/rtems/posix/semaphoreimpl.h @@ -0,0 +1,143 @@ +/** + * @file + * + * @brief Private Inlined Routines for POSIX Semaphores + * + * This include file contains the static inline implementation of the private + * inlined routines for POSIX Semaphores. + */ + +/* + * COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_SEMAPHOREIMPL_H +#define _RTEMS_POSIX_SEMAPHOREIMPL_H + +#include <rtems/posix/semaphore.h> +#include <rtems/posix/posixapi.h> +#include <rtems/score/semaphoreimpl.h> +#include <rtems/seterr.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief This is a random number used to check if a semaphore object is + * properly initialized. + */ +#define POSIX_SEMAPHORE_MAGIC 0x5d367fe7UL + +/** + * This defines the information control block used to manage + * this class of objects. + */ +extern Objects_Information _POSIX_Semaphore_Information; + +RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control * + _POSIX_Semaphore_Allocate_unprotected( void ) +{ + return (POSIX_Semaphore_Control *) + _Objects_Allocate_unprotected( &_POSIX_Semaphore_Information ); +} + +/** + * @brief POSIX Semaphore Free + * + * This routine frees a semaphore control block to the + * inactive chain of free semaphore control blocks. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Free ( + POSIX_Semaphore_Control *the_semaphore +) +{ + _Objects_Free( &_POSIX_Semaphore_Information, &the_semaphore->Object ); +} + +RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get( + sem_t *sem +) +{ + return RTEMS_CONTAINER_OF( sem, POSIX_Semaphore_Control, Semaphore ); +} + +RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_named( const sem_t *sem ) +{ + return sem->_Semaphore._Queue._name != NULL; +} + +RTEMS_INLINE_ROUTINE bool _POSIX_Semaphore_Is_busy( const sem_t *sem ) +{ + return sem->_Semaphore._Queue._heads != NULL; +} + +RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Initialize( + sem_t *sem, + const char *name, + unsigned int value +) +{ + sem->_flags = (uintptr_t) sem ^ POSIX_SEMAPHORE_MAGIC; + _Semaphore_Initialize_named( &sem->_Semaphore, name, value ); +} + +RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Destroy( sem_t *sem ) +{ + sem->_flags = 0; + _Semaphore_Destroy( &sem->_Semaphore ); +} + +/** + * @brief POSIX Semaphore Delete + * + * This routine supports the sem_close and sem_unlink routines. + */ +void _POSIX_Semaphore_Delete( POSIX_Semaphore_Control *the_semaphore ); + +/** + * @brief POSIX Semaphore Namespace Remove + */ +RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Namespace_remove ( + POSIX_Semaphore_Control *the_semaphore +) +{ + _Objects_Namespace_remove( + &_POSIX_Semaphore_Information, &the_semaphore->Object ); +} + +RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get_by_name( + const char *name, + size_t *name_length_p, + Objects_Get_by_name_error *error +) +{ + return (POSIX_Semaphore_Control *) _Objects_Get_by_name( + &_POSIX_Semaphore_Information, + name, + name_length_p, + error + ); +} + +#define POSIX_SEMAPHORE_VALIDATE_OBJECT( sem ) \ + do { \ + if ( \ + ( sem ) == NULL \ + || ( (uintptr_t) ( sem ) ^ POSIX_SEMAPHORE_MAGIC ) != ( sem )->_flags \ + ) { \ + rtems_set_errno_and_return_minus_one( EINVAL ); \ + } \ + } while ( 0 ) + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/shm.h b/cpukit/include/rtems/posix/shm.h new file mode 100644 index 0000000000..d2b6036493 --- /dev/null +++ b/cpukit/include/rtems/posix/shm.h @@ -0,0 +1,213 @@ +/** + * @file + * + * @brief Internal Support for POSIX Shared Memory + */ + +/* + * Copyright (c) 2016 Gedare Bloom. + * + * 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. + */ + +#ifndef _RTEMS_POSIX_SHM_H +#define _RTEMS_POSIX_SHM_H + +#include <rtems/score/object.h> +#include <rtems/score/threadq.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup POSIXShmPrivate POSIX Shared Memory Private Support + * + * @ingroup POSIXAPI + * + * Internal implementation support for POSIX shared memory. + * @{ + */ +typedef struct POSIX_Shm_Object_operations POSIX_Shm_Object_operations; +extern const POSIX_Shm_Object_operations _POSIX_Shm_Object_operations; + +/** + * @brief Encapsulation for the storage and manipulation of shm objects. + */ +typedef struct { + /** + * @brief The handle is private for finding object storage. + */ + void *handle; + + /** + * @brief The number of bytes allocated to the object. A size of 0 with + * a handle of NULL means no object is allocated. + */ + size_t size; + + /** + * @brief Implementation-specific operations on shm objects. + */ + const POSIX_Shm_Object_operations *ops; +} POSIX_Shm_Object; + +/** + * @brief Operations on POSIX Shared Memory Objects. + */ +struct POSIX_Shm_Object_operations { + /** + * @brief Allocates a new @a shm_obj with initial @a size. + * + * New shared memory is initialized to zeroes. + * + * Returns 0 for success. + */ + int ( *object_create ) ( POSIX_Shm_Object *shm_obj, size_t size ); + + /** + * @brief Changes the @a shm_obj size to @a size. + * + * Zeroes out the portion of the shared memory object that shrinks or grows. + * + * Returns 0 for success. + */ + int ( *object_resize ) ( POSIX_Shm_Object *shm_obj, size_t size ); + + /** + * @brief Deletes the @a shm_obj. + * + * Zeroes out the memory. + * + * Returns 0 for success. + */ + int ( *object_delete ) ( POSIX_Shm_Object *shm_obj ); + + /** + * @brief Copies up to @count bytes of the @a shm_obj data into @a buf. + * + * Returns the number of bytes read (copied) into @a buf. + */ + int ( *object_read ) ( POSIX_Shm_Object *shm_obj, void *buf, size_t count ); + + /** + * @brief Maps a shared memory object. + * + * Establishes a memory mapping between the shared memory object and the + * caller. + * + * Returns the mapped address of the object. + */ + void * ( *object_mmap ) ( POSIX_Shm_Object *shm_obj, size_t len, int prot, off_t off); +}; + +/** + * @brief Control for a POSIX Shared Memory Object + */ +typedef struct { + Objects_Control Object; + Thread_queue_Control Wait_queue; + + int reference_count; + + POSIX_Shm_Object shm_object; + + uid_t uid; + gid_t gid; + mode_t mode; + int oflag; + + time_t atime; + time_t mtime; + time_t ctime; +} POSIX_Shm_Control; + +/** + * @brief object_create operation for shm objects stored in RTEMS Workspace. + */ +extern int _POSIX_Shm_Object_create_from_workspace( + POSIX_Shm_Object *shm_obj, + size_t size +); + +/** + * @brief object_delete operation for shm objects stored in RTEMS Workspace. + */ +extern int _POSIX_Shm_Object_delete_from_workspace( POSIX_Shm_Object *shm_obj ); + +/** + * @brief object_resize operation for shm objects stored in RTEMS Workspace. + */ +extern int _POSIX_Shm_Object_resize_from_workspace( + POSIX_Shm_Object *shm_obj, + size_t size +); + +/** + * @brief object_read operation for shm objects stored in RTEMS Workspace. + */ +extern int _POSIX_Shm_Object_read_from_workspace( + POSIX_Shm_Object *shm_obj, + void *buf, + size_t count +); + +/** + * @brief object_mmap operation for shm objects stored in RTEMS Workspace. + */ +extern void * _POSIX_Shm_Object_mmap_from_workspace( + POSIX_Shm_Object *shm_obj, + size_t len, + int prot, + off_t off +); + +/** + * @brief object_create operation for shm objects stored in C program heap. + */ +extern int _POSIX_Shm_Object_create_from_heap( + POSIX_Shm_Object *shm_obj, + size_t size +); + +/** + * @brief object_delete operation for shm objects stored in C program heap. + */ +extern int _POSIX_Shm_Object_delete_from_heap( POSIX_Shm_Object *shm_obj ); + +/** + * @brief object_resize operation for shm objects stored in C program heap. + */ +extern int _POSIX_Shm_Object_resize_from_heap( + POSIX_Shm_Object *shm_obj, + size_t size +); + +/** + * @brief object_read operation for shm objects stored in C program heap. + */ +extern int _POSIX_Shm_Object_read_from_heap( + POSIX_Shm_Object *shm_obj, + void *buf, + size_t count +); + +/** + * @brief object_mmap operation for shm objects stored in C program heap. + */ +extern void * _POSIX_Shm_Object_mmap_from_heap( + POSIX_Shm_Object *shm_obj, + size_t len, + int prot, + off_t off +); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/include/rtems/posix/shmimpl.h b/cpukit/include/rtems/posix/shmimpl.h new file mode 100644 index 0000000000..f16af8123d --- /dev/null +++ b/cpukit/include/rtems/posix/shmimpl.h @@ -0,0 +1,135 @@ +/** + * @file + * + * @brief Private Support Information for POSIX Shared Memory + * + */ + +/* + * Copyright (c) 2016 Gedare Bloom. + * + * 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. + */ + +#ifndef _RTEMS_POSIX_SHMIMPL_H +#define _RTEMS_POSIX_SHMIMPL_H + +#include <rtems/fs.h> +#include <rtems/libio.h> +#include <rtems/posix/posixapi.h> +#include <rtems/posix/shm.h> +#include <rtems/score/objectimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup POSIXShmPrivate + * @{ + */ + +extern Objects_Information _POSIX_Shm_Information; + +RTEMS_INLINE_ROUTINE POSIX_Shm_Control *_POSIX_Shm_Allocate_unprotected( void ) +{ + return (POSIX_Shm_Control *) + _Objects_Allocate_unprotected( &_POSIX_Shm_Information ); +} + +/** + * @brief POSIX Shared Memory Free + * + * This routine frees a shm control block. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Shm_Free ( + POSIX_Shm_Control *the_shm +) +{ + _Objects_Free( &_POSIX_Shm_Information, &the_shm->Object ); +} + +RTEMS_INLINE_ROUTINE POSIX_Shm_Control *_POSIX_Shm_Get_by_name( + const char *name, + size_t *name_length_p, + Objects_Get_by_name_error *error +) +{ + return (POSIX_Shm_Control *) _Objects_Get_by_name( + &_POSIX_Shm_Information, + name, + name_length_p, + error + ); +} + +RTEMS_INLINE_ROUTINE void _POSIX_Shm_Update_atime( + POSIX_Shm_Control *shm +) +{ + struct timeval now; + gettimeofday( &now, 0 ); + shm->atime = now.tv_sec; +} + +RTEMS_INLINE_ROUTINE void _POSIX_Shm_Update_mtime_ctime( + POSIX_Shm_Control *shm +) +{ + struct timeval now; + gettimeofday( &now, 0 ); + shm->mtime = now.tv_sec; + shm->ctime = now.tv_sec; +} + +static inline POSIX_Shm_Control* iop_to_shm( rtems_libio_t *iop ) +{ + return (POSIX_Shm_Control*) iop->data1; +} + +static inline POSIX_Shm_Control* loc_to_shm( + const rtems_filesystem_location_info_t *loc +) +{ + return (POSIX_Shm_Control*) loc->node_access; +} + +static inline int POSIX_Shm_Attempt_delete( + POSIX_Shm_Control* shm +) +{ + Objects_Control *obj; + ISR_lock_Context lock_ctx; + int err; + + err = 0; + + _Objects_Allocator_lock(); + --shm->reference_count; + if ( shm->reference_count == 0 ) { + if ( (*shm->shm_object.ops->object_delete)( &shm->shm_object ) != 0 ) { + err = EIO; + } + } + /* check if the object has been unlinked yet. */ + obj = _Objects_Get( shm->Object.id, &lock_ctx, &_POSIX_Shm_Information ); + if ( obj == NULL ) { + /* if it was unlinked, then it can be freed. */ + _POSIX_Shm_Free( shm ); + } else { + /* it will be freed when it is unlinked. */ + _ISR_lock_ISR_enable( &lock_ctx ); + } + _Objects_Allocator_unlock(); + return err; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cpukit/include/rtems/posix/sigset.h b/cpukit/include/rtems/posix/sigset.h new file mode 100644 index 0000000000..96bcc086ba --- /dev/null +++ b/cpukit/include/rtems/posix/sigset.h @@ -0,0 +1,45 @@ +/** + * @file + * + * @brief POSIX Signal Sets Management Helper + * + * This file defines the interface to implementation helper for management + * of POSIX Signal Sets. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_SIGSET_H +#define _RTEMS_POSIX_SIGSET_H + +#include <signal.h> // sigset_t + +/* + * Currently 32 signals numbered 1-32 are defined + */ + +#define SIGNAL_EMPTY_MASK 0x00000000L +#define SIGNAL_ALL_MASK 0xffffffffL + +static inline sigset_t signo_to_mask( + uint32_t sig +) +{ + return 1u << (sig - 1); +} + +static inline bool is_valid_signo( + int signo +) +{ + return ((signo) >= 1 && (signo) <= 32 ); +} + +#endif diff --git a/cpukit/include/rtems/posix/spinlockimpl.h b/cpukit/include/rtems/posix/spinlockimpl.h new file mode 100644 index 0000000000..d28e0391fc --- /dev/null +++ b/cpukit/include/rtems/posix/spinlockimpl.h @@ -0,0 +1,58 @@ +/** + * @file + * + * @brief Inlined Routines from the POSIX Spinlock Manager + * + * This file contains the static inlin implementation of the inlined + * routines from the POSIX Spinlock Manager. + */ + +/* + * 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. + */ + +#ifndef _RTEMS_POSIX_SPINLOCKIMPL_H +#define _RTEMS_POSIX_SPINLOCKIMPL_H + +#include <pthread.h> + +#include <rtems/score/isrlevel.h> + +#if defined(RTEMS_SMP) +#include <rtems/score/percpu.h> +#include <rtems/score/smplockticket.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { +#if defined(RTEMS_SMP) + SMP_ticket_lock_Control Lock; +#else + unsigned int reserved[ 2 ]; +#endif + ISR_Level interrupt_state; +} POSIX_Spinlock_Control; + +RTEMS_INLINE_ROUTINE POSIX_Spinlock_Control *_POSIX_Spinlock_Get( + pthread_spinlock_t *lock +) +{ + return (POSIX_Spinlock_Control *) lock; +} + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/threadsup.h b/cpukit/include/rtems/posix/threadsup.h new file mode 100644 index 0000000000..d3ee5b28bb --- /dev/null +++ b/cpukit/include/rtems/posix/threadsup.h @@ -0,0 +1,98 @@ +/** + * @file + * + * @brief POSIX Thread API Support + * + * This defines the POSIX thread API extension. + */ + +/* + * COPYRIGHT (c) 1989-2014. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_THREADSUP_H +#define _RTEMS_POSIX_THREADSUP_H + +#include <rtems/score/thread.h> +#include <rtems/score/watchdog.h> + +#include <pthread.h> +#include <signal.h> + +/** + * @defgroup POSIX_THREAD POSIX Thread API Extension + * + * @ingroup POSIXAPI + * + */ +/**@{**/ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This defines the POSIX API support structure associated with + * each thread in a system with POSIX configured. + */ +typedef struct { + /** + * @brief Control block for the sporadic server scheduling policy. + */ + struct { + /** The thread of this sporadic control block */ + Thread_Control *thread; + + /** + * @brief This is the timer which controls when the thread executes at high + * and low priority when using the sporadic server scheduling policy. + */ + Watchdog_Control Timer; + + /** + * @brief The low priority when using the sporadic server scheduling + * policy. + */ + Priority_Node Low_priority; + + /** + * @brief Replenishment period for sporadic server. + */ + struct timespec sched_ss_repl_period; + + /** + * @brief Initial budget for sporadic server. + */ + struct timespec sched_ss_init_budget; + + /** + * @brief Maximum pending replenishments. + * + * Only used by pthread_getschedparam() and pthread_getattr_np(). + */ + int sched_ss_max_repl; + } Sporadic; + + /** This is the set of signals which are currently unblocked. */ + sigset_t signals_unblocked; + /** This is the set of signals which are currently pending. */ + sigset_t signals_pending; + + /** + * @brief Signal post-switch action in case signals are pending. + */ + Thread_Action Signal_action; +} POSIX_API_Control; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/timer.h b/cpukit/include/rtems/posix/timer.h new file mode 100644 index 0000000000..79fe093219 --- /dev/null +++ b/cpukit/include/rtems/posix/timer.h @@ -0,0 +1,60 @@ +/** + * @file + * + * @brief POSIX Timers Internal Support + * + * This include files defines the internal support for implementation of + * POSIX Timers. + */ + +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_TIMER_H +#define _RTEMS_POSIX_TIMER_H + +#include <rtems/score/object.h> +#include <rtems/score/watchdog.h> + +#include <pthread.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup POSIX_INTERNAL_TIMERS POSIX Timer Private Support + * + * @ingroup POSIXAPI + */ +/**@{*/ + +/* + * Data for a timer + */ +typedef struct { + Objects_Control Object; + Watchdog_Control Timer; /* Internal Timer */ + pthread_t thread_id; /* Thread identifier */ + char state; /* State of the timer */ + struct sigevent inf; /* Information associated to the timer */ + struct itimerspec timer_data; /* Timing data of the timer */ + uint32_t ticks; /* Number of ticks of the initialization */ + uint32_t overrun; /* Number of expirations of the timer */ + struct timespec time; /* Time at which the timer was started */ +} POSIX_Timer_Control; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/cpukit/include/rtems/posix/timerimpl.h b/cpukit/include/rtems/posix/timerimpl.h new file mode 100644 index 0000000000..42a814c992 --- /dev/null +++ b/cpukit/include/rtems/posix/timerimpl.h @@ -0,0 +1,134 @@ +/** + * @file + * + * @brief Inlined Routines from the POSIX Timer Manager + * + * This file contains the static inline implementation of the inlined routines + * from the POSIX Timer Manager. + */ + +/* + * COPYRIGHT (c) 1989-2013. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +#ifndef _RTEMS_POSIX_TIMERIMPL_H +#define _RTEMS_POSIX_TIMERIMPL_H + +#include <rtems/posix/timer.h> +#include <rtems/score/objectimpl.h> +#include <rtems/score/watchdogimpl.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** Timer is free */ +#define POSIX_TIMER_STATE_FREE 0x01 + +/** Created timer but not running */ +#define POSIX_TIMER_STATE_CREATE_NEW 0x02 + +/** Created timer and running */ +#define POSIX_TIMER_STATE_CREATE_RUN 0x03 + +/** Created, ran and stopped timer */ +#define POSIX_TIMER_STATE_CREATE_STOP 0x04 + +/** Indicates that the fire time is relative to the current one */ +#define POSIX_TIMER_RELATIVE 0 + +/* + * POSIX defines TIMER_ABSTIME but no constant for relative. So + * we have one internally but we need to be careful it has a different + * value. + */ +#if (POSIX_TIMER_RELATIVE == TIMER_ABSTIME) +#error "POSIX_TIMER_RELATIVE == TIMER_ABSTIME" +#endif + +/** + * The following defines the information control block used to manage + * this class of objects. + */ +extern Objects_Information _POSIX_Timer_Information; + +/** + * @brief POSIX Timer Allocate + * + * This function allocates a timer control block from + * the inactive chain of free timer control blocks. + */ +RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Allocate( void ) +{ + return (POSIX_Timer_Control *) _Objects_Allocate( &_POSIX_Timer_Information ); +} + +/** + * @brief POSIX Timer Free + * + * This routine frees a timer control block to the + * inactive chain of free timer control blocks. + */ +RTEMS_INLINE_ROUTINE void _POSIX_Timer_Free ( + POSIX_Timer_Control *the_timer +) +{ + _Objects_Free( &_POSIX_Timer_Information, &the_timer->Object ); +} + +void _POSIX_Timer_TSR( Watchdog_Control *the_watchdog ); + +/** + * @brief POSIX Timer Get + * + * This function maps timer IDs to timer control blocks. + * If ID corresponds to a local timer, then it returns + * the timer control pointer which maps to ID and location + * is set to OBJECTS_LOCAL. Otherwise, location is set + * to OBJECTS_ERROR and the returned value is undefined. + */ +RTEMS_INLINE_ROUTINE POSIX_Timer_Control *_POSIX_Timer_Get ( + timer_t id, + ISR_lock_Context *lock_context +) +{ + return (POSIX_Timer_Control *) _Objects_Get( + (Objects_Id) id, + lock_context, + &_POSIX_Timer_Information + ); +} + +RTEMS_INLINE_ROUTINE Per_CPU_Control *_POSIX_Timer_Acquire_critical( + POSIX_Timer_Control *ptimer, + ISR_lock_Context *lock_context +) +{ + Per_CPU_Control *cpu; + + cpu = _Watchdog_Get_CPU( &ptimer->Timer ); + _Watchdog_Per_CPU_acquire_critical( cpu, lock_context ); + + return cpu; +} + +RTEMS_INLINE_ROUTINE void _POSIX_Timer_Release( + Per_CPU_Control *cpu, + ISR_lock_Context *lock_context +) +{ + _Watchdog_Per_CPU_release_critical( cpu, lock_context ); + _ISR_lock_ISR_enable( lock_context ); +} + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ |