diff options
Diffstat (limited to 'cpukit/score/inline/rtems')
28 files changed, 4521 insertions, 0 deletions
diff --git a/cpukit/score/inline/rtems/score/address.inl b/cpukit/score/inline/rtems/score/address.inl new file mode 100644 index 0000000000..03aeef3732 --- /dev/null +++ b/cpukit/score/inline/rtems/score/address.inl @@ -0,0 +1,143 @@ +/** + * @file rtems/score/address.inl + * + * This include file contains the bodies of the routines + * about addresses which are inlined. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_ADDRESS_H +# error "Never use <rtems/score/address.inl> directly; include <rtems/score/address.h> instead." +#endif + +#ifndef _RTEMS_SCORE_ADDRESS_INL +#define _RTEMS_SCORE_ADDRESS_INL + +#include <rtems/score/basedefs.h> + +/** + * @addtogroup ScoreAddress + * @{ + */ + +/** @brief Add Offset to Address + * + * This function is used to add an @a offset to a @a base address. + * It returns the resulting address. This address is typically + * converted to an access type before being used further. + * + * @param[in] base is the base address. + * @param[in] offset is the offset to add to @a base. + * + * @return This method returns the resulting address. + */ +#include <rtems/bspIo.h> +RTEMS_INLINE_ROUTINE void *_Addresses_Add_offset ( + const void *base, + uintptr_t offset +) +{ + return (void *)((uintptr_t)base + offset); +} + +/** @brief Subtract Offset from Offset + * + * This function is used to subtract an @a offset from a @a base + * address. It returns the resulting address. This address is + * typically converted to an access type before being used further. + * + * @param[in] base is the base address. + * @param[in] offset is the offset to subtract to @a base. + * + * @return This method returns the resulting address. + */ + +RTEMS_INLINE_ROUTINE void *_Addresses_Subtract_offset ( + const void *base, + uintptr_t offset +) +{ + return (void *)((uintptr_t)base - offset); +} + +/** @brief Subtract Two Offsets + * + * This function is used to subtract two addresses. It returns the + * resulting offset. + * + * @param[in] left is the address on the left hand side of the subtraction. + * @param[in] right is the address on the right hand side of the subtraction. + * + * @return This method returns the resulting address. + * + * @note The cast of an address to an uint32_t makes this code + * dependent on an addresses being thirty two bits. + */ +RTEMS_INLINE_ROUTINE int32_t _Addresses_Subtract ( + const void *left, + const void *right +) +{ + return (int32_t) ((const char *) left - (const char *) right); +} + +/** @brief Is Address Aligned + * + * This function returns true if the given address is correctly + * aligned for this processor and false otherwise. Proper alignment + * is based on correctness and efficiency. + * + * @param[in] address is the address being checked for alignment. + * + * @return This method returns true if the address is aligned and + * false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Addresses_Is_aligned ( + const void *address +) +{ +#if (CPU_ALIGNMENT == 0) + return true; +#else + return (((uintptr_t)address % CPU_ALIGNMENT) == 0); +#endif +} + +/** @brief Is Address In Range + * + * This function returns true if the given address is within the + * memory range specified and false otherwise. base is the address + * of the first byte in the memory range and limit is the address + * of the last byte in the memory range. The base address is + * assumed to be lower than the limit address. + * + * @param[in] address is the address to check. + * @param[in] base is the lowest address of the range to check against. + * @param[in] limit is the highest address of the range to check against. + * + * @return This method returns true if the given @a address is within the + * memory range specified and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Addresses_Is_in_range ( + const void *address, + const void *base, + const void *limit +) +{ + return (address >= base && address <= limit); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/chain.inl b/cpukit/score/inline/rtems/score/chain.inl new file mode 100644 index 0000000000..ae6fd38b43 --- /dev/null +++ b/cpukit/score/inline/rtems/score/chain.inl @@ -0,0 +1,647 @@ +/** + * @file + * + * @ingroup ScoreChain + * + * @brief Chain Handler API. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. + * + * COPYRIGHT (c) 1989-2006. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_CHAIN_H +# error "Never use <rtems/score/chain.inl> directly; include <rtems/score/chain.h> instead." +#endif + +#ifndef _RTEMS_SCORE_CHAIN_INL +#define _RTEMS_SCORE_CHAIN_INL + +/** + * @addtogroup ScoreChain + * @{ + */ + +/** @brief Set off chain + * + * This function sets the next and previous fields of the @a node to NULL + * indicating the @a node is not part of a chain. + * + * @param[in] node the node set to off chain. + */ +RTEMS_INLINE_ROUTINE void _Chain_Set_off_chain( + Chain_Node *node +) +{ + node->next = node->previous = NULL; +} + +/** @brief Is the Node off Chain + * + * This function returns true if the @a node is not on a chain. A @a node is + * off chain if the next and previous fields are set to NULL. + * + * @param[in] node is the node off chain. + * + * @return This function returns true if the @a node is off chain. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Is_node_off_chain( + const Chain_Node *node +) +{ + return (node->next == NULL) && (node->previous == NULL); +} + +/** @brief Are Two Nodes Equal + * + * This function returns true if @a left and @a right are equal, + * and false otherwise. + * + * @param[in] left is the node on the left hand side of the comparison. + * @param[in] right is the node on the left hand side of the comparison. + * + * @return This function returns true if @a left and @a right are equal, + * and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Are_nodes_equal( + const Chain_Node *left, + const Chain_Node *right +) +{ + return left == right; +} + +/** @brief Is this Chain Control Pointer Null + * + * This function returns true if the_chain is NULL and false otherwise. + * + * @param[in] the_chain is the chain to be checked for empty status. + * + * @return This method returns true if the_chain is NULL and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Is_null( + const Chain_Control *the_chain +) +{ + return (the_chain == NULL); +} + +/** @brief Is the Chain Node Pointer NULL + * + * This function returns true if the_node is NULL and false otherwise. + * + * @param[in] the_node is the node pointer to check. + * + * @return This method returns true if the_node is NULL and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Is_null_node( + const Chain_Node *the_node +) +{ + return (the_node == NULL); +} + +/** @brief Return pointer to Chain Head + * + * This function returns a pointer to the head node on the chain. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the permanent head node of the chain. + */ +RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Head( + Chain_Control *the_chain +) +{ + return &the_chain->Head.Node; +} + +/** @brief Return pointer to immutable Chain Head + * + * This function returns a pointer to the head node on the chain. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the permanent head node of the chain. + */ +RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_head( + const Chain_Control *the_chain +) +{ + return &the_chain->Head.Node; +} + +/** @brief Return pointer to Chain Tail + * + * This function returns a pointer to the last node on the chain. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the permanent tail node of the chain. + */ +RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Tail( + Chain_Control *the_chain +) +{ + return &the_chain->Tail.Node; +} + +/** @brief Return pointer to immutable Chain Tail + * + * This function returns a pointer to the last node on the chain. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the permanent tail node of the chain. + */ +RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_tail( + const Chain_Control *the_chain +) +{ + return &the_chain->Tail.Node; +} + +/** @brief Return pointer to Chain's First node + * + * This function returns a pointer to the first node on the chain after the + * head. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the first node of the chain. + */ +RTEMS_INLINE_ROUTINE Chain_Node *_Chain_First( + Chain_Control *the_chain +) +{ + return _Chain_Head( the_chain )->next; +} + +/** @brief Return pointer to immutable Chain's First node + * + * This function returns a pointer to the first node on the chain after the + * head. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the first node of the chain. + */ +RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_first( + const Chain_Control *the_chain +) +{ + return _Chain_Immutable_head( the_chain )->next; +} + +/** @brief Return pointer to Chain's Last node + * + * This function returns a pointer to the last node on the chain just before + * the tail. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the last node of the chain. + */ +RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Last( + Chain_Control *the_chain +) +{ + return _Chain_Tail( the_chain )->previous; +} + +/** @brief Return pointer to immutable Chain's Last node + * + * This function returns a pointer to the last node on the chain just before + * the tail. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This method returns the last node of the chain. + */ +RTEMS_INLINE_ROUTINE const Chain_Node *_Chain_Immutable_last( + const Chain_Control *the_chain +) +{ + return _Chain_Immutable_tail( the_chain )->previous; +} + +/** @brief Return pointer the next node from this node + * + * This function returns a pointer to the next node after this node. + * + * @param[in] the_node is the node to be operated upon. + * + * @return This method returns the next node on the chain. + */ +RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Next( + Chain_Node *the_node +) +{ + return the_node->next; +} + +/** @brief Return pointer the previous node from this node + * + * This function returns a pointer to the previous node on this chain. + * + * @param[in] the_node is the node to be operated upon. + * + * @return This method returns the previous node on the chain. + */ +RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Previous( + Chain_Node *the_node +) +{ + return the_node->previous; +} + +/** @brief Is the Chain Empty + * + * This function returns true if there a no nodes on @a the_chain and + * false otherwise. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This function returns true if there a no nodes on @a the_chain and + * false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Is_empty( + const Chain_Control *the_chain +) +{ + return _Chain_Immutable_first( the_chain ) + == _Chain_Immutable_tail( the_chain ); +} + +/** @brief Is this the First Node on the Chain + * + * This function returns true if the_node is the first node on a chain and + * false otherwise. + * + * @param[in] the_node is the node the caller wants to know if it is + * the first node on a chain. + * + * @return This function returns true if @a the_node is the first node on + * a chain and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Is_first( + const Chain_Node *the_node +) +{ + return (the_node->previous == NULL); +} + +/** @brief Is this the Last Node on the Chain + * + * This function returns true if @a the_node is the last node on a chain and + * false otherwise. + * + * @param[in] the_node is the node to check as the last node. + * + * @return This function returns true if @a the_node is the last node on + * a chain and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Is_last( + const Chain_Node *the_node +) +{ + return (the_node->next == NULL); +} + +/** @brief Does this Chain have only One Node + * + * This function returns true if there is only one node on @a the_chain and + * false otherwise. + * + * @param[in] the_chain is the chain to be operated upon. + * + * @return This function returns true if there is only one node on + * @a the_chain and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Has_only_one_node( + const Chain_Control *the_chain +) +{ + return _Chain_Immutable_first( the_chain ) + == _Chain_Immutable_last( the_chain ); +} + +/** @brief Is this Node the Chain Head + * + * This function returns true if @a the_node is the head of the_chain and + * false otherwise. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to check for being the Chain Head. + * + * @return This function returns true if @a the_node is the head of + * @a the_chain and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Is_head( + Chain_Control *the_chain, + const Chain_Node *the_node +) +{ + return (the_node == _Chain_Head(the_chain)); +} + +/** @brief Is this Node the Chail Tail + * + * This function returns true if the_node is the tail of the_chain and + * false otherwise. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to check for being the Chain Tail. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Is_tail( + Chain_Control *the_chain, + const Chain_Node *the_node +) +{ + return (the_node == _Chain_Tail(the_chain)); +} + +/** @brief Initialize this Chain as Empty + * + * This routine initializes the specified chain to contain zero nodes. + * + * @param[in] the_chain is the chain to be initialized. + */ +RTEMS_INLINE_ROUTINE void _Chain_Initialize_empty( + Chain_Control *the_chain +) +{ + Chain_Node *head = _Chain_Head( the_chain ); + Chain_Node *tail = _Chain_Tail( the_chain ); + + head->next = tail; + head->previous = NULL; + tail->previous = head; +} + +/** @brief Extract this Node (unprotected) + * + * This routine extracts the_node from the chain on which it resides. + * It does NOT disable interrupts to ensure the atomicity of the + * extract operation. + * + * @param[in] the_node is the node to be extracted. + */ +RTEMS_INLINE_ROUTINE void _Chain_Extract_unprotected( + Chain_Node *the_node +) +{ + Chain_Node *next; + Chain_Node *previous; + + next = the_node->next; + previous = the_node->previous; + next->previous = previous; + previous->next = next; +} + +/** @brief Get the First Node (unprotected) + * + * This function removes the first node from the_chain and returns + * a pointer to that node. It does NOT disable interrupts to ensure + * the atomicity of the get operation. + * + * @param[in] the_chain is the chain to attempt to get the first node from. + * + * @return This method returns the first node on the chain even if it is + * the Chain Tail. + * + * @note This routine assumes that there is at least one node on the chain + * and always returns a node even if it is the Chain Tail. + */ +RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_first_unprotected( + Chain_Control *the_chain +) +{ + Chain_Node *head = _Chain_Head( the_chain ); + Chain_Node *old_first = head->next; + Chain_Node *new_first = old_first->next; + + head->next = new_first; + new_first->previous = head; + + return old_first; +} + +/** @brief Get the First Node (unprotected) + * + * This function removes the first node from the_chain and returns + * a pointer to that node. If the_chain is empty, then NULL is returned. + * + * @param[in] the_chain is the chain to attempt to get the first node from. + * + * @return This method returns the first node on the chain or NULL if the + * chain is empty. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * get operation. + */ +RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_unprotected( + Chain_Control *the_chain +) +{ + if ( !_Chain_Is_empty(the_chain)) + return _Chain_Get_first_unprotected(the_chain); + else + return NULL; +} + +/** @brief Insert a Node (unprotected) + * + * This routine inserts the_node on a chain immediately following + * after_node. + * + * @param[in] after_node is the node which will precede @a the_node on the + * chain. + * @param[in] the_node is the node to be inserted. + * + * @note It does NOT disable interrupts to ensure the atomicity + * of the extract operation. + */ +RTEMS_INLINE_ROUTINE void _Chain_Insert_unprotected( + Chain_Node *after_node, + Chain_Node *the_node +) +{ + Chain_Node *before_node; + + the_node->previous = after_node; + before_node = after_node->next; + after_node->next = the_node; + the_node->next = before_node; + before_node->previous = the_node; +} + +/** @brief Append a Node (unprotected) + * + * This routine appends the_node onto the end of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be appended. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * append operation. + */ +RTEMS_INLINE_ROUTINE void _Chain_Append_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + Chain_Node *tail = _Chain_Tail( the_chain ); + Chain_Node *old_last = tail->previous; + + the_node->next = tail; + tail->previous = the_node; + old_last->next = the_node; + the_node->previous = old_last; +} + +/** @brief Prepend a Node (unprotected) + * + * This routine prepends the_node onto the front of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be prepended. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * prepend operation. + */ +RTEMS_INLINE_ROUTINE void _Chain_Prepend_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + _Chain_Insert_unprotected(_Chain_Head(the_chain), the_node); +} + +/** @brief Prepend a Node (protected) + * + * This routine prepends the_node onto the front of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be prepended. + * + * @note It disables interrupts to ensure the atomicity of the + * prepend operation. + */ +RTEMS_INLINE_ROUTINE void _Chain_Prepend( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + _Chain_Insert(_Chain_Head(the_chain), the_node); +} + +/** + * @brief Append a node and check if the chain was empty before (unprotected). + * + * This routine appends the_node onto the end of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be appended. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * append operation. + * + * @retval true The chain was empty before. + * @retval false The chain contained at least one node before. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Append_with_empty_check_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + bool was_empty = _Chain_Is_empty( the_chain ); + + _Chain_Append_unprotected( the_chain, the_node ); + + return was_empty; +} + +/** + * @brief Prepend a node and check if the chain was empty before (unprotected). + * + * This routine prepends the_node onto the front of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be prepended. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * prepend operation. + * + * @retval true The chain was empty before. + * @retval false The chain contained at least one node before. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Prepend_with_empty_check_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + bool was_empty = _Chain_Is_empty( the_chain ); + + _Chain_Prepend_unprotected( the_chain, the_node ); + + return was_empty; +} + +/** + * @brief Get the first node and check if the chain is empty afterwards + * (unprotected). + * + * This function removes the first node from the_chain and returns + * a pointer to that node in @a the_node. If the_chain is empty, then NULL is + * returned. + * + * @param[in] the_chain is the chain to attempt to get the first node from. + * @param[out] the_node is the first node on the chain or NULL if the chain is + * empty. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * get operation. + * + * @retval true The chain is empty now. + * @retval false The chain contains at least one node now. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Get_with_empty_check_unprotected( + Chain_Control *the_chain, + Chain_Node **the_node +) +{ + bool is_empty_now = true; + Chain_Node *head = _Chain_Head( the_chain ); + Chain_Node *tail = _Chain_Tail( the_chain ); + Chain_Node *old_first = head->next; + + if ( old_first != tail ) { + Chain_Node *new_first = old_first->next; + + head->next = new_first; + new_first->previous = head; + + *the_node = old_first; + + is_empty_now = new_first == tail; + } else + *the_node = NULL; + + return is_empty_now; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/corebarrier.inl b/cpukit/score/inline/rtems/score/corebarrier.inl new file mode 100644 index 0000000000..a1e56fc221 --- /dev/null +++ b/cpukit/score/inline/rtems/score/corebarrier.inl @@ -0,0 +1,66 @@ +/** + * @file rtems/score/corebarrier.inl + * + * This include file contains all of the inlined routines associated + * with the SuperCore barrier. + */ + +/* + * COPYRIGHT (c) 1989-2006. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_COREBARRIER_H +# error "Never use <rtems/score/corebarrier.inl> directly; include <rtems/score/corebarrier.h> instead." +#endif + +#ifndef _RTEMS_SCORE_COREBARRIER_INL +#define _RTEMS_SCORE_COREBARRIER_INL + +/** + * @addtogroup ScoreBarrier + * @{ + */ + +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> + +/** + * This function returns true if the automatic release attribute is + * enabled in the @a attribute_set and false otherwise. + * + * @param[in] the_attribute is the attribute set to test + * @return true if the priority attribute is enabled + */ +RTEMS_INLINE_ROUTINE bool _CORE_barrier_Is_automatic( + CORE_barrier_Attributes *the_attribute +) +{ + return + (the_attribute->discipline == CORE_BARRIER_AUTOMATIC_RELEASE); +} + +/** + * This routine returns the number of threads currently waiting at the barrier. + * + * @param[in] the_barrier is the barrier to obtain the number of blocked + * threads for + * @return the current count of this barrier + */ +RTEMS_INLINE_ROUTINE uint32_t _CORE_barrier_Get_number_of_waiting_threads( + CORE_barrier_Control *the_barrier +) +{ + return the_barrier->number_of_waiting_threads; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/coremsg.inl b/cpukit/score/inline/rtems/score/coremsg.inl new file mode 100644 index 0000000000..5ec313af9a --- /dev/null +++ b/cpukit/score/inline/rtems/score/coremsg.inl @@ -0,0 +1,263 @@ +/** + * @file rtems/score/coremsg.inl + * + * This include file contains the static inline implementation of all + * inlined routines in the Core Message Handler. + */ + +/* + * COPYRIGHT (c) 1989-2009. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_COREMSG_H +# error "Never use <rtems/score/coremsg.inl> directly; include <rtems/score/coremsg.h> instead." +#endif + +#ifndef _RTEMS_SCORE_COREMSG_INL +#define _RTEMS_SCORE_COREMSG_INL + +/** + * @addtogroup ScoreMessageQueue + * @{ + */ + +#include <string.h> /* needed for memcpy */ + +/** + * This routine sends a message to the end of the specified message queue. + */ +RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Send( + CORE_message_queue_Control *the_message_queue, + const void *buffer, + size_t size, + Objects_Id id, + CORE_message_queue_API_mp_support_callout api_message_queue_mp_support, + bool wait, + Watchdog_Interval timeout +) +{ + return _CORE_message_queue_Submit( + the_message_queue, + buffer, + size, + id, +#if defined(RTEMS_MULTIPROCESSING) + api_message_queue_mp_support, +#else + NULL, +#endif + CORE_MESSAGE_QUEUE_SEND_REQUEST, + wait, /* sender may block */ + timeout /* timeout interval */ + ); +} + +/** + * This routine sends a message to the front of the specified message queue. + */ +RTEMS_INLINE_ROUTINE CORE_message_queue_Status _CORE_message_queue_Urgent( + CORE_message_queue_Control *the_message_queue, + const void *buffer, + size_t size, + Objects_Id id, + CORE_message_queue_API_mp_support_callout api_message_queue_mp_support, + bool wait, + Watchdog_Interval timeout +) +{ + return _CORE_message_queue_Submit( + the_message_queue, + buffer, + size, + id, +#if defined(RTEMS_MULTIPROCESSING) + api_message_queue_mp_support, +#else + NULL, +#endif + CORE_MESSAGE_QUEUE_URGENT_REQUEST, + wait, /* sender may block */ + timeout /* timeout interval */ + ); +} + +/** + * This routine copies the contents of the source message buffer + * to the destination message buffer. + */ +RTEMS_INLINE_ROUTINE void _CORE_message_queue_Copy_buffer ( + const void *source, + void *destination, + size_t size +) +{ + memcpy(destination, source, size); +} + +/** + * This function allocates a message buffer from the inactive + * message buffer chain. + */ +RTEMS_INLINE_ROUTINE CORE_message_queue_Buffer_control * +_CORE_message_queue_Allocate_message_buffer ( + CORE_message_queue_Control *the_message_queue +) +{ + return (CORE_message_queue_Buffer_control *) + _Chain_Get( &the_message_queue->Inactive_messages ); +} + +/** + * This routine frees a message buffer to the inactive + * message buffer chain. + */ +RTEMS_INLINE_ROUTINE void _CORE_message_queue_Free_message_buffer ( + CORE_message_queue_Control *the_message_queue, + CORE_message_queue_Buffer_control *the_message +) +{ + _Chain_Append( &the_message_queue->Inactive_messages, &the_message->Node ); +} + +/** + * This function returns the priority of @a the_message. + * + * NOTE: It encapsulates the optional behavior that message priority is + * disabled if no API requires it. + */ +RTEMS_INLINE_ROUTINE int _CORE_message_queue_Get_message_priority ( + CORE_message_queue_Buffer_control *the_message +) +{ + #if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY) + return the_message->priority; + #else + return 0; + #endif +} + +/** + * This function sets the priority of @a the_message. + * + * NOTE: It encapsulates the optional behavior that message priority is + * disabled if no API requires it. + */ +RTEMS_INLINE_ROUTINE void _CORE_message_queue_Set_message_priority ( + CORE_message_queue_Buffer_control *the_message, + int priority +) +{ + #if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY) + the_message->priority = priority; + #endif +} + +/** + * This function removes the first message from the_message_queue + * and returns a pointer to it. + */ +RTEMS_INLINE_ROUTINE + CORE_message_queue_Buffer_control *_CORE_message_queue_Get_pending_message ( + CORE_message_queue_Control *the_message_queue +) +{ + return (CORE_message_queue_Buffer_control *) + _Chain_Get_unprotected( &the_message_queue->Pending_messages ); +} + +/** + * This function returns true if the priority attribute is + * enabled in the attribute_set and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _CORE_message_queue_Is_priority( + CORE_message_queue_Attributes *the_attribute +) +{ + return + (the_attribute->discipline == CORE_MESSAGE_QUEUE_DISCIPLINES_PRIORITY); +} + +/** + * This routine places the_message at the rear of the outstanding + * messages on the_message_queue. + */ +RTEMS_INLINE_ROUTINE void _CORE_message_queue_Append_unprotected ( + CORE_message_queue_Control *the_message_queue, + CORE_message_queue_Buffer_control *the_message +) +{ + _Chain_Append_unprotected( + &the_message_queue->Pending_messages, + &the_message->Node + ); +} + +/** + * This routine places the_message at the front of the outstanding + * messages on the_message_queue. + */ +RTEMS_INLINE_ROUTINE void _CORE_message_queue_Prepend_unprotected ( + CORE_message_queue_Control *the_message_queue, + CORE_message_queue_Buffer_control *the_message +) +{ + _Chain_Prepend_unprotected( + &the_message_queue->Pending_messages, + &the_message->Node + ); +} + +/** + * This function returns true if the_message_queue is true and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _CORE_message_queue_Is_null ( + CORE_message_queue_Control *the_message_queue +) +{ + return ( the_message_queue == NULL ); +} + +#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION) + /** + * This function returns true if notification is enabled on this message + * queue and false otherwise. + */ + RTEMS_INLINE_ROUTINE bool _CORE_message_queue_Is_notify_enabled ( + CORE_message_queue_Control *the_message_queue + ) + { + return (the_message_queue->notify_handler != NULL); + } +#endif + +/** + * This routine initializes the notification information for + * @a the_message_queue. + */ +#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION) + RTEMS_INLINE_ROUTINE void _CORE_message_queue_Set_notify ( + CORE_message_queue_Control *the_message_queue, + CORE_message_queue_Notify_Handler the_handler, + void *the_argument + ) + { + the_message_queue->notify_handler = the_handler; + the_message_queue->notify_argument = the_argument; + } +#else + /* turn it into nothing if not enabled */ + #define _CORE_message_queue_Set_notify( \ + the_message_queue, the_handler, the_argument ) +#endif + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/coremutex.inl b/cpukit/score/inline/rtems/score/coremutex.inl new file mode 100644 index 0000000000..f6f666159b --- /dev/null +++ b/cpukit/score/inline/rtems/score/coremutex.inl @@ -0,0 +1,229 @@ +/** + * @file rtems/score/coremutex.inl + * + * This include file contains all of the inlined routines associated + * with the CORE mutexes. + */ + +/* + * COPYRIGHT (c) 1989-2009. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_COREMUTEX_H +# error "Never use <rtems/score/coremutex.inl> directly; include <rtems/score/coremutex.h> instead." +#endif + +#ifndef _RTEMS_SCORE_COREMUTEX_INL +#define _RTEMS_SCORE_COREMUTEX_INL + +/** + * @addtogroup ScoreMutex + * @{ + */ + +/** + * @brief Is Mutex Locked + * + * This routine returns true if the mutex specified is locked and false + * otherwise. + * + * @param[in] the_mutex is the mutex to check + * + * @return This method returns true if the mutex is locked. + */ +RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked( + CORE_mutex_Control *the_mutex +) +{ + return the_mutex->lock == CORE_MUTEX_LOCKED; +} + +/** + * @brief Does Core Mutex Use FIFO Blocking + * + * This routine returns true if the mutex's wait discipline is FIFO and false + * otherwise. + * + * @param[in] the_attribute is the attribute set of the mutex + * + * @return This method returns true if the mutex is using FIFO blocking order. + */ +RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo( + CORE_mutex_Attributes *the_attribute +) +{ + return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO; +} + +/** + * @brief Doex Core Mutex Use Priority Blocking + * + * This routine returns true if the mutex's wait discipline is PRIORITY and + * false otherwise. + * + * @param[in] the_attribute is the attribute set of the mutex + * + * @return This method returns true if the mutex is using + * priority blocking order. + */ +RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority( + CORE_mutex_Attributes *the_attribute +) +{ + return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY; +} + +/** + * @brief Does Mutex Use Priority Inheritance + * + * This routine returns true if the mutex's wait discipline is + * INHERIT_PRIORITY and false otherwise. + * + * @param[in] the_attribute is the attribute set of the mutex + * + * @return This method returns true if the mutex is using priority + * inheritance. + */ +RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority( + CORE_mutex_Attributes *the_attribute +) +{ + return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT; +} + +/** + * @brief Does Mutex Use Priority Ceiling + * + * This routine returns true if the mutex's wait discipline is + * PRIORITY_CEILING and false otherwise. + * + * @param[in] the_attribute is the attribute set of the mutex + * @return This method returns true if the mutex is using priority + * ceiling. + */ +RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling( + CORE_mutex_Attributes *the_attribute +) +{ + return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING; +} + +/* + * Seize Mutex with Quick Success Path + * + * NOTE: There is no MACRO version of this routine. A body is in + * coremutexseize.c that is duplicated from the .inl by hand. + * + * NOTE: The Doxygen for this routine is in the .h file. + */ + +RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body( + CORE_mutex_Control *the_mutex, + ISR_Level *level_p +) +{ + Thread_Control *executing; + + /* disabled when you get here */ + + executing = _Thread_Executing; + executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL; + if ( !_CORE_mutex_Is_locked( the_mutex ) ) { + the_mutex->lock = CORE_MUTEX_LOCKED; + the_mutex->holder = executing; + the_mutex->holder_id = executing->Object.id; + the_mutex->nest_count = 1; + if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){ + +#ifdef __RTEMS_STRICT_ORDER_MUTEX__ + _Chain_Prepend_unprotected( &executing->lock_mutex, + &the_mutex->queue.lock_queue ); + the_mutex->queue.priority_before = executing->current_priority; +#endif + + executing->resource_count++; + } + + if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { + _ISR_Enable( *level_p ); + return 0; + } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING + * + * we possibly bump the priority of the current holder -- which + * happens to be _Thread_Executing. + */ + { + Priority_Control ceiling; + Priority_Control current; + + ceiling = the_mutex->Attributes.priority_ceiling; + current = executing->current_priority; + if ( current == ceiling ) { + _ISR_Enable( *level_p ); + return 0; + } + + if ( current > ceiling ) { + _Thread_Disable_dispatch(); + _ISR_Enable( *level_p ); + _Thread_Change_priority( + the_mutex->holder, + the_mutex->Attributes.priority_ceiling, + false + ); + _Thread_Enable_dispatch(); + return 0; + } + /* if ( current < ceiling ) */ { + executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED; + the_mutex->lock = CORE_MUTEX_UNLOCKED; + the_mutex->nest_count = 0; /* undo locking above */ + executing->resource_count--; /* undo locking above */ + _ISR_Enable( *level_p ); + return 0; + } + } + return 0; + } + + /* + * At this point, we know the mutex was not available. If this thread + * is the thread that has locked the mutex, let's see if we are allowed + * to nest access. + */ + if ( _Thread_Is_executing( the_mutex->holder ) ) { + switch ( the_mutex->Attributes.lock_nesting_behavior ) { + case CORE_MUTEX_NESTING_ACQUIRES: + the_mutex->nest_count++; + _ISR_Enable( *level_p ); + return 0; + #if defined(RTEMS_POSIX_API) + case CORE_MUTEX_NESTING_IS_ERROR: + executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED; + _ISR_Enable( *level_p ); + return 0; + #endif + case CORE_MUTEX_NESTING_BLOCKS: + break; + } + } + + /* + * The mutex is not available and the caller must deal with the possibility + * of blocking. + */ + return 1; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/corerwlock.inl b/cpukit/score/inline/rtems/score/corerwlock.inl new file mode 100644 index 0000000000..b23ef32015 --- /dev/null +++ b/cpukit/score/inline/rtems/score/corerwlock.inl @@ -0,0 +1,51 @@ +/** + * @file rtems/score/corerwlock.inl + * + * This include file contains all of the inlined routines associated + * with the SuperCore RWLock. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_CORERWLOCK_H +# error "Never use <rtems/score/corerwlock.inl> directly; include <rtems/score/corerwlock.h> instead." +#endif + +#ifndef _RTEMS_SCORE_CORERWLOCK_INL +#define _RTEMS_SCORE_CORERWLOCK_INL + +/** + * @addtogroup ScoreRWLock + * @{ + */ + +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> + +/** + * + * This method is used to initialize core rwlock attributes. + * + * @param[in] the_attributes pointer to the attributes to initialize. + */ +RTEMS_INLINE_ROUTINE void _CORE_RWLock_Initialize_attributes( + CORE_RWLock_Attributes *the_attributes +) +{ + the_attributes->XXX = 0; +} + + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/coresem.inl b/cpukit/score/inline/rtems/score/coresem.inl new file mode 100644 index 0000000000..3608b2d91b --- /dev/null +++ b/cpukit/score/inline/rtems/score/coresem.inl @@ -0,0 +1,115 @@ +/** + * @file rtems/score/coresem.inl + * + * This include file contains all of the inlined routines associated + * with the SuperCore semaphore. + */ + +/* + * COPYRIGHT (c) 1989-2006. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_CORESEM_H +# error "Never use <rtems/score/coresem.inl> directly; include <rtems/score/coresem.h> instead." +#endif + +#ifndef _RTEMS_SCORE_CORESEM_INL +#define _RTEMS_SCORE_CORESEM_INL + +/** + * @addtogroup ScoreSemaphore + * @{ + */ + +#include <rtems/score/thread.h> +#include <rtems/score/threadq.h> + +/** + * This function returns true if the priority attribute is + * enabled in the @a attribute_set and false otherwise. + * + * @param[in] the_attribute is the attribute set to test + * @return true if the priority attribute is enabled + */ +RTEMS_INLINE_ROUTINE bool _CORE_semaphore_Is_priority( + CORE_semaphore_Attributes *the_attribute +) +{ + return ( the_attribute->discipline == CORE_SEMAPHORE_DISCIPLINES_PRIORITY ); +} + +/** + * This routine returns the current count associated with the semaphore. + * + * @param[in] the_semaphore is the semaphore to obtain the count of + * @return the current count of this semaphore + */ +RTEMS_INLINE_ROUTINE uint32_t _CORE_semaphore_Get_count( + CORE_semaphore_Control *the_semaphore +) +{ + return the_semaphore->count; +} + +/** + * This routine attempts to receive a unit from the_semaphore. + * If a unit is available or if the wait flag is false, then the routine + * returns. Otherwise, the calling task is blocked until a unit becomes + * available. + * + * @param[in] the_semaphore is the semaphore to obtain + * @param[in] id is the Id of the owning API level Semaphore object + * @param[in] wait is true if the thread is willing to wait + * @param[in] timeout is the maximum number of ticks to block + * @param[in] level_p is a temporary variable used to contain the ISR + * disable level cookie + * + * @note There is currently no MACRO version of this routine. + */ +RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize_isr_disable( + CORE_semaphore_Control *the_semaphore, + Objects_Id id, + bool wait, + Watchdog_Interval timeout, + ISR_Level *level_p +) +{ + Thread_Control *executing; + + /* disabled when you get here */ + + executing = _Thread_Executing; + executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL; + if ( the_semaphore->count != 0 ) { + the_semaphore->count -= 1; + _ISR_Enable( *level_p ); + return; + } + + if ( !wait ) { + _ISR_Enable( *level_p ); + executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT; + return; + } + + _Thread_Disable_dispatch(); + _Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue ); + executing->Wait.queue = &the_semaphore->Wait_queue; + executing->Wait.id = id; + _ISR_Enable( *level_p ); + + _Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout ); + _Thread_Enable_dispatch(); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/corespinlock.inl b/cpukit/score/inline/rtems/score/corespinlock.inl new file mode 100644 index 0000000000..05e3408742 --- /dev/null +++ b/cpukit/score/inline/rtems/score/corespinlock.inl @@ -0,0 +1,63 @@ +/** + * @file rtems/score/corespinlock.inl + * + * This include file contains all of the inlined routines associated + * with the SuperCore spinlock. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_CORESPINLOCK_H +# error "Never use <rtems/score/corespinlock.inl> directly; include <rtems/score/corespinlock.h> instead." +#endif + +#ifndef _RTEMS_SCORE_CORESPINLOCK_INL +#define _RTEMS_SCORE_CORESPINLOCK_INL + +/** + * @addtogroup ScoreSpinlock + * @{ + */ + +/** + * + * This method is used to initialize core spinlock attributes. + * + * @param[in] the_attributes pointer to the attributes to initialize. + */ +RTEMS_INLINE_ROUTINE void _CORE_spinlock_Initialize_attributes( + CORE_spinlock_Attributes *the_attributes +) +{ + the_attributes->XXX = 0; +} + +/** + * + * This method is used to determine if the spinlock is available or not. + * + * @param[in] the_spinlock will be checked + * + * @return This method will return true if the spinlock is busy + * and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _CORE_spinlock_Is_busy( + CORE_spinlock_Control *the_spinlock +) +{ + return (the_spinlock->users != 0); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/heap.inl b/cpukit/score/inline/rtems/score/heap.inl new file mode 100644 index 0000000000..50fb16a55c --- /dev/null +++ b/cpukit/score/inline/rtems/score/heap.inl @@ -0,0 +1,243 @@ +/** + * @file + * + * @ingroup ScoreHeap + * + * @brief Heap Handler API. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_HEAP_H +# error "Never use <rtems/score/heap.inl> directly; include <rtems/score/heap.h> instead." +#endif + +#ifndef _RTEMS_SCORE_HEAP_INL +#define _RTEMS_SCORE_HEAP_INL + +#include <rtems/score/address.h> + +/** + * @addtogroup ScoreHeap + * + * @{ + */ + +RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_head( Heap_Control *heap ) +{ + return &heap->free_list; +} + +RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_tail( Heap_Control *heap ) +{ + return &heap->free_list; +} + +RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_first( Heap_Control *heap ) +{ + return _Heap_Free_list_head(heap)->next; +} + +RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_last( Heap_Control *heap ) +{ + return _Heap_Free_list_tail(heap)->prev; +} + +RTEMS_INLINE_ROUTINE void _Heap_Free_list_remove( Heap_Block *block ) +{ + Heap_Block *next = block->next; + Heap_Block *prev = block->prev; + + prev->next = next; + next->prev = prev; +} + +RTEMS_INLINE_ROUTINE void _Heap_Free_list_replace( + Heap_Block *old_block, + Heap_Block *new_block +) +{ + Heap_Block *next = old_block->next; + Heap_Block *prev = old_block->prev; + + new_block->next = next; + new_block->prev = prev; + + next->prev = new_block; + prev->next = new_block; +} + +RTEMS_INLINE_ROUTINE void _Heap_Free_list_insert_after( + Heap_Block *block_before, + Heap_Block *new_block +) +{ + Heap_Block *next = block_before->next; + + new_block->next = next; + new_block->prev = block_before; + block_before->next = new_block; + next->prev = new_block; +} + +RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned( + uintptr_t value, + uintptr_t alignment +) +{ + return (value % alignment) == 0; +} + +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_up( + uintptr_t value, + uintptr_t alignment +) +{ + uintptr_t remainder = value % alignment; + + if ( remainder != 0 ) { + return value - remainder + alignment; + } else { + return value; + } +} + +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_down( + uintptr_t value, + uintptr_t alignment +) +{ + return value - (value % alignment); +} + +/** + * @brief Returns the block which is @a offset away from @a block. + */ +RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_at( + const Heap_Block *block, + uintptr_t offset +) +{ + return (Heap_Block *) ((uintptr_t) block + offset); +} + +RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Prev_block( + const Heap_Block *block +) +{ + return (Heap_Block *) ((uintptr_t) block - block->prev_size); +} + +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Alloc_area_of_block( + const Heap_Block *block +) +{ + return (uintptr_t) block + HEAP_BLOCK_HEADER_SIZE; +} + +RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_of_alloc_area( + uintptr_t alloc_begin, + uintptr_t page_size +) +{ + return (Heap_Block *) (_Heap_Align_down( alloc_begin, page_size ) + - HEAP_BLOCK_HEADER_SIZE); +} + +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Block_size( const Heap_Block *block ) +{ + return block->size_and_flag & ~HEAP_PREV_BLOCK_USED; +} + +RTEMS_INLINE_ROUTINE void _Heap_Block_set_size( + Heap_Block *block, + uintptr_t size +) +{ + uintptr_t flag = block->size_and_flag & HEAP_PREV_BLOCK_USED; + + block->size_and_flag = size | flag; +} + +RTEMS_INLINE_ROUTINE bool _Heap_Is_prev_used( const Heap_Block *block ) +{ + return block->size_and_flag & HEAP_PREV_BLOCK_USED; +} + +RTEMS_INLINE_ROUTINE bool _Heap_Is_used( + const Heap_Block *block +) +{ + const Heap_Block *const next_block = + _Heap_Block_at( block, _Heap_Block_size( block ) ); + + return _Heap_Is_prev_used( next_block ); +} + +RTEMS_INLINE_ROUTINE bool _Heap_Is_free( + const Heap_Block *block +) +{ + return !_Heap_Is_used( block ); +} + +RTEMS_INLINE_ROUTINE bool _Heap_Is_block_in_heap( + const Heap_Control *heap, + const Heap_Block *block +) +{ + return (uintptr_t) block >= (uintptr_t) heap->first_block + && (uintptr_t) block <= (uintptr_t) heap->last_block; +} + +/** + * @brief Sets the size of the last block for heap @a heap. + * + * The next block of the last block will be the first block. Since the first + * block indicates that the previous block is used, this ensures that the last + * block appears as used for the _Heap_Is_used() and _Heap_Is_free() functions. + * + * This feature will be used to terminate the scattered heap area list. See + * also _Heap_Extend(). + */ +RTEMS_INLINE_ROUTINE void _Heap_Set_last_block_size( Heap_Control *heap ) +{ + _Heap_Block_set_size( + heap->last_block, + (uintptr_t) heap->first_block - (uintptr_t) heap->last_block + ); +} + +/** + * @brief Returns the size of the allocatable area in bytes. + * + * This value is an integral multiple of the page size. + */ +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Get_size( const Heap_Control *heap ) +{ + return heap->stats.size; +} + +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Max( uintptr_t a, uintptr_t b ) +{ + return a > b ? a : b; +} + +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Min( uintptr_t a, uintptr_t b ) +{ + return a < b ? a : b; +} + +/** @} */ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/isr.inl b/cpukit/score/inline/rtems/score/isr.inl new file mode 100644 index 0000000000..605dfeeab5 --- /dev/null +++ b/cpukit/score/inline/rtems/score/isr.inl @@ -0,0 +1,58 @@ +/** + * @file rtems/score/isr.inl + * + * This include file contains the static implementation of all + * inlined routines in the Interrupt Handler. + */ + +/* + * COPYRIGHT (c) 1989-2004. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_ISR_H +# error "Never use <rtems/score/isr.inl> directly; include <rtems/score/isr.h> instead." +#endif + +#ifndef _RTEMS_SCORE_ISR_INL +#define _RTEMS_SCORE_ISR_INL + +/** + * @addtogroup ScoreISR + * @{ + */ + +/** + * This function returns true if the vector is a valid vector number + * for this processor and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _ISR_Is_vector_number_valid ( + uint32_t vector +) +{ + return ( vector <= CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER ); +} + +/** + * This function returns true if handler is the entry point of a valid + * use interrupt service routine and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _ISR_Is_valid_user_handler ( + void *handler +) +{ + return (handler != NULL); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/mppkt.inl b/cpukit/score/inline/rtems/score/mppkt.inl new file mode 100644 index 0000000000..593e8eebb1 --- /dev/null +++ b/cpukit/score/inline/rtems/score/mppkt.inl @@ -0,0 +1,61 @@ +/** + * @file rtems/score/mppkt.inl + * + * This package is the implementation of the Packet Handler + * routines which are inlined. + */ + +/* + * COPYRIGHT (c) 1989-2004. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_MPPKT_H +# error "Never use <rtems/score/mppkt.inl> directly; include <rtems/score/mppkt.h> instead." +#endif + +#ifndef _RTEMS_SCORE_MPPKT_INL +#define _RTEMS_SCORE_MPPKT_INL + +/** + * @addtogroup ScoreMPPacket + * @{ + */ + +/** + * This function returns true if the the_packet_class is valid, + * and false otherwise. + * + * @note Check for lower bounds (MP_PACKET_CLASSES_FIRST ) is unnecessary + * because this enum starts at lower bound of zero. + */ + +RTEMS_INLINE_ROUTINE bool _Mp_packet_Is_valid_packet_class ( + MP_packet_Classes the_packet_class +) +{ + return ( the_packet_class <= MP_PACKET_CLASSES_LAST ); +} + +/** + * This function returns true if the the_packet_class is null, + * and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Mp_packet_Is_null ( + MP_packet_Prefix *the_packet +) +{ + return the_packet == NULL; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/object.inl b/cpukit/score/inline/rtems/score/object.inl new file mode 100644 index 0000000000..d4d39acac6 --- /dev/null +++ b/cpukit/score/inline/rtems/score/object.inl @@ -0,0 +1,357 @@ +/** + * @file rtems/score/object.inl + */ + +/* + * + * This include file contains the static inline implementation of all + * of the inlined routines in the Object Handler. + * + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_OBJECT_H +# error "Never use <rtems/score/object.inl> directly; include <rtems/score/object.h> instead." +#endif + +#ifndef _RTEMS_SCORE_OBJECT_INL +#define _RTEMS_SCORE_OBJECT_INL + +/** + * This function builds an object's id from the processor node and index + * values specified. + * + * @param[in] the_api indicates the API associated with this Id. + * @param[in] the_class indicates the class of object. + * It is specific to @a the_api. + * @param[in] node is the node where this object resides. + * @param[in] index is the instance number of this object. + * + * @return This method returns an object Id constructed from the arguments. + */ +RTEMS_INLINE_ROUTINE Objects_Id _Objects_Build_id( + Objects_APIs the_api, + uint32_t the_class, + uint32_t node, + uint32_t index +) +{ + return (( (Objects_Id) the_api ) << OBJECTS_API_START_BIT) | + (( (Objects_Id) the_class ) << OBJECTS_CLASS_START_BIT) | + #if !defined(RTEMS_USE_16_BIT_OBJECT) + (( (Objects_Id) node ) << OBJECTS_NODE_START_BIT) | + #endif + (( (Objects_Id) index ) << OBJECTS_INDEX_START_BIT); +} + +/** + * This function returns the API portion of the ID. + * + * @param[in] id is the object Id to be processed. + * + * @return This method returns an object Id constructed from the arguments. + */ +RTEMS_INLINE_ROUTINE Objects_APIs _Objects_Get_API( + Objects_Id id +) +{ + return (Objects_APIs) ((id >> OBJECTS_API_START_BIT) & OBJECTS_API_VALID_BITS); +} + +/** + * This function returns the class portion of the ID. + * + * @param[in] id is the object Id to be processed + */ +RTEMS_INLINE_ROUTINE uint32_t _Objects_Get_class( + Objects_Id id +) +{ + return (uint32_t) + ((id >> OBJECTS_CLASS_START_BIT) & OBJECTS_CLASS_VALID_BITS); +} + +/** + * This function returns the node portion of the ID. + * + * @param[in] id is the object Id to be processed + * + * @return This method returns the node portion of an object ID. + */ +RTEMS_INLINE_ROUTINE uint32_t _Objects_Get_node( + Objects_Id id +) +{ + /* + * If using 16-bit Ids, then there is no node field and it MUST + * be a single processor system. + */ + #if defined(RTEMS_USE_16_BIT_OBJECT) + return 1; + #else + return (id >> OBJECTS_NODE_START_BIT) & OBJECTS_NODE_VALID_BITS; + #endif +} + +/** + * This function returns the index portion of the ID. + * + * @param[in] id is the Id to be processed + * + * @return This method returns the class portion of the specified object ID. + */ +RTEMS_INLINE_ROUTINE Objects_Maximum _Objects_Get_index( + Objects_Id id +) +{ + return + (Objects_Maximum)((id >> OBJECTS_INDEX_START_BIT) & + OBJECTS_INDEX_VALID_BITS); +} + +/** + * This function returns true if the api is valid. + * + * @param[in] the_api is the api portion of an object ID. + * + * @return This method returns true if the specified api value is valid + * and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Objects_Is_api_valid( + uint32_t the_api +) +{ + if ( !the_api || the_api > OBJECTS_APIS_LAST ) + return false; + return true; +} + +/** + * This function returns true if the node is of the local object, and + * false otherwise. + * + * @param[in] node is the node number and corresponds to the node number + * portion of an object ID. + * + * @return This method returns true if the specified node is the local node + * and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Objects_Is_local_node( + uint32_t node +) +{ + return ( node == _Objects_Local_node ); +} + +/** + * This function returns true if the id is of a local object, and + * false otherwise. + * + * @param[in] id is an object ID + * + * @return This method returns true if the specified object Id is local + * and false otherwise. + * + * @note On a single processor configuration, this always returns true. + */ +RTEMS_INLINE_ROUTINE bool _Objects_Is_local_id( +#if defined(RTEMS_MULTIPROCESSING) + Objects_Id id +#else + Objects_Id id __attribute__((unused)) +#endif +) +{ +#if defined(RTEMS_MULTIPROCESSING) + return _Objects_Is_local_node( _Objects_Get_node(id) ); +#else + return true; +#endif +} + +/** + * This function returns true if left and right are equal, + * and false otherwise. + * + * @param[in] left is the Id on the left hand side of the comparison + * @param[in] right is the Id on the right hand side of the comparison + * + * @return This method returns true if the specified object IDs are equal + * and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Objects_Are_ids_equal( + Objects_Id left, + Objects_Id right +) +{ + return ( left == right ); +} + +/** + * This function returns a pointer to the local_table object + * referenced by the index. + * + * @param[in] information points to an Object Information Table + * @param[in] index is the index of the object the caller wants to access + * + * @return This method returns a pointer to a local object or NULL if the + * index is invalid and RTEMS_DEBUG is enabled. + */ +RTEMS_INLINE_ROUTINE Objects_Control *_Objects_Get_local_object( + Objects_Information *information, + uint16_t index +) +{ + /* + * This routine is ONLY to be called from places in the code + * where the Id is known to be good. Therefore, this should NOT + * occur in normal situations. + */ + #if defined(RTEMS_DEBUG) + if ( index > information->maximum ) + return NULL; + #endif + return information->local_table[ index ]; +} + +/** + * This function sets the pointer to the local_table object + * referenced by the index. + * + * @param[in] information points to an Object Information Table + * @param[in] index is the index of the object the caller wants to access + * @param[in] the_object is the local object pointer + * + * @note This routine is ONLY to be called in places where the + * index portion of the Id is known to be good. This is + * OK since it is normally called from object create/init + * or delete/destroy operations. + */ + +RTEMS_INLINE_ROUTINE void _Objects_Set_local_object( + Objects_Information *information, + uint32_t index, + Objects_Control *the_object +) +{ + /* + * This routine is ONLY to be called from places in the code + * where the Id is known to be good. Therefore, this should NOT + * occur in normal situations. + */ + #if defined(RTEMS_DEBUG) + if ( index > information->maximum ) + return; + #endif + + information->local_table[ index ] = the_object; +} + +/** + * This function sets the pointer to the local_table object + * referenced by the index to a NULL so the object Id is invalid + * after this call. + * + * @param[in] information points to an Object Information Table + * @param[in] the_object is the local object pointer + * + * @note This routine is ONLY to be called in places where the + * index portion of the Id is known to be good. This is + * OK since it is normally called from object create/init + * or delete/destroy operations. + */ + +RTEMS_INLINE_ROUTINE void _Objects_Invalidate_Id( + Objects_Information *information, + Objects_Control *the_object +) +{ + _Objects_Set_local_object( + information, + _Objects_Get_index( the_object->id ), + NULL + ); +} + +/** + * This function places the_object control pointer and object name + * in the Local Pointer and Local Name Tables, respectively. + * + * @param[in] information points to an Object Information Table + * @param[in] the_object is a pointer to an object + * @param[in] name is the name of the object to make accessible + */ +RTEMS_INLINE_ROUTINE void _Objects_Open( + Objects_Information *information, + Objects_Control *the_object, + Objects_Name name +) +{ + _Objects_Set_local_object( + information, + _Objects_Get_index( the_object->id ), + the_object + ); + + the_object->name = name; +} + +/** + * This function places the_object control pointer and object name + * in the Local Pointer and Local Name Tables, respectively. + * + * @param[in] information points to an Object Information Table + * @param[in] the_object is a pointer to an object + * @param[in] name is the name of the object to make accessible + */ +RTEMS_INLINE_ROUTINE void _Objects_Open_u32( + Objects_Information *information, + Objects_Control *the_object, + uint32_t name +) +{ + _Objects_Set_local_object( + information, + _Objects_Get_index( the_object->id ), + the_object + ); + + /* ASSERT: information->is_string == false */ + the_object->name.name_u32 = name; +} + +/** + * This function places the_object control pointer and object name + * in the Local Pointer and Local Name Tables, respectively. + * + * @param[in] information points to an Object Information Table + * @param[in] the_object is a pointer to an object + * @param[in] name is the name of the object to make accessible + */ +RTEMS_INLINE_ROUTINE void _Objects_Open_string( + Objects_Information *information, + Objects_Control *the_object, + const char *name +) +{ + _Objects_Set_local_object( + information, + _Objects_Get_index( the_object->id ), + the_object + ); + + #if defined(RTEMS_SCORE_OBJECT_ENABLE_STRING_NAMES) + /* ASSERT: information->is_string */ + the_object->name.name_p = name; + #endif +} + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/objectmp.inl b/cpukit/score/inline/rtems/score/objectmp.inl new file mode 100644 index 0000000000..53db23621a --- /dev/null +++ b/cpukit/score/inline/rtems/score/objectmp.inl @@ -0,0 +1,71 @@ +/** + * @file rtems/score/objectmp.inl + * + * This include file contains the bodies of all inlined routines + * which deal with global objects. + */ + +/* + * COPYRIGHT (c) 1989-2004. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_OBJECTMP_H +# error "Never use <rtems/score/objectmp.inl> directly; include <rtems/score/objectmp.h> instead." +#endif + +#ifndef _RTEMS_SCORE_OBJECTMP_INL +#define _RTEMS_SCORE_OBJECTMP_INL + +/** + * @addtogroup ScoreObjectMP + * @{ + */ + +/** + * This function allocates a Global Object control block. + */ + +RTEMS_INLINE_ROUTINE Objects_MP_Control *_Objects_MP_Allocate_global_object ( + void +) +{ + return (Objects_MP_Control *) + _Chain_Get( &_Objects_MP_Inactive_global_objects ); +} + +/** + * This routine deallocates a Global Object control block. + */ + +RTEMS_INLINE_ROUTINE void _Objects_MP_Free_global_object ( + Objects_MP_Control *the_object +) +{ + _Chain_Append( + &_Objects_MP_Inactive_global_objects, + &the_object->Object.Node + ); +} + +/** + * This function returns whether the global object is NULL or not. + */ + +RTEMS_INLINE_ROUTINE bool _Objects_MP_Is_null_global_object ( + Objects_MP_Control *the_object +) +{ + return( the_object == NULL ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/priority.inl b/cpukit/score/inline/rtems/score/priority.inl new file mode 100644 index 0000000000..089a81ebda --- /dev/null +++ b/cpukit/score/inline/rtems/score/priority.inl @@ -0,0 +1,53 @@ +/** + * @file rtems/score/priority.inl + * + * This file contains the static inline implementation of all inlined + * routines in the Priority Handler. + */ + +/* + * COPYRIGHT (c) 1989-2004. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_PRIORITY_H +# error "Never use <rtems/score/priority.inl> directly; include <rtems/score/priority.h> instead." +#endif + +#ifndef _RTEMS_SCORE_PRIORITY_INL +#define _RTEMS_SCORE_PRIORITY_INL + +/** + * @addtogroup ScorePriority + * @{ + */ + +/** + * This function returns true if the_priority if valid for a + * user task, and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Priority_Is_valid ( + Priority_Control the_priority +) +{ + /* + * Since PRIORITY_MINIMUM is 0 and priorities are stored unsigned, + * then checking for less than 0 is unnecessary. + */ + + return ( the_priority <= PRIORITY_MAXIMUM ); +} + + + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/prioritybitmap.inl b/cpukit/score/inline/rtems/score/prioritybitmap.inl new file mode 100644 index 0000000000..7938a38afc --- /dev/null +++ b/cpukit/score/inline/rtems/score/prioritybitmap.inl @@ -0,0 +1,193 @@ +/** + * @file rtems/score/prioritybitmap.inl + * + * This file contains the static inline implementation of all inlined + * routines in the Priority Handler bit map implementation + */ + +/* + * COPYRIGHT (c) 1989-2010. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_PRIORITYBITMAP_H +# error "Never use <rtems/score/prioritybitmap.inl> directly; include <rtems/score/prioritybitmap.h> instead." +#endif + +#ifndef _RTEMS_SCORE_PRIORITYBITMAP_INL +#define _RTEMS_SCORE_PRIORITYBITMAP_INL + +/** + * @addtogroup ScorePriority + * @{ + */ + +#include <rtems/score/bitfield.h> + +/** + * This function returns the major portion of the_priority. + */ + +RTEMS_INLINE_ROUTINE Priority_bit_map_Control _Priority_Major ( + Priority_Control the_priority +) +{ + return (Priority_bit_map_Control)( the_priority / 16 ); +} + +/** + * This function returns the minor portion of the_priority. + */ + +RTEMS_INLINE_ROUTINE Priority_bit_map_Control _Priority_Minor ( + Priority_Control the_priority +) +{ + return (Priority_bit_map_Control)( the_priority % 16 ); +} + +#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE ) + +/** + * This function returns the mask associated with the major or minor + * number passed to it. + */ + +RTEMS_INLINE_ROUTINE Priority_bit_map_Control _Priority_Mask ( + uint32_t bit_number +) +{ + return (Priority_bit_map_Control)(0x8000u >> bit_number); +} + +/** + * This function returns the mask bit inverted. + */ + +RTEMS_INLINE_ROUTINE Priority_bit_map_Control _Priority_Mask_invert ( + uint32_t mask +) +{ + return (Priority_bit_map_Control)(~mask); +} + + +/** + * This function translates the bit numbers returned by the bit scan + * of a priority bit field into something suitable for use as + * a major or minor component of a priority. + */ + +RTEMS_INLINE_ROUTINE uint32_t _Priority_Bits_index ( + uint32_t bit_number +) +{ + return bit_number; +} + +#endif + +/** + * Priority Queue implemented by bit map + */ + +/** + * This routine performs the initialization necessary for this handler. + */ + +RTEMS_INLINE_ROUTINE void _Priority_bit_map_Handler_initialization( void ) +{ + int index; + + _Priority_Major_bit_map = 0; + for ( index=0 ; index <16 ; index++ ) + _Priority_Bit_map[ index ] = 0; +} + +/** + * This routine uses the_priority_map to update the priority + * bit maps to indicate that a thread has been readied. + */ + +RTEMS_INLINE_ROUTINE void _Priority_bit_map_Add ( + Priority_bit_map_Information *the_priority_map +) +{ + *the_priority_map->minor |= the_priority_map->ready_minor; + _Priority_Major_bit_map |= the_priority_map->ready_major; +} + +/** + * This routine uses the_priority_map to update the priority + * bit maps to indicate that a thread has been removed from the + * ready state. + */ + +RTEMS_INLINE_ROUTINE void _Priority_bit_map_Remove ( + Priority_bit_map_Information *the_priority_map +) +{ + *the_priority_map->minor &= the_priority_map->block_minor; + if ( *the_priority_map->minor == 0 ) + _Priority_Major_bit_map &= the_priority_map->block_major; +} + +/** + * This function returns the priority of the highest priority + * ready thread. + */ + +RTEMS_INLINE_ROUTINE Priority_Control _Priority_bit_map_Get_highest( void ) +{ + Priority_bit_map_Control minor; + Priority_bit_map_Control major; + + _Bitfield_Find_first_bit( _Priority_Major_bit_map, major ); + _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor ); + + return (_Priority_Bits_index( major ) << 4) + + _Priority_Bits_index( minor ); +} + +/** + * This routine initializes the_priority_map so that it + * contains the information necessary to manage a thread + * at new_priority. + */ + +RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize_information( + Priority_bit_map_Information *the_priority_map, + Priority_Control new_priority +) +{ + Priority_bit_map_Control major; + Priority_bit_map_Control minor; + Priority_bit_map_Control mask; + + major = _Priority_Major( new_priority ); + minor = _Priority_Minor( new_priority ); + + the_priority_map->minor = + &_Priority_Bit_map[ _Priority_Bits_index(major) ]; + + mask = _Priority_Mask( major ); + the_priority_map->ready_major = mask; + /* Add _Priority_Mask_invert to non-generic bitfield then change this code. */ + the_priority_map->block_major = (Priority_bit_map_Control)(~((uint32_t)mask)); + + mask = _Priority_Mask( minor ); + the_priority_map->ready_minor = mask; + /* Add _Priority_Mask_invert to non-generic bitfield then change this code. */ + the_priority_map->block_minor = (Priority_bit_map_Control)(~((uint32_t)mask)); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/scheduler.inl b/cpukit/score/inline/rtems/score/scheduler.inl new file mode 100644 index 0000000000..4a6c74cbf8 --- /dev/null +++ b/cpukit/score/inline/rtems/score/scheduler.inl @@ -0,0 +1,165 @@ +/** + * @file rtems/score/scheduler.inl + * + * This inline file contains all of the inlined routines associated with + * the manipulation of the scheduler. + */ + +/* + * Copyright (C) 2010 Gedare Bloom. + * Copyright (C) 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_SCHEDULER_H +# error "Never use <rtems/score/scheduler.inl> directly; include <rtems/score/scheduler.h> instead." +#endif + +#ifndef _RTEMS_SCORE_SCHEDULER_INL +#define _RTEMS_SCORE_SCHEDULER_INL + +/** + * @addtogroup ScoreScheduler + * @{ + */ + +/** + * The preferred method to add a new scheduler is to define the jump table + * entries and add a case to the _Scheduler_Initialize routine. + * + * Generic scheduling implementations that rely on the ready queue only can + * be found in the _Scheduler_queue_XXX functions. + * + */ + +/* Passing the Scheduler_Control* to these functions allows for multiple + * scheduler's to exist simultaneously, which could be useful on an SMP + * system. Then remote Schedulers may be accessible. How to protect such + * accesses remains an open problem. + */ + +/** @brief _Scheduler_Schedule + * + * This kernel routine implements the scheduling decision logic for + * the scheduler. It does NOT dispatch. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( void ) +{ + _Scheduler.Operations.schedule(); +} + +/** @brief _Scheduler_Yield + * + * This routine is invoked when a thread wishes to voluntarily + * transfer control of the processor to another thread. This routine + * always operates on the scheduler that 'owns' the currently executing + * thread. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Yield( void ) +{ + _Scheduler.Operations.yield(); +} + +/** @brief _Scheduler_Block + * + * This routine removes @a the_thread from the scheduling decision for + * the scheduler. The primary task is to remove the thread from the + * ready queue. It performs any necessary schedulering operations + * including the selection of a new heir thread. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Block( + Thread_Control *the_thread +) +{ + _Scheduler.Operations.block( the_thread ); +} + +/** @brief _Scheduler_Unblock + * + * This routine adds @a the_thread to the scheduling decision for + * the scheduler. The primary task is to add the thread to the + * ready queue per the schedulering policy and update any appropriate + * scheduling variables, for example the heir thread. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( + Thread_Control *the_thread +) +{ + _Scheduler.Operations.unblock( the_thread ); +} + +/** @brief _Scheduler_Allocate + * + * This routine allocates @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void* _Scheduler_Allocate( + Thread_Control *the_thread +) +{ + return _Scheduler.Operations.allocate( the_thread ); +} + +/** @brief _Scheduler_Free + * + * This routine frees @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Free( + Thread_Control *the_thread +) +{ + return _Scheduler.Operations.free( the_thread ); +} + +/** @brief _Scheduler_Update + * + * This routine updates @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Update( + Thread_Control *the_thread +) +{ + _Scheduler.Operations.update( the_thread ); +} + +/** @brief _Scheduler_Enqueue + * + * This routine enqueue @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue( + Thread_Control *the_thread +) +{ + _Scheduler.Operations.enqueue( the_thread ); +} + +/** @brief _Scheduler_Enqueue_first + * + * This routine enqueue_first @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Enqueue_first( + Thread_Control *the_thread +) +{ + _Scheduler.Operations.enqueue_first( the_thread ); +} + +/** @brief _Scheduler_Extract + * + * This routine extract @a the_thread->scheduler + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Extract( + Thread_Control *the_thread +) +{ + _Scheduler.Operations.extract( the_thread ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/schedulerpriority.inl b/cpukit/score/inline/rtems/score/schedulerpriority.inl new file mode 100644 index 0000000000..680606ce53 --- /dev/null +++ b/cpukit/score/inline/rtems/score/schedulerpriority.inl @@ -0,0 +1,195 @@ +/** + * @file rtems/score/schedulerpriority.inl + * + * This inline file contains all of the inlined routines associated with + * the manipulation of the priority-based scheduling structures. + */ + +/* + * Copyright (C) 2010 Gedare Bloom. + * Copyright (C) 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_SCHEDULERPRIORITY_H +# error "Never use <rtems/score/schedulerpriority.inl> directly; include <rtems/score/schedulerpriority.h> instead." +#endif + +#ifndef _RTEMS_SCORE_SCHEDULERPRIORITY_INL +#define _RTEMS_SCORE_SCHEDULERPRIORITY_INL + +#include <rtems/score/wkspace.h> + +/** + * @addtogroup ScoreScheduler + * @{ + */ + +/** @brief Scheduler priority Ready queue initialize + * + * This routine initializes @a the_ready_queue for priority-based scheduling. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_initialize(void) +{ + size_t index; + Chain_Control *ready_queues; + + /* allocate ready queue structures */ + _Scheduler.information = _Workspace_Allocate_or_fatal_error( + ((size_t) PRIORITY_MAXIMUM + 1) * sizeof(Chain_Control) + ); + + /* initialize ready queue structures */ + ready_queues = (Chain_Control *) _Scheduler.information; + for( index=0; index <= PRIORITY_MAXIMUM; index++) + _Chain_Initialize_empty( &ready_queues[index] ); +} + +/** + * @brief _Scheduler_priority_Ready_queue_enqueue + * + * This routine puts @a the_thread on to the priority-based ready queue. + * + * @param[in] the_thread - pointer to thread + */ +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue( + Thread_Control *the_thread +) +{ + Scheduler_priority_Per_thread *sched_info; + Chain_Control *ready; + + sched_info = (Scheduler_priority_Per_thread *) the_thread->scheduler_info; + ready = sched_info->ready_chain; + + _Priority_bit_map_Add( &sched_info->Priority_map ); + + _Chain_Append_unprotected( ready, &the_thread->Object.Node ); +} + +/** + * @brief _Scheduler_priority_Ready_queue_Enqueue_first + * + * This routine puts @a the_thread to the head of the ready queue. + * For priority-based ready queues, the thread will be the first thread + * at its priority level. + * + * @param[in] the_thread - pointer to thread + */ +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first( + Thread_Control *the_thread +) +{ + Scheduler_priority_Per_thread *sched_info; + Chain_Control *ready; + + sched_info = (Scheduler_priority_Per_thread *) the_thread->scheduler_info; + ready = sched_info->ready_chain; + + _Priority_bit_map_Add( &sched_info->Priority_map ); + + _Chain_Prepend_unprotected( + sched_info->ready_chain, + &the_thread->Object.Node + ); +} + +/** + * @brief _Scheduler_priority_Ready_queue_extract + * + * This routine removes a specific thread from the specified + * priority-based ready queue. + * + * @param[in] the_thread - pointer to thread + */ +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract( + Thread_Control *the_thread +) +{ + Scheduler_priority_Per_thread *sched_info; + Chain_Control *ready; + + sched_info = (Scheduler_priority_Per_thread *) the_thread->scheduler_info; + ready = sched_info->ready_chain; + + if ( _Chain_Has_only_one_node( ready ) ) { + _Chain_Initialize_empty( ready ); + _Priority_bit_map_Remove( &sched_info->Priority_map ); + } else { + _Chain_Extract_unprotected( &the_thread->Object.Node ); + } +} + +/** + * @brief _Scheduler_priority_Ready_queue_first + * + * This routines returns a pointer to the first thread on @a the_ready_queue. + * + * @param[in] the_ready_queue - pointer to thread queue + * + * @return This method returns the first thread or NULL + */ +RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_priority_Ready_queue_first( + Chain_Control *the_ready_queue +) +{ + Priority_Control index = _Priority_bit_map_Get_highest(); + + if ( !_Chain_Is_empty( &the_ready_queue[ index ] ) ) + return (Thread_Control *) _Chain_First( &the_ready_queue[ index ] ); + + return NULL; +} + +/** + * @brief _Scheduler_priority_Ready_queue_requeue + * + * This routine is invoked when a thread changes priority and should be + * moved to a different position on the ready queue. + * + * @param[in] the_thread - pointer to thread + */ +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_requeue( + Thread_Control *the_thread +) +{ + Scheduler_priority_Per_thread *sched_info; + Chain_Control *ready; + + sched_info = (Scheduler_priority_Per_thread *) the_thread->scheduler_info; + ready = sched_info->ready_chain; + + if ( !_Chain_Has_only_one_node( sched_info->ready_chain ) ) { + _Chain_Extract_unprotected( &the_thread->Object.Node ); + + _Chain_Append_unprotected( + sched_info->ready_chain, + &the_thread->Object.Node + ); + } +} + +/** + * @brief _Scheduler_priority_Schedule_body + * + * This kernel routine implements scheduling decision logic + * for priority-based scheduling. + * + * @param[in] the_thread - pointer to thread + */ +RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(void) +{ + _Thread_Heir = _Scheduler_priority_Ready_queue_first( + (Chain_Control *) _Scheduler.information + ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/schedulersimple.inl b/cpukit/score/inline/rtems/score/schedulersimple.inl new file mode 100644 index 0000000000..0996efc896 --- /dev/null +++ b/cpukit/score/inline/rtems/score/schedulersimple.inl @@ -0,0 +1,53 @@ +/** + * @file rtems/score/schedulersimple.inl + * + * This inline file contains all of the inlined routines associated with + * the manipulation of the priority-based scheduling structures. + */ + +/* + * Copyright (C) 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_SCHEDULERSIMPLE_H +# error "Never use <rtems/score/schedulersimple.inl> directly; include <rtems/score/schedulersimple.h> instead." +#endif + +#ifndef _RTEMS_SCORE_SCHEDULERSIMPLE_INL +#define _RTEMS_SCORE_SCHEDULERSIMPLE_INL + +#include <rtems/score/thread.h> + +/** + * @addtogroup ScoreScheduler + * @{ + */ + +/** + * This routine puts @a the_thread on to the ready queue. + * + * @param[in] the_ready_queue is a pointer to the ready queue head + * @param[in] the_thread is the thread to be blocked + */ +RTEMS_INLINE_ROUTINE void _Scheduler_simple_Ready_queue_Requeue( + Scheduler_Control *the_ready_queue, + Thread_Control *the_thread +) +{ + /* extract */ + _Chain_Extract_unprotected( &the_thread->Object.Node ); + + /* enqueue */ + _Scheduler_simple_Ready_queue_Enqueue( the_thread ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/stack.inl b/cpukit/score/inline/rtems/score/stack.inl new file mode 100644 index 0000000000..c5d809cb81 --- /dev/null +++ b/cpukit/score/inline/rtems/score/stack.inl @@ -0,0 +1,113 @@ +/** + * @file rtems/score/stack.inl + * + * This file contains the static inline implementation of the inlined + * routines from the Stack Handler. + */ + +/* + * COPYRIGHT (c) 1989-2006. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_STACK_H +# error "Never use <rtems/score/stack.inl> directly; include <rtems/score/stack.h> instead." +#endif + +#ifndef _RTEMS_SCORE_STACK_INL +#define _RTEMS_SCORE_STACK_INL + +#include <rtems/score/basedefs.h> /* RTEMS_INLINE_ROUTINE */ +#include <rtems/score/cpu.h> /* CPU_STACK_ALIGNMENT */ + +/** + * @addtogroup ScoreStack + * @{ + */ + +/** + * This routine initializes the_stack record to indicate that + * size bytes of memory starting at starting_address have been + * reserved for a stack. + */ +RTEMS_INLINE_ROUTINE void _Stack_Initialize ( + Stack_Control *the_stack, + void *starting_address, + size_t size +) +{ + the_stack->area = starting_address; + the_stack->size = size; +} + +/** + * This function returns the minimum stack size configured + * for this application. + * + * @return This method returns the minimum stack size; + */ +RTEMS_INLINE_ROUTINE uint32_t _Stack_Minimum (void) +{ + return rtems_minimum_stack_size; +} + +/** + * This function returns true if size bytes is enough memory for + * a valid stack area on this processor, and false otherwise. + * + * @param[in] size is the stack size to check + * + * @return This method returns true if the stack is large enough. + */ +RTEMS_INLINE_ROUTINE bool _Stack_Is_enough ( + size_t size +) +{ + return ( size >= _Stack_Minimum() ); +} + +/** + * This function returns the appropriate stack size given the requested + * size. If the requested size is below the minimum, then the minimum + * configured stack size is returned. + * + * @param[in] size is the stack size to check + * + * @return This method returns the appropriate stack size. + */ +RTEMS_INLINE_ROUTINE size_t _Stack_Ensure_minimum ( + size_t size +) +{ + if ( size >= _Stack_Minimum() ) + return size; + return _Stack_Minimum(); +} + +/** + * This function increases the stack size to ensure that the thread + * has the desired amount of stack space after the initial stack + * pointer is determined based on alignment restrictions. + * + * @note + * + * The amount of adjustment for alignment is CPU dependent. + */ + +RTEMS_INLINE_ROUTINE uint32_t _Stack_Adjust_size ( + size_t size +) +{ + return size + CPU_STACK_ALIGNMENT; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/states.inl b/cpukit/score/inline/rtems/score/states.inl new file mode 100644 index 0000000000..5a10985e95 --- /dev/null +++ b/cpukit/score/inline/rtems/score/states.inl @@ -0,0 +1,377 @@ +/** + * @file rtems/score/states.inl + * + * This file contains the static inline implementation of the inlined + * routines associated with thread state information. + */ + +/* + * COPYRIGHT (c) 1989-2009. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_STATES_H +# error "Never use <rtems/score/states.inl> directly; include <rtems/score/states.h> instead." +#endif + +#ifndef _RTEMS_SCORE_STATES_INL +#define _RTEMS_SCORE_STATES_INL + +#include <rtems/score/basedefs.h> /* RTEMS_INLINE_ROUTINE */ + +/** + * @addtogroup ScoreStates + * @{ + */ + +/** + * This function sets the given states_to_set into the current_state + * passed in. The result is returned to the user in current_state. + * + * @param[in] states_to_set is the state bits to set + * @param[in] current_state is the state set to add them to + * + * @return This method returns the updated states value. + */ +RTEMS_INLINE_ROUTINE States_Control _States_Set ( + States_Control states_to_set, + States_Control current_state +) +{ + return (current_state | states_to_set); +} + +/** + * This function clears the given states_to_clear into the current_state + * passed in. The result is returned to the user in current_state. + * + * @param[in] states_to_set is the state bits to clean + * @param[in] current_state is the state set to remove them from + * + * @return This method returns the updated states value. + */ +RTEMS_INLINE_ROUTINE States_Control _States_Clear ( + States_Control states_to_clear, + States_Control current_state +) +{ + return (current_state & ~states_to_clear); +} + +/** + * This function returns true if the_states indicates that the + * state is READY, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_ready ( + States_Control the_states +) +{ + return (the_states == STATES_READY); +} + +/** + * This function returns true if the DORMANT state is the ONLY state + * set in the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_only_dormant ( + States_Control the_states +) +{ + return (the_states == STATES_DORMANT); +} + +/** + * This function returns true if the DORMANT state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_dormant ( + States_Control the_states +) +{ + return (the_states & STATES_DORMANT); +} + +/** + * This function returns true if the SUSPENDED state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_suspended ( + States_Control the_states +) +{ + return (the_states & STATES_SUSPENDED); +} + +/** + * This function returns true if the TRANSIENT state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_transient ( + States_Control the_states +) +{ + return (the_states & STATES_TRANSIENT); +} + +/** + * This function returns true if the DELAYING state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_delaying ( + States_Control the_states +) +{ + return (the_states & STATES_DELAYING); +} + +/** + * This function returns true if the WAITING_FOR_BUFFER state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_buffer ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_BUFFER); +} + +/** + * This function returns true if the WAITING_FOR_SEGMENT state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_segment ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_SEGMENT); +} + +/** + * This function returns true if the WAITING_FOR_MESSAGE state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_message ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_MESSAGE); +} + +/** + * This function returns true if the WAITING_FOR_EVENT state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_event ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_EVENT); +} + +/** + * This function returns true if the WAITING_FOR_MUTEX state + * is set in the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_mutex ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_MUTEX); +} + +/** + * This function returns true if the WAITING_FOR_SEMAPHORE state + * is set in the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_semaphore ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_SEMAPHORE); +} + +/** + * This function returns true if the WAITING_FOR_TIME state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_time ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_TIME); +} + +/** + * This function returns true if the WAITING_FOR_TIME state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_rpc_reply ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_RPC_REPLY); +} + +/** + * This function returns true if the WAITING_FOR_PERIOD state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_period ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_PERIOD); +} + +/** + * This function returns true if the task's state is set in + * way that allows it to be interrupted by a signal. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_interruptible_by_signal ( + States_Control the_states +) +{ + return (the_states & STATES_INTERRUPTIBLE_BY_SIGNAL); + +} +/** + * This function returns true if one of the states which indicates + * that a task is blocked waiting for a local resource is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ + +RTEMS_INLINE_ROUTINE bool _States_Is_locally_blocked ( + States_Control the_states +) +{ + return (the_states & STATES_LOCALLY_BLOCKED); +} + +/** + * This function returns true if one of the states which indicates + * that a task is blocked waiting for a local resource is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the state indicates that the + * assocated thread is waiting on a thread queue. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_on_thread_queue ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_ON_THREAD_QUEUE); +} + +/** + * This function returns true if one of the states which indicates + * that a task is blocked is set in the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the state indicates that the + * assocated thread is blocked. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_blocked ( + States_Control the_states +) +{ + return (the_states & STATES_BLOCKED); +} + +/** + * This function returns true if any of the states in the mask + * are set in the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * @param[in] mask is the state bits to test for + * + * @return This method returns true if the indicates state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Are_set ( + States_Control the_states, + States_Control mask +) +{ + return ( (the_states & mask) != STATES_READY); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/sysstate.inl b/cpukit/score/inline/rtems/score/sysstate.inl new file mode 100644 index 0000000000..f391badaf3 --- /dev/null +++ b/cpukit/score/inline/rtems/score/sysstate.inl @@ -0,0 +1,104 @@ +/** + * @file + * + * @ingroup ScoreSysState + * + * @brief System State Handler API. + */ + +/* + * COPYRIGHT (c) 1989-2004. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_SYSSTATE_H +# error "Never use <rtems/score/sysstate.inl> directly; include <rtems/score/sysstate.h> instead." +#endif + +#ifndef _RTEMS_SCORE_SYSSTATE_INL +#define _RTEMS_SCORE_SYSSTATE_INL + +/** + * @addtogroup ScoreSysState + * + * @{ + */ + +RTEMS_INLINE_ROUTINE void _System_state_Set ( + System_state_Codes state +) +{ + _System_state_Current = state; +} + +RTEMS_INLINE_ROUTINE void _System_state_Handler_initialization ( +#if defined(RTEMS_MULTIPROCESSING) + bool is_multiprocessing +#else + bool is_multiprocessing __attribute__((unused)) +#endif +) +{ + _System_state_Set( SYSTEM_STATE_BEFORE_INITIALIZATION ); +#if defined(RTEMS_MULTIPROCESSING) + _System_state_Is_multiprocessing = is_multiprocessing; +#endif +} + +RTEMS_INLINE_ROUTINE System_state_Codes _System_state_Get ( void ) +{ + return _System_state_Current; +} + +RTEMS_INLINE_ROUTINE bool _System_state_Is_before_initialization ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEFORE_INITIALIZATION); +} + +RTEMS_INLINE_ROUTINE bool _System_state_Is_before_multitasking ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEFORE_MULTITASKING); +} + +RTEMS_INLINE_ROUTINE bool _System_state_Is_begin_multitasking ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_BEGIN_MULTITASKING); +} + +RTEMS_INLINE_ROUTINE bool _System_state_Is_shutdown ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_SHUTDOWN); +} + +RTEMS_INLINE_ROUTINE bool _System_state_Is_up ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_UP); +} + +RTEMS_INLINE_ROUTINE bool _System_state_Is_failed ( + System_state_Codes state +) +{ + return (state == SYSTEM_STATE_FAILED); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl new file mode 100644 index 0000000000..e700bdfb53 --- /dev/null +++ b/cpukit/score/inline/rtems/score/thread.inl @@ -0,0 +1,353 @@ +/** + * @file rtems/score/thread.inl + * + * This file contains the macro implementation of the inlined + * routines from the Thread handler. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_THREAD_H +# error "Never use <rtems/score/thread.inl> directly; include <rtems/score/thread.h> instead." +#endif + +#ifndef _RTEMS_SCORE_THREAD_INL +#define _RTEMS_SCORE_THREAD_INL + +#include <rtems/score/sysstate.h> +#include <rtems/score/context.h> + +/** + * @addtogroup ScoreThread + * @{ + */ + +/** + * This routine halts multitasking and returns control to + * the "thread" (i.e. the BSP) which initially invoked the + * routine which initialized the system. + */ + +RTEMS_INLINE_ROUTINE void _Thread_Stop_multitasking( void ) +{ + /* + * This may look a bit of an odd but _Context_Restart_self is just + * a very careful restore of a specific context which ensures that + * if we were running within the same context, it would work. + * + * And we will not return to this thread, so there is no point of + * saving the context. + */ + _Context_Restart_self( &_Thread_BSP_context ); + + /*************************************************************** + *************************************************************** + * SYSTEM SHUTS DOWN!!! WE DO NOT RETURN TO THIS POINT!!! * + *************************************************************** + *************************************************************** + */ +} + +/** + * This function returns true if the_thread is the currently executing + * thread, and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Thread_Is_executing ( + const Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Executing ); +} + +/** + * This function returns true if the_thread is the heir + * thread, and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Thread_Is_heir ( + const Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Heir ); +} + +/** + * This function returns true if the currently executing thread + * is also the heir thread, and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Thread_Is_executing_also_the_heir( void ) +{ + return ( _Thread_Executing == _Thread_Heir ); +} + +/** + * This routine clears any blocking state for the_thread. It performs + * any necessary scheduling operations including the selection of + * a new heir thread. + */ + +RTEMS_INLINE_ROUTINE void _Thread_Unblock ( + Thread_Control *the_thread +) +{ + _Thread_Clear_state( the_thread, STATES_BLOCKED ); +} + +/** + * This routine resets the current context of the calling thread + * to that of its initial state. + */ + +RTEMS_INLINE_ROUTINE void _Thread_Restart_self( void ) +{ +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) + if ( _Thread_Executing->fp_context != NULL ) + _Context_Restore_fp( &_Thread_Executing->fp_context ); +#endif + + _CPU_Context_Restart_self( &_Thread_Executing->Registers ); +} + +/** + * This function returns true if the floating point context of + * the_thread is currently loaded in the floating point unit, and + * false otherwise. + */ + +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) +RTEMS_INLINE_ROUTINE bool _Thread_Is_allocated_fp ( + const Thread_Control *the_thread +) +{ + return ( the_thread == _Thread_Allocated_fp ); +} +#endif + +/** + * This routine is invoked when the currently loaded floating + * point context is now longer associated with an active thread. + */ + +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) +RTEMS_INLINE_ROUTINE void _Thread_Deallocate_fp( void ) +{ + _Thread_Allocated_fp = NULL; +} +#endif + +/** + * This routine prevents dispatching. + */ + +#if defined(RTEMS_HEAVY_STACK_DEBUG) || defined(RTEMS_HEAVY_MALLOC_DEBUG) + #include <rtems/bspIo.h> + #include <rtems/fatal.h> + #include <rtems/stackchk.h> + #include <rtems/score/sysstate.h> + #include <rtems/score/heap.h> + + /* + * This is currently not defined in any .h file, so we have to + * extern it here. + */ + extern Heap_Control *RTEMS_Malloc_Heap; +#endif + +RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void ) +{ + /* + * This check is very brutal to system performance but is very helpful + * at finding blown stack problems. If you have a stack problem and + * need help finding it, then uncomment this code. Every system + * call will check the stack and since mutexes are used frequently + * in most systems, you might get lucky. + */ + #if defined(RTEMS_HEAVY_STACK_DEBUG) + if (_System_state_Is_up(_System_state_Get()) && (_ISR_Nest_level == 0)) { + if ( rtems_stack_checker_is_blown() ) { + printk( "Stack blown!!\n" ); + rtems_fatal_error_occurred( 99 ); + } + } + #endif + + _Thread_Dispatch_disable_level += 1; + RTEMS_COMPILER_MEMORY_BARRIER(); + + /* + * This check is even more brutal than the other one. This enables + * malloc heap integrity checking upon entry to every system call. + */ + #if defined(RTEMS_HEAVY_MALLOC_DEBUG) + if ( _Thread_Dispatch_disable_level == 1 ) { + _Heap_Walk( RTEMS_Malloc_Heap,99, false ); + } + #endif +} + +/** + * This routine allows dispatching to occur again. If this is + * the outer most dispatching critical section, then a dispatching + * operation will be performed and, if necessary, control of the + * processor will be transferred to the heir thread. + */ + +#if ( (defined(CPU_INLINE_ENABLE_DISPATCH) && \ + (CPU_INLINE_ENABLE_DISPATCH == FALSE)) || \ + (__RTEMS_DO_NOT_INLINE_THREAD_ENABLE_DISPATCH__ == 1) ) +void _Thread_Enable_dispatch( void ); +#else +/* inlining of enable dispatching must be true */ +RTEMS_INLINE_ROUTINE void _Thread_Enable_dispatch( void ) +{ + RTEMS_COMPILER_MEMORY_BARRIER(); + if ( (--_Thread_Dispatch_disable_level) == 0 ) + _Thread_Dispatch(); +} +#endif + + +/** + * This routine allows dispatching to occur again. However, + * no dispatching operation is performed even if this is the outer + * most dispatching critical section. + */ + +RTEMS_INLINE_ROUTINE void _Thread_Unnest_dispatch( void ) +{ + RTEMS_COMPILER_MEMORY_BARRIER(); + _Thread_Dispatch_disable_level -= 1; +} + +/** + * This function returns true if dispatching is disabled, and false + * otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Thread_Is_dispatching_enabled( void ) +{ + return ( _Thread_Dispatch_disable_level == 0 ); +} + +/** + * This function returns true if dispatching is disabled, and false + * otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Thread_Is_context_switch_necessary( void ) +{ + return ( _Thread_Dispatch_necessary ); +} + +/** + * This routine initializes the thread dispatching subsystem. + */ + +RTEMS_INLINE_ROUTINE void _Thread_Dispatch_initialization( void ) +{ + _Thread_Dispatch_disable_level = 1; +} + +/** + * This function returns true if the_thread is NULL and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Thread_Is_null ( + const Thread_Control *the_thread +) +{ + return ( the_thread == NULL ); +} + +/** @brief _Thread_Is_proxy_blocking + * + * status which indicates that a proxy is blocking, and false otherwise. + */ +RTEMS_INLINE_ROUTINE bool _Thread_Is_proxy_blocking ( + uint32_t code +) +{ + return (code == THREAD_STATUS_PROXY_BLOCKING); +} + +/** + * This routine allocates an internal thread. + */ + +RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void ) +{ + return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information ); +} + +/** + * This routine frees an internal thread. + */ + +RTEMS_INLINE_ROUTINE void _Thread_Internal_free ( + Thread_Control *the_task +) +{ + _Objects_Free( &_Thread_Internal_information, &the_task->Object ); +} + +/** + * This routine returns the C library re-enterant pointer. + */ + +RTEMS_INLINE_ROUTINE struct _reent **_Thread_Get_libc_reent( void ) +{ + return _Thread_libc_reent; +} + +/** + * This routine set the C library re-enterant pointer. + */ + +RTEMS_INLINE_ROUTINE void _Thread_Set_libc_reent ( + struct _reent **libc_reent +) +{ + _Thread_libc_reent = libc_reent; +} + +/** + * This routine evaluates the current scheduling information for the + * system and determines if a context switch is required. This + * is usually called after changing an execution mode such as preemptability + * for a thread. + * + * @param[in] are_signals_pending specifies whether or not the API + * level signals are pending and a dispatch is needed. + */ +RTEMS_INLINE_ROUTINE bool _Thread_Evaluate_is_dispatch_needed( + bool are_signals_pending +) +{ + Thread_Control *executing; + + executing = _Thread_Executing; + + if ( are_signals_pending || + (!_Thread_Is_heir( executing ) && executing->is_preemptible) ) { + _Thread_Dispatch_necessary = true; + return true; + } + + return false; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/threadmp.inl b/cpukit/score/inline/rtems/score/threadmp.inl new file mode 100644 index 0000000000..648ed0e1d2 --- /dev/null +++ b/cpukit/score/inline/rtems/score/threadmp.inl @@ -0,0 +1,64 @@ +/** + * @file rtems/score/threadmp.inl + * + * This include file contains the bodies of all inlined routines + * for the multiprocessing part of thread package. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_THREADMP_H +# error "Never use <rtems/score/threadmp.inl> directly; include <rtems/score/threadmp.h> instead." +#endif + +#include <rtems/score/mpci.h> + +#ifndef _RTEMS_SCORE_THREADMP_INL +#define _RTEMS_SCORE_THREADMP_INL + +/** + * @addtogroup ScoreThreadMP + * @{ + */ + +/** + * This function returns true if the thread in question is the + * multiprocessing receive thread. + * + * @note This is a macro to avoid needing a prototype for + * _MPCI_Receive_server_tcb until it is used. + */ +#define _Thread_MP_Is_receive(_the_thread) \ + (_the_thread == _MPCI_Receive_server_tcb) + +/** + * This routine frees a proxy control block to the + * inactive chain of free proxy control blocks. + */ + +RTEMS_INLINE_ROUTINE void _Thread_MP_Free_proxy ( + Thread_Control *the_thread +) +{ + Thread_Proxy_control *the_proxy; + + the_proxy = (Thread_Proxy_control *) the_thread; + + _Chain_Extract( &the_proxy->Active ); + + _Chain_Append( &_Thread_MP_Inactive_proxies, &the_thread->Object.Node ); +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/threadq.inl b/cpukit/score/inline/rtems/score/threadq.inl new file mode 100644 index 0000000000..b8bc99bf20 --- /dev/null +++ b/cpukit/score/inline/rtems/score/threadq.inl @@ -0,0 +1,36 @@ +/** + * @file rtems/score/threadq.inl + * + * This inline file contains all of the inlined routines associated with + * the manipulation of thread queues. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_THREADQ_H +# error "Never use <rtems/score/threadq.inl> directly; include <rtems/score/threadq.h> instead." +#endif + +#ifndef _RTEMS_SCORE_THREADQ_INL +#define _RTEMS_SCORE_THREADQ_INL + +#include <rtems/score/thread.h> + +/** + * @addtogroup ScoreThreadQ + * @{ + */ + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/tod.inl b/cpukit/score/inline/rtems/score/tod.inl new file mode 100644 index 0000000000..67a37862e9 --- /dev/null +++ b/cpukit/score/inline/rtems/score/tod.inl @@ -0,0 +1,79 @@ +/** + * @file rtems/score/tod.inl + * + * This file contains the static inline implementation of the inlined routines + * from the Time of Day Handler. + */ + +/* + * COPYRIGHT (c) 1989-2007. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_TOD_H +# error "Never use <rtems/score/tod.inl> directly; include <rtems/score/tod.h> instead." +#endif + +#ifndef _RTEMS_SCORE_TOD_INL +#define _RTEMS_SCORE_TOD_INL + +#include <sys/time.h> /* struct timeval */ + +#include <rtems/score/isr.h> + +/** + * @addtogroup ScoreTOD + * @{ + */ + +/** + * This routine deactivates updating of the current time of day. + */ + +RTEMS_INLINE_ROUTINE void _TOD_Deactivate( void ) +{ + /* XXX do we need something now that we are using timespec for TOD */ +} + +/** + * This routine activates updating of the current time of day. + */ + +RTEMS_INLINE_ROUTINE void _TOD_Activate( void ) +{ + /* XXX do we need something now that we are using timespec for TOD */ +} + +/** + * This routine returns a timeval based upon the internal timespec format TOD. + */ + +RTEMS_INLINE_ROUTINE void _TOD_Get_timeval( + struct timeval *time +) +{ + ISR_Level level; + struct timespec now; + suseconds_t useconds; + + _ISR_Disable(level); + _TOD_Get( &now ); + _ISR_Enable(level); + + useconds = (suseconds_t)now.tv_nsec; + useconds /= (suseconds_t)TOD_NANOSECONDS_PER_MICROSECOND; + + time->tv_sec = now.tv_sec; + time->tv_usec = useconds; +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/tqdata.inl b/cpukit/score/inline/rtems/score/tqdata.inl new file mode 100644 index 0000000000..6db7ce2f5a --- /dev/null +++ b/cpukit/score/inline/rtems/score/tqdata.inl @@ -0,0 +1,73 @@ +/** + * @file rtems/score/tqdata.inl + * + * This file contains the static inline implementation of the inlined + * routines needed to support the Thread Queue Data. + */ + +/* + * COPYRIGHT (c) 1989-2008. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_TQDATA_H +# error "Never use <rtems/score/tqdata.inl> directly; include <rtems/score/tqdata.h> instead." +#endif + +#ifndef _RTEMS_SCORE_TQDATA_INL +#define _RTEMS_SCORE_TQDATA_INL + +/** + * @addtogroup ScoreThreadQ + * @{ + */ + +/** + * This function returns the index of the priority chain on which + * a thread of the_priority should be placed. + */ + +RTEMS_INLINE_ROUTINE uint32_t _Thread_queue_Header_number ( + Priority_Control the_priority +) +{ + return (the_priority / TASK_QUEUE_DATA_PRIORITIES_PER_HEADER); +} + +/** + * This function returns true if the_priority indicates that the + * enqueue search should start at the front of this priority + * group chain, and false if the search should start at the rear. + */ + +RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_reverse_search ( + Priority_Control the_priority +) +{ + return ( the_priority & TASK_QUEUE_DATA_REVERSE_SEARCH_MASK ); +} + +/** + * This routine is invoked to indicate that the specified thread queue is + * entering a critical section. + */ + +RTEMS_INLINE_ROUTINE void _Thread_queue_Enter_critical_section ( + Thread_queue_Control *the_thread_queue +) +{ + the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; +} + +/** + * @} + */ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/watchdog.inl b/cpukit/score/inline/rtems/score/watchdog.inl new file mode 100644 index 0000000000..14f7759f79 --- /dev/null +++ b/cpukit/score/inline/rtems/score/watchdog.inl @@ -0,0 +1,262 @@ +/** + * @file rtems/score/watchdog.inl + * + * This file contains the static inline implementation of all inlined + * routines in the Watchdog Handler. + */ + +/* + * COPYRIGHT (c) 1989-2004. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_WATCHDOG_H +# error "Never use <rtems/score/watchdog.inl> directly; include <rtems/score/watchdog.h> instead." +#endif + +#ifndef _RTEMS_SCORE_WATCHDOG_INL +#define _RTEMS_SCORE_WATCHDOG_INL + +/** + * @addtogroup ScoreWatchdog + * @{ + */ + +/** + * This routine initializes the specified watchdog. The watchdog is + * made inactive, the watchdog id and handler routine are set to the + * specified values. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Initialize( + Watchdog_Control *the_watchdog, + Watchdog_Service_routine_entry routine, + Objects_Id id, + void *user_data +) +{ + the_watchdog->state = WATCHDOG_INACTIVE; + the_watchdog->routine = routine; + the_watchdog->id = id; + the_watchdog->user_data = user_data; +} + +/** + * This routine returns true if the watchdog timer is in the ACTIVE + * state, and false otherwise. + */ + +RTEMS_INLINE_ROUTINE bool _Watchdog_Is_active( + Watchdog_Control *the_watchdog +) +{ + + return ( the_watchdog->state == WATCHDOG_ACTIVE ); + +} + +/** + * This routine activates THE_WATCHDOG timer which is already + * on a watchdog chain. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Activate( + Watchdog_Control *the_watchdog +) +{ + + the_watchdog->state = WATCHDOG_ACTIVE; + +} + +/** + * This routine deactivates THE_WATCHDOG timer which will remain + * on a watchdog chain. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Deactivate( + Watchdog_Control *the_watchdog +) +{ + + the_watchdog->state = WATCHDOG_REMOVE_IT; + +} + +/** + * This routine is invoked at each clock tick to update the ticks + * watchdog chain. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_ticks( void ) +{ + + _Watchdog_Tickle( &_Watchdog_Ticks_chain ); + +} + +/** + * This routine is invoked at each clock tick to update the seconds + * watchdog chain. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Tickle_seconds( void ) +{ + + _Watchdog_Tickle( &_Watchdog_Seconds_chain ); + +} + +/** + * This routine inserts THE_WATCHDOG into the ticks watchdog chain + * for a time of UNITS ticks. The INSERT_MODE indicates whether + * THE_WATCHDOG is to be activated automatically or later, explicitly + * by the caller. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Insert_ticks( + Watchdog_Control *the_watchdog, + Watchdog_Interval units +) +{ + + the_watchdog->initial = units; + + _Watchdog_Insert( &_Watchdog_Ticks_chain, the_watchdog ); + +} + +/** + * This routine inserts THE_WATCHDOG into the seconds watchdog chain + * for a time of UNITS seconds. The INSERT_MODE indicates whether + * THE_WATCHDOG is to be activated automatically or later, explicitly + * by the caller. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Insert_seconds( + Watchdog_Control *the_watchdog, + Watchdog_Interval units +) +{ + + the_watchdog->initial = units; + + _Watchdog_Insert( &_Watchdog_Seconds_chain, the_watchdog ); + +} + +/** + * This routine adjusts the seconds watchdog chain in the forward + * or backward DIRECTION for UNITS seconds. This is invoked when the + * current time of day is changed. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Adjust_seconds( + Watchdog_Adjust_directions direction, + Watchdog_Interval units +) +{ + + _Watchdog_Adjust( &_Watchdog_Seconds_chain, direction, units ); + +} + +/** + * This routine adjusts the ticks watchdog chain in the forward + * or backward DIRECTION for UNITS ticks. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Adjust_ticks( + Watchdog_Adjust_directions direction, + Watchdog_Interval units +) +{ + + _Watchdog_Adjust( &_Watchdog_Ticks_chain, direction, units ); + +} + +/** + * This routine resets THE_WATCHDOG timer to its state at INSERT + * time. This routine is valid only on interval watchdog timers + * and is used to make an interval watchdog timer fire "every" so + * many ticks. + */ + +RTEMS_INLINE_ROUTINE void _Watchdog_Reset( + Watchdog_Control *the_watchdog +) +{ + + (void) _Watchdog_Remove( the_watchdog ); + + _Watchdog_Insert( &_Watchdog_Ticks_chain, the_watchdog ); + +} + +/** + * This routine returns a pointer to the watchdog timer following + * THE_WATCHDOG on the watchdog chain. + */ + +RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Next( + Watchdog_Control *the_watchdog +) +{ + + return ( (Watchdog_Control *) the_watchdog->Node.next ); + +} + +/** + * This routine returns a pointer to the watchdog timer preceding + * THE_WATCHDOG on the watchdog chain. + */ + +RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Previous( + Watchdog_Control *the_watchdog +) +{ + + return ( (Watchdog_Control *) the_watchdog->Node.previous ); + +} + +/** + * This routine returns a pointer to the first watchdog timer + * on the watchdog chain HEADER. + */ + +RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_First( + Chain_Control *header +) +{ + + return ( (Watchdog_Control *) _Chain_First( header ) ); + +} + +/** + * This routine returns a pointer to the last watchdog timer + * on the watchdog chain HEADER. + */ + +RTEMS_INLINE_ROUTINE Watchdog_Control *_Watchdog_Last( + Chain_Control *header +) +{ + + return ( (Watchdog_Control *) _Chain_Last( header ) ); + +} + +/**@}*/ + +#endif +/* end of include file */ diff --git a/cpukit/score/inline/rtems/score/wkspace.inl b/cpukit/score/inline/rtems/score/wkspace.inl new file mode 100644 index 0000000000..4342f2d20f --- /dev/null +++ b/cpukit/score/inline/rtems/score/wkspace.inl @@ -0,0 +1,34 @@ +/** + * @file rtems/score/wkspace.inl + * + * This include file contains the bodies of the routines which contains + * information related to the RAM Workspace. + */ + +/* + * COPYRIGHT (c) 1989-2007. + * 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.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef _RTEMS_SCORE_WKSPACE_H +# error "Never use <rtems/score/wkspace.inl> directly; include <rtems/score/wkspace.h> instead." +#endif + +#ifndef _RTEMS_SCORE_WKSPACE_INL +#define _RTEMS_SCORE_WKSPACE_INL + +/** + * @addtogroup ScoreWorkspace + * @{ + */ + +/**@}*/ + +#endif +/* end of include file */ |