2002-07-01 Joel Sherrill <joel@OARcorp.com>

* Mega patch merge to change the format of the object IDs to
	loosen the dependency between the SCORE and the various APIs.
	There was considerable work to simplify the object name management
        and it appears that the name_table field is no longer needed.
	This patch also includes the addition of the internal mutex
	which is currently only used to protect some types of allocation
	and deallocation.  This significantly can reduce context
	switch latency under certain circumstances.  In particular,
	some heap/region operations were O(n) and had dispatching
	disabled.  This should help enormously.  With this merge,
	the patch is not as clean as it should be.  In particular,
	the documentation has not been modified to reflect the new object
	ID layout, the IDs in the test screens are not updated, and
	_Objects_Get_information needs to be a real routine not inlined.
	As part of this patch a lot of MP code for thread/proxy blocking
	was made conditional and cleaned up.
	* include/Makefile.am, include/rtems/score/coremsg.h,
	include/rtems/score/coremutex.h, include/rtems/score/coresem.h,
	include/rtems/score/object.h, include/rtems/score/threadq.h,
	inline/rtems/score/object.inl, inline/rtems/score/thread.inl,
	macros/rtems/score/object.inl, src/Makefile.am, src/coremsg.c,
	src/coremutex.c, src/coresem.c, src/mpci.c,
	src/objectcomparenameraw.c, src/objectextendinformation.c,
	src/objectinitializeinformation.c, src/objectnametoid.c,
	src/thread.c, src/threadclose.c, src/threadget.c, src/threadq.c,
	src/threadqextractwithproxy.c: Modified as part of above.
	* include/rtems/score/apimutex.h, src/objectgetnoprotection.c: New
	files.
This commit is contained in:
Joel Sherrill
2002-07-01 22:30:12 +00:00
parent 3a05d15f4b
commit ef9505a92f
52 changed files with 1064 additions and 338 deletions

View File

@@ -1,3 +1,34 @@
2002-07-01 Joel Sherrill <joel@OARcorp.com>
* Mega patch merge to change the format of the object IDs to
loosen the dependency between the SCORE and the various APIs.
There was considerable work to simplify the object name management
and it appears that the name_table field is no longer needed.
This patch also includes the addition of the internal mutex
which is currently only used to protect some types of allocation
and deallocation. This significantly can reduce context
switch latency under certain circumstances. In particular,
some heap/region operations were O(n) and had dispatching
disabled. This should help enormously. With this merge,
the patch is not as clean as it should be. In particular,
the documentation has not been modified to reflect the new object
ID layout, the IDs in the test screens are not updated, and
_Objects_Get_information needs to be a real routine not inlined.
As part of this patch a lot of MP code for thread/proxy blocking
was made conditional and cleaned up.
* include/Makefile.am, include/rtems/score/coremsg.h,
include/rtems/score/coremutex.h, include/rtems/score/coresem.h,
include/rtems/score/object.h, include/rtems/score/threadq.h,
inline/rtems/score/object.inl, inline/rtems/score/thread.inl,
macros/rtems/score/object.inl, src/Makefile.am, src/coremsg.c,
src/coremutex.c, src/coresem.c, src/mpci.c,
src/objectcomparenameraw.c, src/objectextendinformation.c,
src/objectinitializeinformation.c, src/objectnametoid.c,
src/thread.c, src/threadclose.c, src/threadget.c, src/threadq.c,
src/threadqextractwithproxy.c: Modified as part of above.
* include/rtems/score/apimutex.h, src/objectgetnoprotection.c: New
files.
2001-05-17 Joel Sherrill <joel@OARcorp.com>
* macros/rtems/score/thread..inl: Implemented missing routines

View File

@@ -27,6 +27,7 @@ MP_H_FILES = rtems/score/mpci.h rtems/score/mppkt.h rtems/score/objectmp.h \
# H_FILES that get installed in the rtems/score subdirectoy
STD_H_FILES = rtems/score/address.h rtems/score/apiext.h \
rtems/score/apimutex.h \
rtems/score/bitfield.h rtems/score/chain.h rtems/score/context.h \
rtems/score/copyrt.h rtems/score/coremsg.h rtems/score/coremutex.h \
rtems/score/coresem.h rtems/score/heap.h rtems/score/interr.h \

View File

@@ -0,0 +1,153 @@
/* apimutex.h
*
* This include file contains all the constants and structures associated
* with the API Mutex Handler. This handler is used by API level
* routines to manage mutual exclusion.
*
* COPYRIGHT (c) 1989-2002.
* 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.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __API_MUTEX_h
#define __API_MUTEX_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems/score/coremutex.h>
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
/*
* The following defines the control block used to manage each mutex.
*/
typedef struct {
Objects_Control Object;
CORE_mutex_Control Mutex;
} API_Mutex_Control;
/*
* The following defines the information control block used to manage
* this class of objects.
*/
SCORE_EXTERN Objects_Information _API_Mutex_Information;
/*
* _API_Mutex_Initialization
*
* DESCRIPTION:
*
* This routine performs the initialization necessary for this handler.
*/
#if defined(RTEMS_MULTIPROCESSING)
#define _API_Mutex_Initialization( _maximum_mutexes ) \
_Objects_Initialize_information( \
&_API_Mutex_Information, \
OBJECTS_INTERNAL_API, \
OBJECTS_INTERNAL_MUTEXES, \
_maximum_mutexes, \
sizeof( API_Mutex_Control ), \
FALSE, \
0, \
FALSE, \
NULL \
);
#else
#define _API_Mutex_Initialization( _maximum_mutexes ) \
_Objects_Initialize_information( \
&_API_Mutex_Information, \
OBJECTS_INTERNAL_API, \
OBJECTS_INTERNAL_MUTEXES, \
_maximum_mutexes, \
sizeof( API_Mutex_Control ), \
FALSE, \
0 \
);
#endif
/*
* _API_Mutex_Allocate
*
* DESCRIPTION:
*
* This routine allocates an api mutex from the inactive set.
*/
#define _API_Mutex_Allocate( _the_mutex ) \
do { \
CORE_mutex_Attributes attr = \
{ CORE_MUTEX_NESTING_IS_ERROR, FALSE, \
CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT, 0 }; \
(_the_mutex) = (API_Mutex_Control *) \
_Objects_Allocate( &_API_Mutex_Information ); \
_CORE_mutex_Initialize( \
&(_the_mutex)->Mutex, &attr, CORE_MUTEX_UNLOCKED ); \
} while (0)
/*
* _API_Mutex_Lock
*
* DESCRIPTION:
*
* This routine acquires the specified api mutex.
*/
#define _API_Mutex_Lock( _the_mutex ) \
do { \
ISR_Level _level; \
_CORE_mutex_Seize( \
&(_the_mutex)->Mutex, (_the_mutex)->Object.id, TRUE, 0, (_level) ); \
} while (0)
/*
* _API_Mutex_Unlock
*
* DESCRIPTION:
*
* This routine releases the specified api mutex.
*/
#define _API_Mutex_Unlock( _the_mutex ) \
do { \
_Thread_Disable_dispatch(); \
_CORE_mutex_Surrender( \
&(_the_mutex)->Mutex, (_the_mutex)->Object.id, NULL ); \
_Thread_Enable_dispatch(); \
} while (0);
/*XXX when the APIs all use this for allocation and deallocation
*XXX protection, then they should be renamed and probably moved
*/
SCORE_EXTERN API_Mutex_Control *_RTEMS_Allocator_Mutex;
#define _RTEMS_Lock_allocator() \
_API_Mutex_Lock( _RTEMS_Allocator_Mutex )
#define _RTEMS_Unlock_allocator() \
_API_Mutex_Unlock( _RTEMS_Allocator_Mutex )
/*
* There are no inlines for this handler.
*/
#ifndef __RTEMS_APPLICATION__
/* #include <rtems/score/apimutex.inl> */
#endif
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -144,11 +144,9 @@ typedef struct {
boolean _CORE_message_queue_Initialize(
CORE_message_queue_Control *the_message_queue,
Objects_Classes the_class,
CORE_message_queue_Attributes *the_message_queue_attributes,
unsigned32 maximum_pending_messages,
unsigned32 maximum_message_size,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 maximum_message_size
);
/*

View File

@@ -134,10 +134,8 @@ typedef struct {
void _CORE_mutex_Initialize(
CORE_mutex_Control *the_mutex,
Objects_Classes the_class,
CORE_mutex_Attributes *the_mutex_attributes,
unsigned32 initial_lock,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 initial_lock
);
/*

View File

@@ -89,10 +89,8 @@ typedef struct {
void _CORE_semaphore_Initialize(
CORE_semaphore_Control *the_semaphore,
Objects_Classes the_class,
CORE_semaphore_Attributes *the_semaphore_attributes,
unsigned32 initial_value,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 initial_value
);
/*

View File

@@ -26,7 +26,8 @@ extern "C" {
#include <rtems/score/isr.h>
/*
* Mask to enable unlimited objects
* Mask to enable unlimited objects. This is used in the configuration
* table when specifying the number of configured objects.
*/
#define OBJECTS_UNLIMITED_OBJECTS 0x80000000
@@ -60,63 +61,95 @@ typedef boolean (*Objects_Name_comparators)(
* The following type defines the control block used to manage
* object IDs. The format is as follows (0=LSB):
*
* Bits 0 .. 15 = index
* Bits 16 .. 25 = node
* Bits 26 .. 31 = class
* Bits 0 .. 15 = index (up to 65535 objects of a type)
* Bits 16 .. 23 = node (up to 255 nodes)
* Bits 24 .. 26 = API (up to 7 API classes)
* Bits 27 .. 31 = class (up to 31 object types per API)
*/
typedef unsigned32 Objects_Id;
#define OBJECTS_INDEX_START_BIT 0
#define OBJECTS_NODE_START_BIT 16
#define OBJECTS_CLASS_START_BIT 26
#define OBJECTS_API_START_BIT 24
#define OBJECTS_CLASS_START_BIT 27
#define OBJECTS_INDEX_MASK 0x0000ffff
#define OBJECTS_NODE_MASK 0x03ff0000
#define OBJECTS_CLASS_MASK 0xfc000000
#define OBJECTS_NODE_MASK 0x00ff0000
#define OBJECTS_API_MASK 0x07000000
#define OBJECTS_CLASS_MASK 0xf8000000
#define OBJECTS_INDEX_VALID_BITS 0x0000ffff
#define OBJECTS_NODE_VALID_BITS 0x000003ff
#define OBJECTS_CLASS_VALID_BITS 0x000000cf
#define OBJECTS_NODE_VALID_BITS 0x000000ff
#define OBJECTS_API_VALID_BITS 0x00000007
#define OBJECTS_CLASS_VALID_BITS 0x0000001f
/*
* This enumerated type is used in the class field of the object ID.
*/
typedef enum {
OBJECTS_NO_CLASS = 0,
OBJECTS_INTERNAL_THREADS = 1,
OBJECTS_RTEMS_TASKS = 2,
OBJECTS_POSIX_THREADS = 3,
OBJECTS_ITRON_TASKS = 4,
OBJECTS_RTEMS_TIMERS = 5,
OBJECTS_RTEMS_SEMAPHORES = 6,
OBJECTS_RTEMS_MESSAGE_QUEUES = 7,
OBJECTS_RTEMS_PARTITIONS = 8,
OBJECTS_RTEMS_REGIONS = 9,
OBJECTS_RTEMS_PORTS = 10,
OBJECTS_RTEMS_PERIODS = 11,
OBJECTS_RTEMS_EXTENSIONS = 12,
OBJECTS_POSIX_KEYS = 13,
OBJECTS_POSIX_INTERRUPTS = 14,
OBJECTS_POSIX_MESSAGE_QUEUE_FDS = 15,
OBJECTS_POSIX_MESSAGE_QUEUES = 16,
OBJECTS_POSIX_MUTEXES = 17,
OBJECTS_POSIX_SEMAPHORES = 18,
OBJECTS_POSIX_CONDITION_VARIABLES = 19,
OBJECTS_ITRON_EVENTFLAGS = 10,
OBJECTS_ITRON_MAILBOXES = 21,
OBJECTS_ITRON_MESSAGE_BUFFERS = 22,
OBJECTS_ITRON_PORTS = 23,
OBJECTS_ITRON_SEMAPHORES = 24,
OBJECTS_ITRON_VARIABLE_MEMORY_POOLS = 25,
OBJECTS_ITRON_FIXED_MEMORY_POOLS = 26
} Objects_Classes;
#define OBJECTS_NO_CLASS 0
#define OBJECTS_CLASSES_FIRST OBJECTS_NO_CLASS
#define OBJECTS_CLASSES_LAST OBJECTS_ITRON_FIXED_MEMORY_POOLS
#define OBJECTS_CLASSES_FIRST_THREAD_CLASS OBJECTS_INTERNAL_THREADS
#define OBJECTS_CLASSES_LAST_THREAD_CLASS OBJECTS_ITRON_TASKS
typedef enum {
OBJECTS_NO_API = 0,
OBJECTS_INTERNAL_API = 1,
OBJECTS_CLASSIC_API = 2,
OBJECTS_POSIX_API = 3,
OBJECTS_ITRON_API = 4
} Objects_APIs;
#define OBJECTS_APIS_LAST OBJECTS_ITRON_API
typedef enum {
OBJECTS_INTERNAL_NO_CLASS = 0,
OBJECTS_INTERNAL_THREADS = 1,
OBJECTS_INTERNAL_MUTEXES = 2
} Objects_Internal_API;
#define OBJECTS_INTERNAL_CLASSES_LAST OBJECTS_INTERNAL_MUTEXES
typedef enum {
OBJECTS_CLASSIC_NO_CLASS = 0,
OBJECTS_RTEMS_TASKS = 1,
OBJECTS_RTEMS_TIMERS = 2,
OBJECTS_RTEMS_SEMAPHORES = 3,
OBJECTS_RTEMS_MESSAGE_QUEUES = 4,
OBJECTS_RTEMS_PARTITIONS = 5,
OBJECTS_RTEMS_REGIONS = 6,
OBJECTS_RTEMS_PORTS = 7,
OBJECTS_RTEMS_PERIODS = 8,
OBJECTS_RTEMS_EXTENSIONS = 9
} Objects_Classic_API;
#define OBJECTS_RTEMS_CLASSES_LAST OBJECTS_RTEMS_EXTENSIONS
typedef enum {
OBJECTS_POSIX_NO_CLASS = 0,
OBJECTS_POSIX_THREADS = 1,
OBJECTS_POSIX_KEYS = 2,
OBJECTS_POSIX_INTERRUPTS = 3,
OBJECTS_POSIX_MESSAGE_QUEUE_FDS = 4,
OBJECTS_POSIX_MESSAGE_QUEUES = 5,
OBJECTS_POSIX_MUTEXES = 6,
OBJECTS_POSIX_SEMAPHORES = 7,
OBJECTS_POSIX_CONDITION_VARIABLES = 8
} Objects_POSIX_API;
#define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_CONDITION_VARIABLES
typedef enum {
OBJECTS_ITRON_NO_CLASS = 0,
OBJECTS_ITRON_TASKS = 1,
OBJECTS_ITRON_EVENTFLAGS = 2,
OBJECTS_ITRON_MAILBOXES = 3,
OBJECTS_ITRON_MESSAGE_BUFFERS = 4,
OBJECTS_ITRON_PORTS = 5,
OBJECTS_ITRON_SEMAPHORES = 6,
OBJECTS_ITRON_VARIABLE_MEMORY_POOLS = 7,
OBJECTS_ITRON_FIXED_MEMORY_POOLS = 8
} Objects_ITRON_API;
#define OBJECTS_ITRON_CLASSES_LAST OBJECTS_ITRON_FIXED_MEMORY_POOLS
/*
* This enumerated type lists the locations which may be returned
@@ -130,6 +163,15 @@ typedef enum {
OBJECTS_ERROR = 2 /* id was invalid */
} Objects_Locations;
/*
* The following type defines the callout used when a local task
* is extracted from a remote thread queue (i.e. it's proxy must
* extracted from the remote queue).
*/
typedef void ( *Objects_Thread_queue_Extract_callout )( void * );
/*
* The following defines the Object Control Block used to manage
* each object local to this node.
@@ -147,7 +189,8 @@ typedef struct {
*/
typedef struct {
Objects_Classes the_class; /* Class of this object */
Objects_APIs the_api; /* API of this object */
unsigned32 the_class; /* class of this object */
Objects_Id minimum_id; /* minimum valid id of this type */
Objects_Id maximum_id; /* maximum valid id of this type */
unsigned32 maximum; /* maximum number of objects */
@@ -156,15 +199,16 @@ typedef struct {
unsigned32 size; /* size of the objects */
Objects_Control **local_table;
Objects_Name *name_table;
Chain_Control *global_table; /* pointer to global table */
Chain_Control Inactive; /* chain of inactive ctl blocks */
unsigned32 inactive; /* number of objects on the InActive list */
unsigned32 *inactive_per_block; /* used to release a block */
void **object_blocks; /* the object memory to remove */
boolean is_string; /* TRUE if names are strings */
unsigned32 name_length; /* maximum length of names */
boolean is_thread; /* TRUE if these are threads */
/* irregardless of API */
Objects_Thread_queue_Extract_callout *extract;
#if defined(RTEMS_MULTIPROCESSING)
Chain_Control *global_table; /* pointer to global table */
#endif
} Objects_Information;
/*
@@ -176,13 +220,13 @@ SCORE_EXTERN unsigned32 _Objects_Local_node;
SCORE_EXTERN unsigned32 _Objects_Maximum_nodes;
/*
* The following is the list of information blocks for each object
* The following is the list of information blocks per API for each object
* class. From the ID, we can go to one of these information blocks,
* and obtain a pointer to the appropriate object control block.
*/
SCORE_EXTERN Objects_Information
*_Objects_Information_table[OBJECTS_CLASSES_LAST + 1];
**_Objects_Information_table[OBJECTS_APIS_LAST + 1];
/*
* The following defines the constant which may be used
@@ -208,8 +252,8 @@ SCORE_EXTERN Objects_Information
#define OBJECTS_ID_INITIAL_INDEX (0)
#define OBJECTS_ID_FINAL_INDEX (0xffff)
#define OBJECTS_ID_INITIAL(_class, _node) \
_Objects_Build_id( (_class), (_node), OBJECTS_ID_INITIAL_INDEX )
#define OBJECTS_ID_INITIAL(_api, _class, _node) \
_Objects_Build_id( (_api), (_class), (_node), OBJECTS_ID_INITIAL_INDEX )
#define OBJECTS_ID_FINAL ((Objects_Id)~0)
@@ -268,13 +312,17 @@ void _Objects_Shrink_information(
void _Objects_Initialize_information (
Objects_Information *information,
Objects_Classes the_class,
boolean supports_global,
Objects_APIs the_api,
unsigned32 the_class,
unsigned32 maximum,
unsigned32 size,
boolean is_string,
unsigned32 maximum_name_length,
boolean is_task
unsigned32 maximum_name_length
#if defined(RTEMS_MULTIPROCESSING)
,
boolean supports_global,
Objects_Thread_queue_Extract_callout *extract
#endif
);
/*PAGE
@@ -460,6 +508,13 @@ Objects_Control *_Objects_Get_by_index (
Objects_Id id,
Objects_Locations *location
);
Objects_Control *_Objects_Get_no_protection(
Objects_Information *information,
Objects_Id id,
Objects_Locations *location
);
/*
* _Objects_Get_next
*

View File

@@ -47,12 +47,14 @@ typedef void ( *Thread_queue_Flush_callout )(
* extracted from the remote queue).
*/
#if 0
typedef void ( *Thread_queue_Extract_callout )(
Thread_Control *
);
SCORE_EXTERN Thread_queue_Extract_callout
_Thread_queue_Extract_table[ OBJECTS_CLASSES_LAST + 1 ];
#endif
/*
* _Thread_queue_Dequeue
@@ -103,7 +105,7 @@ void _Thread_queue_Extract(
* DESCRIPTION:
*
* This routine extracts the_thread from the_thread_queue
* and insures that if there is a proxy for this task on
* and ensures that if there is a proxy for this task on
* another node, it is also dealt with.
*/
@@ -152,10 +154,8 @@ void _Thread_queue_Flush(
void _Thread_queue_Initialize(
Thread_queue_Control *the_thread_queue,
Objects_Classes the_class,
Thread_queue_Disciplines the_discipline,
States_Control state,
Thread_queue_Extract_callout proxy_extract_callout,
unsigned32 timeout_status
);

View File

@@ -3,7 +3,7 @@
* This include file contains the static inline implementation of all
* of the inlined routines in the Object Handler.
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2002.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -27,16 +27,34 @@
*/
RTEMS_INLINE_ROUTINE Objects_Id _Objects_Build_id(
Objects_Classes the_class,
Objects_APIs the_api,
unsigned32 the_class,
unsigned32 node,
unsigned32 index
)
{
return (( (Objects_Id) the_class ) << OBJECTS_CLASS_START_BIT) |
return (( (Objects_Id) the_api ) << OBJECTS_API_START_BIT) |
(( (Objects_Id) the_class ) << OBJECTS_CLASS_START_BIT) |
(( (Objects_Id) node ) << OBJECTS_NODE_START_BIT) |
(( (Objects_Id) index ) << OBJECTS_INDEX_START_BIT);
}
/*PAGE
*
* _Objects_Get_API
*
* DESCRIPTION:
*
* This function returns the API portion of the ID.
*/
RTEMS_INLINE_ROUTINE Objects_APIs _Objects_Get_API(
Objects_Id id
)
{
return (Objects_APIs) ((id >> OBJECTS_API_START_BIT) & OBJECTS_API_VALID_BITS);
}
/*PAGE
*
* _Objects_Get_class
@@ -46,15 +64,14 @@ RTEMS_INLINE_ROUTINE Objects_Id _Objects_Build_id(
* This function returns the class portion of the ID.
*/
RTEMS_INLINE_ROUTINE Objects_Classes _Objects_Get_class(
RTEMS_INLINE_ROUTINE unsigned32 _Objects_Get_class(
Objects_Id id
)
{
return (Objects_Classes)
return (unsigned32)
((id >> OBJECTS_CLASS_START_BIT) & OBJECTS_CLASS_VALID_BITS);
}
/*PAGE
*
* _Objects_Get_node
@@ -97,10 +114,11 @@ RTEMS_INLINE_ROUTINE unsigned32 _Objects_Get_index(
*/
RTEMS_INLINE_ROUTINE boolean _Objects_Is_class_valid(
Objects_Classes the_class
unsigned32 the_class
)
{
return the_class && the_class <= OBJECTS_CLASSES_LAST;
/* XXX how do we determine this now? */
return TRUE; /* the_class && the_class <= OBJECTS_CLASSES_LAST; */
}
/*PAGE
@@ -210,14 +228,17 @@ RTEMS_INLINE_ROUTINE Objects_Information *_Objects_Get_information(
Objects_Id id
)
{
Objects_Classes the_class;
Objects_APIs the_api;
unsigned32 the_class;
the_class = _Objects_Get_class( id );
if ( !_Objects_Is_class_valid( the_class ) )
return NULL;
return _Objects_Information_table[ the_class ];
the_api = _Objects_Get_API( id );
return _Objects_Information_table[ the_api ][ the_class ];
}
/*PAGE
@@ -245,7 +266,8 @@ RTEMS_INLINE_ROUTINE void _Objects_Open(
/* _Objects_Copy_name_string( name, the_object->name ); */
the_object->name = name;
else
_Objects_Copy_name_raw( name, the_object->name, information->name_length );
/* _Objects_Copy_name_raw( name, the_object->name, information->name_length ); */
the_object->name = name;
}
/*PAGE

View File

@@ -309,7 +309,8 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get (
Objects_Locations *location
)
{
Objects_Classes the_class;
unsigned32 the_api;
unsigned32 the_class;
Objects_Information *information;
Thread_Control *tp = (Thread_Control *) 0;
@@ -320,16 +321,21 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get (
goto done;
}
the_class = _Objects_Get_class( id );
if ( the_class > OBJECTS_CLASSES_LAST ) {
the_api = _Objects_Get_API( id );
if ( the_api && the_api > OBJECTS_APIS_LAST ) {
*location = OBJECTS_ERROR;
goto done;
}
information = _Objects_Information_table[ the_class ];
the_class = _Objects_Get_class( id );
if ( the_class != 1 ) { /* threads are always first class :) */
*location = OBJECTS_ERROR;
goto done;
}
if ( !information || !information->is_thread ) {
information = _Objects_Information_table[ the_api ][ the_class ];
if ( !information ) {
*location = OBJECTS_ERROR;
goto done;
}

View File

@@ -22,10 +22,20 @@
*
*/
#define _Objects_Build_id( _the_class, _node, _index ) \
( (( (Objects_Id) (_the_class) ) << OBJECTS_CLASS_START_BIT) | \
(( (Objects_Id) (_node) ) << OBJECTS_NODE_START_BIT) | \
(( (Objects_Id) (_index) ) << OBJECTS_INDEX_START_BIT) )
#define _Objects_Build_id( _the_api, _the_class, _node, _index ) \
( (( (Objects_Id) _the_api ) << OBJECTS_API_START_BIT) | \
(( (Objects_Id) _the_class ) << OBJECTS_CLASS_START_BIT) | \
(( (Objects_Id) _node ) << OBJECTS_NODE_START_BIT) | \
(( (Objects_Id) _index ) << OBJECTS_INDEX_START_BIT) )
/*PAGE
*
* _Objects_Get_API
*/
#define _Objects_Get_API( _id ) \
(Objects_APIs) \
(((_id) >> OBJECTS_API_START_BIT) & OBJECTS_API_VALID_BITS)
/*PAGE
*
@@ -33,7 +43,7 @@
*/
#define _Objects_Get_class( _id ) \
(Objects_Classes) \
(unsigned32) \
(((_id) >> OBJECTS_CLASS_START_BIT) & OBJECTS_CLASS_VALID_BITS)
/*PAGE
@@ -61,7 +71,7 @@
*/
#define _Objects_Is_class_valid( _the_class ) \
( (_the_class) && (_the_class) <= OBJECTS_CLASSES_LAST )
( (_the_class) /* XXX && (_the_class) <= OBJECTS_CLASSES_LAST */ )
/*PAGE
*
@@ -123,7 +133,8 @@
( \
( !_Objects_Is_class_valid( _Objects_Get_class( id ) ) ) ? \
NULL : \
_Objects_Information_table[ _Objects_Get_class( id ) ] \
_Objects_Information_table[ _Objects_Get_API( id ) ] \
[ _Objects_Get_class( id ) ] \
)
/*PAGE

View File

@@ -28,7 +28,7 @@ OBJECT_C_FILES = object.c objectallocate.c objectallocatebyindex.c \
objectcopynameraw.c objectcopynamestring.c objectextendinformation.c \
objectfree.c objectget.c objectgetisr.c objectgetbyindex.c \
objectgetnext.c objectinitializeinformation.c objectnametoid.c \
objectshrinkinformation.c
objectshrinkinformation.c objectgetnoprotection.c
THREAD_C_FILES = thread.c threadchangepriority.c threadclearstate.c \
threadclose.c threadcreateidle.c threaddelayended.c threaddispatch.c \
@@ -44,8 +44,7 @@ THREADQ_C_FILES = threadq.c threadqdequeue.c threadqdequeuefifo.c \
threadqdequeuepriority.c threadqenqueue.c threadqenqueuefifo.c \
threadqenqueuepriority.c threadqextract.c threadqextractfifo.c \
threadqextractpriority.c threadqextractwithproxy.c threadqfirst.c \
threadqfirstfifo.c threadqfirstpriority.c threadqflush.c \
threadqtimeout.c
threadqfirstfifo.c threadqfirstpriority.c threadqflush.c threadqtimeout.c
TOD_C_FILES = coretod.c coretodset.c coretodtickle.c coretodtoseconds.c \
coretodvalidate.c

View File

@@ -42,7 +42,6 @@
* the_message_queue_attributes - the message queue's attributes
* maximum_pending_messages - maximum message and reserved buffer count
* maximum_message_size - maximum size of each message
* proxy_extract_callout - remote extract support
*
* Output parameters:
* TRUE - if the message queue is initialized
@@ -51,11 +50,9 @@
boolean _CORE_message_queue_Initialize(
CORE_message_queue_Control *the_message_queue,
Objects_Classes the_class,
CORE_message_queue_Attributes *the_message_queue_attributes,
unsigned32 maximum_pending_messages,
unsigned32 maximum_message_size,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 maximum_message_size
)
{
unsigned32 message_buffering_required;
@@ -96,11 +93,9 @@ boolean _CORE_message_queue_Initialize(
_Thread_queue_Initialize(
&the_message_queue->Wait_queue,
the_class,
_CORE_message_queue_Is_priority( the_message_queue_attributes ) ?
THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
STATES_WAITING_FOR_MESSAGE,
proxy_extract_callout,
CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
);

View File

@@ -32,20 +32,16 @@
*
* Input parameters:
* the_mutex - the mutex control block to initialize
* the_class - the API class of the object
* the_mutex_attributes - the mutex attributes specified at create time
* initial_lock - mutex initial lock or unlocked status
* proxy_extract_callout - MP specific extract callout
*
* Output parameters: NONE
*/
void _CORE_mutex_Initialize(
CORE_mutex_Control *the_mutex,
Objects_Classes the_class,
CORE_mutex_Attributes *the_mutex_attributes,
unsigned32 initial_lock,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 initial_lock
)
{
@@ -84,11 +80,9 @@ void _CORE_mutex_Initialize(
_Thread_queue_Initialize(
&the_mutex->Wait_queue,
the_class,
_CORE_mutex_Is_fifo( the_mutex_attributes ) ?
THREAD_QUEUE_DISCIPLINE_FIFO : THREAD_QUEUE_DISCIPLINE_PRIORITY,
STATES_WAITING_FOR_MUTEX,
proxy_extract_callout,
CORE_MUTEX_TIMEOUT
);
}

View File

@@ -36,20 +36,16 @@
*
* Input parameters:
* the_semaphore - the semaphore control block to initialize
* the_class - the API class of the object
* the_semaphore_attributes - the attributes specified at create time
* initial_value - semaphore's initial value
* proxy_extract_callout - MP specific extract callout
*
* Output parameters: NONE
*/
void _CORE_semaphore_Initialize(
CORE_semaphore_Control *the_semaphore,
Objects_Classes the_class,
CORE_semaphore_Attributes *the_semaphore_attributes,
unsigned32 initial_value,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 initial_value
)
{
@@ -58,11 +54,9 @@ void _CORE_semaphore_Initialize(
_Thread_queue_Initialize(
&the_semaphore->Wait_queue,
the_class,
_CORE_semaphore_Is_priority( the_semaphore_attributes ) ?
THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
STATES_WAITING_FOR_SEMAPHORE,
proxy_extract_callout,
CORE_SEMAPHORE_TIMEOUT
);
}

View File

@@ -71,18 +71,14 @@ void _MPCI_Handler_initialization(
_CORE_semaphore_Initialize(
&_MPCI_Semaphore,
OBJECTS_NO_CLASS, /* free floating semaphore */
&attributes, /* the_semaphore_attributes */
0, /* initial_value */
NULL /* proxy_extract_callout */
0 /* initial_value */
);
_Thread_queue_Initialize(
&_MPCI_Remote_blocked_threads,
OBJECTS_NO_CLASS,
THREAD_QUEUE_DISCIPLINE_FIFO,
STATES_WAITING_FOR_RPC_REPLY,
NULL,
timeout_status
);
}

View File

@@ -37,13 +37,21 @@ boolean _Objects_Compare_name_raw(
unsigned32 length
)
{
#if 0
unsigned32 *name_1_p = (unsigned32 *) name_1;
unsigned32 *name_2_p = (unsigned32 *) name_2;
unsigned32 tmp_length = length / OBJECTS_NAME_ALIGNMENT;
#endif
if ( name_1 == name_2 )
return TRUE;
return FALSE;
#if 0
while ( tmp_length-- )
if ( *name_1_p++ != *name_2_p++ )
return FALSE;
return TRUE;
#endif
}

View File

@@ -208,9 +208,11 @@ void _Objects_Extend_information(
information->name_table = name_table;
information->local_table = local_table;
information->maximum = maximum;
information->maximum_id =
_Objects_Build_id(
information->the_class, _Objects_Local_node, information->maximum
information->maximum_id = _Objects_Build_id(
information->the_api,
information->the_class,
_Objects_Local_node,
information->maximum
);
_ISR_Enable( level );
@@ -268,9 +270,11 @@ void _Objects_Extend_information(
while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
the_object->id =
_Objects_Build_id(
information->the_class, _Objects_Local_node, index
the_object->id = _Objects_Build_id(
information->the_api,
information->the_class,
_Objects_Local_node,
index
);
the_object->name = (void *) name_area;

View File

@@ -0,0 +1,83 @@
/*
* Object Handler -- Object Get
*
*
* COPYRIGHT (c) 1989-2002.
* 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.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems/system.h>
#include <rtems/score/address.h>
#include <rtems/score/chain.h>
#include <rtems/score/object.h>
#if defined(RTEMS_MULTIPROCESSING)
#include <rtems/score/objectmp.h>
#endif
#include <rtems/score/thread.h>
#include <rtems/score/wkspace.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/isr.h>
/*PAGE
*
* _Objects_Get_no_protection
*
* This routine sets the object pointer for the given
* object id based on the given object information structure.
*
* Input parameters:
* information - pointer to entry in table for this class
* id - object id to search for
* location - address of where to store the location
*
* Output parameters:
* returns - address of object if local
* location - one of the following:
* OBJECTS_ERROR - invalid object ID
* OBJECTS_REMOTE - remote object
* OBJECTS_LOCAL - local object
*/
Objects_Control *_Objects_Get_no_protection(
Objects_Information *information,
Objects_Id id,
Objects_Locations *location
)
{
Objects_Control *the_object;
unsigned32 index;
#if defined(RTEMS_MULTIPROCESSING)
index = id - information->minimum_id + 1;
#else
/* index = _Objects_Get_index( id ); */
index = id & 0x0000ffff;
/* This should work but doesn't always :( */
/* index = (unsigned16) id; */
#endif
if ( information->maximum >= index ) {
if ( (the_object = information->local_table[ index ]) != NULL ) {
*location = OBJECTS_LOCAL;
return the_object;
}
*location = OBJECTS_ERROR;
return NULL;
}
*location = OBJECTS_ERROR;
/*
* Not supported for multiprocessing
*/
#if 0 && defined(RTEMS_MULTIPROCESSING)
_Objects_MP_Is_remote( information, id, location, &the_object );
return the_object;
#endif
return NULL;
}

View File

@@ -32,37 +32,42 @@
*
* Input parameters:
* information - object information table
* the_class - object class
* supports_global - TRUE if this is a global object class
* maximum - maximum objects of this class
* size - size of this object's control block
* is_string - TRUE if names for this object are strings
* maximum_name_length - maximum length of each object's name
* is_thread - TRUE if this class is threads
* When multiprocessing is configured,
* supports_global - TRUE if this is a global object class
* extract_callout - pointer to threadq extract callout if MP
*
* Output parameters: NONE
*/
void _Objects_Initialize_information(
Objects_Information *information,
Objects_Classes the_class,
boolean supports_global,
Objects_APIs the_api,
unsigned32 the_class,
unsigned32 maximum,
unsigned32 size,
boolean is_string,
unsigned32 maximum_name_length,
boolean is_thread
unsigned32 maximum_name_length
#if defined(RTEMS_MULTIPROCESSING)
,
boolean supports_global,
Objects_Thread_queue_Extract_callout *extract
#endif
)
{
static Objects_Control *null_local_table = NULL;
unsigned32 minimum_index;
unsigned32 index;
unsigned32 name_length;
#if defined(RTEMS_MULTIPROCESSING)
unsigned32 index;
#endif
information->the_api = the_api;
information->the_class = the_class;
information->is_string = is_string;
information->is_thread = is_thread;
information->local_table = 0;
information->name_table = 0;
@@ -75,7 +80,7 @@ void _Objects_Initialize_information(
* Set the entry in the object information table.
*/
_Objects_Information_table[ the_class ] = information;
_Objects_Information_table[ the_api ][ the_class ] = information;
/*
* Set the size of the object
@@ -110,7 +115,7 @@ void _Objects_Initialize_information(
else minimum_index = 1;
information->minimum_id =
_Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
_Objects_Build_id( the_api, the_class, _Objects_Local_node, minimum_index );
/*
* Calculate the maximum name length
@@ -153,6 +158,9 @@ void _Objects_Initialize_information(
* Take care of multiprocessing
*/
#if defined(RTEMS_MULTIPROCESSING)
information->extract = extract;
if ( supports_global == TRUE && _System_state_Is_multiprocessing ) {
information->global_table =
@@ -165,4 +173,5 @@ void _Objects_Initialize_information(
}
else
information->global_table = NULL;
#endif
}

View File

@@ -73,9 +73,7 @@ Objects_Name_to_id_errors _Objects_Name_to_id(
else compare_them = _Objects_Compare_name_raw;
for ( index = 1; index <= information->maximum; index++ ) {
the_object = information->local_table[ index ];
if ( !the_object || !the_object->name )
continue;

View File

@@ -90,13 +90,18 @@ void _Thread_Handler_initialization(
_Objects_Initialize_information(
&_Thread_Internal_information,
OBJECTS_INTERNAL_API,
OBJECTS_INTERNAL_THREADS,
FALSE,
( _System_state_Is_multiprocessing ) ? 2 : 1,
sizeof( Thread_Control ),
TRUE,
8,
TRUE
/* size of this object's control block */
TRUE, /* TRUE if names for this object are strings */
8 /* maximum length of each object's name */
#if defined(RTEMS_MULTIPROCESSING)
,
FALSE, /* TRUE if this is a global object class */
NULL /* Proxy extraction support callout */
#endif
);
}

View File

@@ -46,7 +46,6 @@ void _Thread_Close(
_Thread_Set_state( the_thread, STATES_TRANSIENT );
if ( !_Thread_queue_Extract_with_proxy( the_thread ) ) {
if ( _Watchdog_Is_active( &the_thread->Timer ) )
(void) _Watchdog_Remove( &the_thread->Timer );
}

View File

@@ -43,30 +43,41 @@ Thread_Control *_Thread_Get (
Objects_Locations *location
)
{
Objects_Classes the_class;
unsigned32 the_api;
unsigned32 the_class;
Objects_Information *information;
Thread_Control *tp = (Thread_Control *) 0;
if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) {
_Thread_Disable_dispatch();
*location = OBJECTS_LOCAL;
return( _Thread_Executing );
tp = _Thread_Executing;
goto done;
}
the_api = _Objects_Get_API( id );
if ( the_api && the_api > OBJECTS_APIS_LAST ) {
*location = OBJECTS_ERROR;
goto done;
}
the_class = _Objects_Get_class( id );
if ( the_class > OBJECTS_CLASSES_LAST ) {
if ( the_class != 1 ) { /* threads are always first class :) */
*location = OBJECTS_ERROR;
return (Thread_Control *) 0;
goto done;
}
information = _Objects_Information_table[ the_class ];
information = _Objects_Information_table[ the_api ][ the_class ];
if ( !information || !information->is_thread ) {
if ( !information ) {
*location = OBJECTS_ERROR;
return (Thread_Control *) 0;
goto done;
}
return (Thread_Control *) _Objects_Get( information, id, location );
tp = (Thread_Control *) _Objects_Get( information, id, location );
done:
return tp;
}
#endif

View File

@@ -29,10 +29,8 @@
*
* Input parameters:
* the_thread_queue - pointer to a threadq header
* the_class - class of the object to which this belongs
* discipline - queueing discipline
* state - state of waiting threads
* proxy_extract_callout - MP specific callout
* timeout_status - return on a timeout
*
* Output parameters: NONE
@@ -40,17 +38,13 @@
void _Thread_queue_Initialize(
Thread_queue_Control *the_thread_queue,
Objects_Classes the_class,
Thread_queue_Disciplines the_discipline,
States_Control state,
Thread_queue_Extract_callout proxy_extract_callout,
unsigned32 timeout_status
)
{
unsigned32 index;
_Thread_queue_Extract_table[ the_class ] = proxy_extract_callout;
the_thread_queue->state = state;
the_thread_queue->discipline = the_discipline;
the_thread_queue->timeout_status = timeout_status;

View File

@@ -26,7 +26,7 @@
* _Thread_queue_Extract_with_proxy
*
* This routine extracts the_thread from the_thread_queue
* and insures that if there is a proxy for this task on
* and ensures that if there is a proxy for this task on
* another node, it is also dealt with.
*
* XXX
@@ -37,8 +37,8 @@ boolean _Thread_queue_Extract_with_proxy(
)
{
States_Control state;
Objects_Classes the_class;
Thread_queue_Extract_callout proxy_extract_callout;
Objects_Information *the_information;
Objects_Thread_queue_Extract_callout proxy_extract_callout;
state = the_thread->current_state;
@@ -46,9 +46,10 @@ boolean _Thread_queue_Extract_with_proxy(
if ( _States_Is_waiting_for_rpc_reply( state ) &&
_States_Is_locally_blocked( state ) ) {
the_class = _Objects_Get_class( the_thread->Wait.id );
the_information = _Objects_Get_information( the_thread->Wait.id );
proxy_extract_callout = _Thread_queue_Extract_table[ the_class ];
proxy_extract_callout =
(Objects_Thread_queue_Extract_callout) the_information->extract;
if ( proxy_extract_callout )
(*proxy_extract_callout)( the_thread );

View File

@@ -1,3 +1,34 @@
2002-07-01 Joel Sherrill <joel@OARcorp.com>
* Mega patch merge to change the format of the object IDs to
loosen the dependency between the SCORE and the various APIs.
There was considerable work to simplify the object name management
and it appears that the name_table field is no longer needed.
This patch also includes the addition of the internal mutex
which is currently only used to protect some types of allocation
and deallocation. This significantly can reduce context
switch latency under certain circumstances. In particular,
some heap/region operations were O(n) and had dispatching
disabled. This should help enormously. With this merge,
the patch is not as clean as it should be. In particular,
the documentation has not been modified to reflect the new object
ID layout, the IDs in the test screens are not updated, and
_Objects_Get_information needs to be a real routine not inlined.
As part of this patch a lot of MP code for thread/proxy blocking
was made conditional and cleaned up.
* include/Makefile.am, include/rtems/score/coremsg.h,
include/rtems/score/coremutex.h, include/rtems/score/coresem.h,
include/rtems/score/object.h, include/rtems/score/threadq.h,
inline/rtems/score/object.inl, inline/rtems/score/thread.inl,
macros/rtems/score/object.inl, src/Makefile.am, src/coremsg.c,
src/coremutex.c, src/coresem.c, src/mpci.c,
src/objectcomparenameraw.c, src/objectextendinformation.c,
src/objectinitializeinformation.c, src/objectnametoid.c,
src/thread.c, src/threadclose.c, src/threadget.c, src/threadq.c,
src/threadqextractwithproxy.c: Modified as part of above.
* include/rtems/score/apimutex.h, src/objectgetnoprotection.c: New
files.
2001-05-17 Joel Sherrill <joel@OARcorp.com>
* macros/rtems/score/thread..inl: Implemented missing routines

View File

@@ -27,6 +27,7 @@ MP_H_FILES = rtems/score/mpci.h rtems/score/mppkt.h rtems/score/objectmp.h \
# H_FILES that get installed in the rtems/score subdirectoy
STD_H_FILES = rtems/score/address.h rtems/score/apiext.h \
rtems/score/apimutex.h \
rtems/score/bitfield.h rtems/score/chain.h rtems/score/context.h \
rtems/score/copyrt.h rtems/score/coremsg.h rtems/score/coremutex.h \
rtems/score/coresem.h rtems/score/heap.h rtems/score/interr.h \

View File

@@ -0,0 +1,153 @@
/* apimutex.h
*
* This include file contains all the constants and structures associated
* with the API Mutex Handler. This handler is used by API level
* routines to manage mutual exclusion.
*
* COPYRIGHT (c) 1989-2002.
* 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.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __API_MUTEX_h
#define __API_MUTEX_h
#ifdef __cplusplus
extern "C" {
#endif
#include <rtems/score/coremutex.h>
#include <rtems/score/isr.h>
#include <rtems/score/object.h>
/*
* The following defines the control block used to manage each mutex.
*/
typedef struct {
Objects_Control Object;
CORE_mutex_Control Mutex;
} API_Mutex_Control;
/*
* The following defines the information control block used to manage
* this class of objects.
*/
SCORE_EXTERN Objects_Information _API_Mutex_Information;
/*
* _API_Mutex_Initialization
*
* DESCRIPTION:
*
* This routine performs the initialization necessary for this handler.
*/
#if defined(RTEMS_MULTIPROCESSING)
#define _API_Mutex_Initialization( _maximum_mutexes ) \
_Objects_Initialize_information( \
&_API_Mutex_Information, \
OBJECTS_INTERNAL_API, \
OBJECTS_INTERNAL_MUTEXES, \
_maximum_mutexes, \
sizeof( API_Mutex_Control ), \
FALSE, \
0, \
FALSE, \
NULL \
);
#else
#define _API_Mutex_Initialization( _maximum_mutexes ) \
_Objects_Initialize_information( \
&_API_Mutex_Information, \
OBJECTS_INTERNAL_API, \
OBJECTS_INTERNAL_MUTEXES, \
_maximum_mutexes, \
sizeof( API_Mutex_Control ), \
FALSE, \
0 \
);
#endif
/*
* _API_Mutex_Allocate
*
* DESCRIPTION:
*
* This routine allocates an api mutex from the inactive set.
*/
#define _API_Mutex_Allocate( _the_mutex ) \
do { \
CORE_mutex_Attributes attr = \
{ CORE_MUTEX_NESTING_IS_ERROR, FALSE, \
CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT, 0 }; \
(_the_mutex) = (API_Mutex_Control *) \
_Objects_Allocate( &_API_Mutex_Information ); \
_CORE_mutex_Initialize( \
&(_the_mutex)->Mutex, &attr, CORE_MUTEX_UNLOCKED ); \
} while (0)
/*
* _API_Mutex_Lock
*
* DESCRIPTION:
*
* This routine acquires the specified api mutex.
*/
#define _API_Mutex_Lock( _the_mutex ) \
do { \
ISR_Level _level; \
_CORE_mutex_Seize( \
&(_the_mutex)->Mutex, (_the_mutex)->Object.id, TRUE, 0, (_level) ); \
} while (0)
/*
* _API_Mutex_Unlock
*
* DESCRIPTION:
*
* This routine releases the specified api mutex.
*/
#define _API_Mutex_Unlock( _the_mutex ) \
do { \
_Thread_Disable_dispatch(); \
_CORE_mutex_Surrender( \
&(_the_mutex)->Mutex, (_the_mutex)->Object.id, NULL ); \
_Thread_Enable_dispatch(); \
} while (0);
/*XXX when the APIs all use this for allocation and deallocation
*XXX protection, then they should be renamed and probably moved
*/
SCORE_EXTERN API_Mutex_Control *_RTEMS_Allocator_Mutex;
#define _RTEMS_Lock_allocator() \
_API_Mutex_Lock( _RTEMS_Allocator_Mutex )
#define _RTEMS_Unlock_allocator() \
_API_Mutex_Unlock( _RTEMS_Allocator_Mutex )
/*
* There are no inlines for this handler.
*/
#ifndef __RTEMS_APPLICATION__
/* #include <rtems/score/apimutex.inl> */
#endif
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -144,11 +144,9 @@ typedef struct {
boolean _CORE_message_queue_Initialize(
CORE_message_queue_Control *the_message_queue,
Objects_Classes the_class,
CORE_message_queue_Attributes *the_message_queue_attributes,
unsigned32 maximum_pending_messages,
unsigned32 maximum_message_size,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 maximum_message_size
);
/*

View File

@@ -134,10 +134,8 @@ typedef struct {
void _CORE_mutex_Initialize(
CORE_mutex_Control *the_mutex,
Objects_Classes the_class,
CORE_mutex_Attributes *the_mutex_attributes,
unsigned32 initial_lock,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 initial_lock
);
/*

View File

@@ -89,10 +89,8 @@ typedef struct {
void _CORE_semaphore_Initialize(
CORE_semaphore_Control *the_semaphore,
Objects_Classes the_class,
CORE_semaphore_Attributes *the_semaphore_attributes,
unsigned32 initial_value,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 initial_value
);
/*

View File

@@ -26,7 +26,8 @@ extern "C" {
#include <rtems/score/isr.h>
/*
* Mask to enable unlimited objects
* Mask to enable unlimited objects. This is used in the configuration
* table when specifying the number of configured objects.
*/
#define OBJECTS_UNLIMITED_OBJECTS 0x80000000
@@ -60,63 +61,95 @@ typedef boolean (*Objects_Name_comparators)(
* The following type defines the control block used to manage
* object IDs. The format is as follows (0=LSB):
*
* Bits 0 .. 15 = index
* Bits 16 .. 25 = node
* Bits 26 .. 31 = class
* Bits 0 .. 15 = index (up to 65535 objects of a type)
* Bits 16 .. 23 = node (up to 255 nodes)
* Bits 24 .. 26 = API (up to 7 API classes)
* Bits 27 .. 31 = class (up to 31 object types per API)
*/
typedef unsigned32 Objects_Id;
#define OBJECTS_INDEX_START_BIT 0
#define OBJECTS_NODE_START_BIT 16
#define OBJECTS_CLASS_START_BIT 26
#define OBJECTS_API_START_BIT 24
#define OBJECTS_CLASS_START_BIT 27
#define OBJECTS_INDEX_MASK 0x0000ffff
#define OBJECTS_NODE_MASK 0x03ff0000
#define OBJECTS_CLASS_MASK 0xfc000000
#define OBJECTS_NODE_MASK 0x00ff0000
#define OBJECTS_API_MASK 0x07000000
#define OBJECTS_CLASS_MASK 0xf8000000
#define OBJECTS_INDEX_VALID_BITS 0x0000ffff
#define OBJECTS_NODE_VALID_BITS 0x000003ff
#define OBJECTS_CLASS_VALID_BITS 0x000000cf
#define OBJECTS_NODE_VALID_BITS 0x000000ff
#define OBJECTS_API_VALID_BITS 0x00000007
#define OBJECTS_CLASS_VALID_BITS 0x0000001f
/*
* This enumerated type is used in the class field of the object ID.
*/
typedef enum {
OBJECTS_NO_CLASS = 0,
OBJECTS_INTERNAL_THREADS = 1,
OBJECTS_RTEMS_TASKS = 2,
OBJECTS_POSIX_THREADS = 3,
OBJECTS_ITRON_TASKS = 4,
OBJECTS_RTEMS_TIMERS = 5,
OBJECTS_RTEMS_SEMAPHORES = 6,
OBJECTS_RTEMS_MESSAGE_QUEUES = 7,
OBJECTS_RTEMS_PARTITIONS = 8,
OBJECTS_RTEMS_REGIONS = 9,
OBJECTS_RTEMS_PORTS = 10,
OBJECTS_RTEMS_PERIODS = 11,
OBJECTS_RTEMS_EXTENSIONS = 12,
OBJECTS_POSIX_KEYS = 13,
OBJECTS_POSIX_INTERRUPTS = 14,
OBJECTS_POSIX_MESSAGE_QUEUE_FDS = 15,
OBJECTS_POSIX_MESSAGE_QUEUES = 16,
OBJECTS_POSIX_MUTEXES = 17,
OBJECTS_POSIX_SEMAPHORES = 18,
OBJECTS_POSIX_CONDITION_VARIABLES = 19,
OBJECTS_ITRON_EVENTFLAGS = 10,
OBJECTS_ITRON_MAILBOXES = 21,
OBJECTS_ITRON_MESSAGE_BUFFERS = 22,
OBJECTS_ITRON_PORTS = 23,
OBJECTS_ITRON_SEMAPHORES = 24,
OBJECTS_ITRON_VARIABLE_MEMORY_POOLS = 25,
OBJECTS_ITRON_FIXED_MEMORY_POOLS = 26
} Objects_Classes;
#define OBJECTS_NO_CLASS 0
#define OBJECTS_CLASSES_FIRST OBJECTS_NO_CLASS
#define OBJECTS_CLASSES_LAST OBJECTS_ITRON_FIXED_MEMORY_POOLS
#define OBJECTS_CLASSES_FIRST_THREAD_CLASS OBJECTS_INTERNAL_THREADS
#define OBJECTS_CLASSES_LAST_THREAD_CLASS OBJECTS_ITRON_TASKS
typedef enum {
OBJECTS_NO_API = 0,
OBJECTS_INTERNAL_API = 1,
OBJECTS_CLASSIC_API = 2,
OBJECTS_POSIX_API = 3,
OBJECTS_ITRON_API = 4
} Objects_APIs;
#define OBJECTS_APIS_LAST OBJECTS_ITRON_API
typedef enum {
OBJECTS_INTERNAL_NO_CLASS = 0,
OBJECTS_INTERNAL_THREADS = 1,
OBJECTS_INTERNAL_MUTEXES = 2
} Objects_Internal_API;
#define OBJECTS_INTERNAL_CLASSES_LAST OBJECTS_INTERNAL_MUTEXES
typedef enum {
OBJECTS_CLASSIC_NO_CLASS = 0,
OBJECTS_RTEMS_TASKS = 1,
OBJECTS_RTEMS_TIMERS = 2,
OBJECTS_RTEMS_SEMAPHORES = 3,
OBJECTS_RTEMS_MESSAGE_QUEUES = 4,
OBJECTS_RTEMS_PARTITIONS = 5,
OBJECTS_RTEMS_REGIONS = 6,
OBJECTS_RTEMS_PORTS = 7,
OBJECTS_RTEMS_PERIODS = 8,
OBJECTS_RTEMS_EXTENSIONS = 9
} Objects_Classic_API;
#define OBJECTS_RTEMS_CLASSES_LAST OBJECTS_RTEMS_EXTENSIONS
typedef enum {
OBJECTS_POSIX_NO_CLASS = 0,
OBJECTS_POSIX_THREADS = 1,
OBJECTS_POSIX_KEYS = 2,
OBJECTS_POSIX_INTERRUPTS = 3,
OBJECTS_POSIX_MESSAGE_QUEUE_FDS = 4,
OBJECTS_POSIX_MESSAGE_QUEUES = 5,
OBJECTS_POSIX_MUTEXES = 6,
OBJECTS_POSIX_SEMAPHORES = 7,
OBJECTS_POSIX_CONDITION_VARIABLES = 8
} Objects_POSIX_API;
#define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_CONDITION_VARIABLES
typedef enum {
OBJECTS_ITRON_NO_CLASS = 0,
OBJECTS_ITRON_TASKS = 1,
OBJECTS_ITRON_EVENTFLAGS = 2,
OBJECTS_ITRON_MAILBOXES = 3,
OBJECTS_ITRON_MESSAGE_BUFFERS = 4,
OBJECTS_ITRON_PORTS = 5,
OBJECTS_ITRON_SEMAPHORES = 6,
OBJECTS_ITRON_VARIABLE_MEMORY_POOLS = 7,
OBJECTS_ITRON_FIXED_MEMORY_POOLS = 8
} Objects_ITRON_API;
#define OBJECTS_ITRON_CLASSES_LAST OBJECTS_ITRON_FIXED_MEMORY_POOLS
/*
* This enumerated type lists the locations which may be returned
@@ -130,6 +163,15 @@ typedef enum {
OBJECTS_ERROR = 2 /* id was invalid */
} Objects_Locations;
/*
* The following type defines the callout used when a local task
* is extracted from a remote thread queue (i.e. it's proxy must
* extracted from the remote queue).
*/
typedef void ( *Objects_Thread_queue_Extract_callout )( void * );
/*
* The following defines the Object Control Block used to manage
* each object local to this node.
@@ -147,7 +189,8 @@ typedef struct {
*/
typedef struct {
Objects_Classes the_class; /* Class of this object */
Objects_APIs the_api; /* API of this object */
unsigned32 the_class; /* class of this object */
Objects_Id minimum_id; /* minimum valid id of this type */
Objects_Id maximum_id; /* maximum valid id of this type */
unsigned32 maximum; /* maximum number of objects */
@@ -156,15 +199,16 @@ typedef struct {
unsigned32 size; /* size of the objects */
Objects_Control **local_table;
Objects_Name *name_table;
Chain_Control *global_table; /* pointer to global table */
Chain_Control Inactive; /* chain of inactive ctl blocks */
unsigned32 inactive; /* number of objects on the InActive list */
unsigned32 *inactive_per_block; /* used to release a block */
void **object_blocks; /* the object memory to remove */
boolean is_string; /* TRUE if names are strings */
unsigned32 name_length; /* maximum length of names */
boolean is_thread; /* TRUE if these are threads */
/* irregardless of API */
Objects_Thread_queue_Extract_callout *extract;
#if defined(RTEMS_MULTIPROCESSING)
Chain_Control *global_table; /* pointer to global table */
#endif
} Objects_Information;
/*
@@ -176,13 +220,13 @@ SCORE_EXTERN unsigned32 _Objects_Local_node;
SCORE_EXTERN unsigned32 _Objects_Maximum_nodes;
/*
* The following is the list of information blocks for each object
* The following is the list of information blocks per API for each object
* class. From the ID, we can go to one of these information blocks,
* and obtain a pointer to the appropriate object control block.
*/
SCORE_EXTERN Objects_Information
*_Objects_Information_table[OBJECTS_CLASSES_LAST + 1];
**_Objects_Information_table[OBJECTS_APIS_LAST + 1];
/*
* The following defines the constant which may be used
@@ -208,8 +252,8 @@ SCORE_EXTERN Objects_Information
#define OBJECTS_ID_INITIAL_INDEX (0)
#define OBJECTS_ID_FINAL_INDEX (0xffff)
#define OBJECTS_ID_INITIAL(_class, _node) \
_Objects_Build_id( (_class), (_node), OBJECTS_ID_INITIAL_INDEX )
#define OBJECTS_ID_INITIAL(_api, _class, _node) \
_Objects_Build_id( (_api), (_class), (_node), OBJECTS_ID_INITIAL_INDEX )
#define OBJECTS_ID_FINAL ((Objects_Id)~0)
@@ -268,13 +312,17 @@ void _Objects_Shrink_information(
void _Objects_Initialize_information (
Objects_Information *information,
Objects_Classes the_class,
boolean supports_global,
Objects_APIs the_api,
unsigned32 the_class,
unsigned32 maximum,
unsigned32 size,
boolean is_string,
unsigned32 maximum_name_length,
boolean is_task
unsigned32 maximum_name_length
#if defined(RTEMS_MULTIPROCESSING)
,
boolean supports_global,
Objects_Thread_queue_Extract_callout *extract
#endif
);
/*PAGE
@@ -460,6 +508,13 @@ Objects_Control *_Objects_Get_by_index (
Objects_Id id,
Objects_Locations *location
);
Objects_Control *_Objects_Get_no_protection(
Objects_Information *information,
Objects_Id id,
Objects_Locations *location
);
/*
* _Objects_Get_next
*

View File

@@ -47,12 +47,14 @@ typedef void ( *Thread_queue_Flush_callout )(
* extracted from the remote queue).
*/
#if 0
typedef void ( *Thread_queue_Extract_callout )(
Thread_Control *
);
SCORE_EXTERN Thread_queue_Extract_callout
_Thread_queue_Extract_table[ OBJECTS_CLASSES_LAST + 1 ];
#endif
/*
* _Thread_queue_Dequeue
@@ -103,7 +105,7 @@ void _Thread_queue_Extract(
* DESCRIPTION:
*
* This routine extracts the_thread from the_thread_queue
* and insures that if there is a proxy for this task on
* and ensures that if there is a proxy for this task on
* another node, it is also dealt with.
*/
@@ -152,10 +154,8 @@ void _Thread_queue_Flush(
void _Thread_queue_Initialize(
Thread_queue_Control *the_thread_queue,
Objects_Classes the_class,
Thread_queue_Disciplines the_discipline,
States_Control state,
Thread_queue_Extract_callout proxy_extract_callout,
unsigned32 timeout_status
);

View File

@@ -3,7 +3,7 @@
* This include file contains the static inline implementation of all
* of the inlined routines in the Object Handler.
*
* COPYRIGHT (c) 1989-1999.
* COPYRIGHT (c) 1989-2002.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
@@ -27,16 +27,34 @@
*/
RTEMS_INLINE_ROUTINE Objects_Id _Objects_Build_id(
Objects_Classes the_class,
Objects_APIs the_api,
unsigned32 the_class,
unsigned32 node,
unsigned32 index
)
{
return (( (Objects_Id) the_class ) << OBJECTS_CLASS_START_BIT) |
return (( (Objects_Id) the_api ) << OBJECTS_API_START_BIT) |
(( (Objects_Id) the_class ) << OBJECTS_CLASS_START_BIT) |
(( (Objects_Id) node ) << OBJECTS_NODE_START_BIT) |
(( (Objects_Id) index ) << OBJECTS_INDEX_START_BIT);
}
/*PAGE
*
* _Objects_Get_API
*
* DESCRIPTION:
*
* This function returns the API portion of the ID.
*/
RTEMS_INLINE_ROUTINE Objects_APIs _Objects_Get_API(
Objects_Id id
)
{
return (Objects_APIs) ((id >> OBJECTS_API_START_BIT) & OBJECTS_API_VALID_BITS);
}
/*PAGE
*
* _Objects_Get_class
@@ -46,15 +64,14 @@ RTEMS_INLINE_ROUTINE Objects_Id _Objects_Build_id(
* This function returns the class portion of the ID.
*/
RTEMS_INLINE_ROUTINE Objects_Classes _Objects_Get_class(
RTEMS_INLINE_ROUTINE unsigned32 _Objects_Get_class(
Objects_Id id
)
{
return (Objects_Classes)
return (unsigned32)
((id >> OBJECTS_CLASS_START_BIT) & OBJECTS_CLASS_VALID_BITS);
}
/*PAGE
*
* _Objects_Get_node
@@ -97,10 +114,11 @@ RTEMS_INLINE_ROUTINE unsigned32 _Objects_Get_index(
*/
RTEMS_INLINE_ROUTINE boolean _Objects_Is_class_valid(
Objects_Classes the_class
unsigned32 the_class
)
{
return the_class && the_class <= OBJECTS_CLASSES_LAST;
/* XXX how do we determine this now? */
return TRUE; /* the_class && the_class <= OBJECTS_CLASSES_LAST; */
}
/*PAGE
@@ -210,14 +228,17 @@ RTEMS_INLINE_ROUTINE Objects_Information *_Objects_Get_information(
Objects_Id id
)
{
Objects_Classes the_class;
Objects_APIs the_api;
unsigned32 the_class;
the_class = _Objects_Get_class( id );
if ( !_Objects_Is_class_valid( the_class ) )
return NULL;
return _Objects_Information_table[ the_class ];
the_api = _Objects_Get_API( id );
return _Objects_Information_table[ the_api ][ the_class ];
}
/*PAGE
@@ -245,7 +266,8 @@ RTEMS_INLINE_ROUTINE void _Objects_Open(
/* _Objects_Copy_name_string( name, the_object->name ); */
the_object->name = name;
else
_Objects_Copy_name_raw( name, the_object->name, information->name_length );
/* _Objects_Copy_name_raw( name, the_object->name, information->name_length ); */
the_object->name = name;
}
/*PAGE

View File

@@ -309,7 +309,8 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get (
Objects_Locations *location
)
{
Objects_Classes the_class;
unsigned32 the_api;
unsigned32 the_class;
Objects_Information *information;
Thread_Control *tp = (Thread_Control *) 0;
@@ -320,16 +321,21 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get (
goto done;
}
the_class = _Objects_Get_class( id );
if ( the_class > OBJECTS_CLASSES_LAST ) {
the_api = _Objects_Get_API( id );
if ( the_api && the_api > OBJECTS_APIS_LAST ) {
*location = OBJECTS_ERROR;
goto done;
}
information = _Objects_Information_table[ the_class ];
the_class = _Objects_Get_class( id );
if ( the_class != 1 ) { /* threads are always first class :) */
*location = OBJECTS_ERROR;
goto done;
}
if ( !information || !information->is_thread ) {
information = _Objects_Information_table[ the_api ][ the_class ];
if ( !information ) {
*location = OBJECTS_ERROR;
goto done;
}

View File

@@ -22,10 +22,20 @@
*
*/
#define _Objects_Build_id( _the_class, _node, _index ) \
( (( (Objects_Id) (_the_class) ) << OBJECTS_CLASS_START_BIT) | \
(( (Objects_Id) (_node) ) << OBJECTS_NODE_START_BIT) | \
(( (Objects_Id) (_index) ) << OBJECTS_INDEX_START_BIT) )
#define _Objects_Build_id( _the_api, _the_class, _node, _index ) \
( (( (Objects_Id) _the_api ) << OBJECTS_API_START_BIT) | \
(( (Objects_Id) _the_class ) << OBJECTS_CLASS_START_BIT) | \
(( (Objects_Id) _node ) << OBJECTS_NODE_START_BIT) | \
(( (Objects_Id) _index ) << OBJECTS_INDEX_START_BIT) )
/*PAGE
*
* _Objects_Get_API
*/
#define _Objects_Get_API( _id ) \
(Objects_APIs) \
(((_id) >> OBJECTS_API_START_BIT) & OBJECTS_API_VALID_BITS)
/*PAGE
*
@@ -33,7 +43,7 @@
*/
#define _Objects_Get_class( _id ) \
(Objects_Classes) \
(unsigned32) \
(((_id) >> OBJECTS_CLASS_START_BIT) & OBJECTS_CLASS_VALID_BITS)
/*PAGE
@@ -61,7 +71,7 @@
*/
#define _Objects_Is_class_valid( _the_class ) \
( (_the_class) && (_the_class) <= OBJECTS_CLASSES_LAST )
( (_the_class) /* XXX && (_the_class) <= OBJECTS_CLASSES_LAST */ )
/*PAGE
*
@@ -123,7 +133,8 @@
( \
( !_Objects_Is_class_valid( _Objects_Get_class( id ) ) ) ? \
NULL : \
_Objects_Information_table[ _Objects_Get_class( id ) ] \
_Objects_Information_table[ _Objects_Get_API( id ) ] \
[ _Objects_Get_class( id ) ] \
)
/*PAGE

View File

@@ -28,7 +28,7 @@ OBJECT_C_FILES = object.c objectallocate.c objectallocatebyindex.c \
objectcopynameraw.c objectcopynamestring.c objectextendinformation.c \
objectfree.c objectget.c objectgetisr.c objectgetbyindex.c \
objectgetnext.c objectinitializeinformation.c objectnametoid.c \
objectshrinkinformation.c
objectshrinkinformation.c objectgetnoprotection.c
THREAD_C_FILES = thread.c threadchangepriority.c threadclearstate.c \
threadclose.c threadcreateidle.c threaddelayended.c threaddispatch.c \
@@ -44,8 +44,7 @@ THREADQ_C_FILES = threadq.c threadqdequeue.c threadqdequeuefifo.c \
threadqdequeuepriority.c threadqenqueue.c threadqenqueuefifo.c \
threadqenqueuepriority.c threadqextract.c threadqextractfifo.c \
threadqextractpriority.c threadqextractwithproxy.c threadqfirst.c \
threadqfirstfifo.c threadqfirstpriority.c threadqflush.c \
threadqtimeout.c
threadqfirstfifo.c threadqfirstpriority.c threadqflush.c threadqtimeout.c
TOD_C_FILES = coretod.c coretodset.c coretodtickle.c coretodtoseconds.c \
coretodvalidate.c

View File

@@ -42,7 +42,6 @@
* the_message_queue_attributes - the message queue's attributes
* maximum_pending_messages - maximum message and reserved buffer count
* maximum_message_size - maximum size of each message
* proxy_extract_callout - remote extract support
*
* Output parameters:
* TRUE - if the message queue is initialized
@@ -51,11 +50,9 @@
boolean _CORE_message_queue_Initialize(
CORE_message_queue_Control *the_message_queue,
Objects_Classes the_class,
CORE_message_queue_Attributes *the_message_queue_attributes,
unsigned32 maximum_pending_messages,
unsigned32 maximum_message_size,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 maximum_message_size
)
{
unsigned32 message_buffering_required;
@@ -96,11 +93,9 @@ boolean _CORE_message_queue_Initialize(
_Thread_queue_Initialize(
&the_message_queue->Wait_queue,
the_class,
_CORE_message_queue_Is_priority( the_message_queue_attributes ) ?
THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
STATES_WAITING_FOR_MESSAGE,
proxy_extract_callout,
CORE_MESSAGE_QUEUE_STATUS_TIMEOUT
);

View File

@@ -32,20 +32,16 @@
*
* Input parameters:
* the_mutex - the mutex control block to initialize
* the_class - the API class of the object
* the_mutex_attributes - the mutex attributes specified at create time
* initial_lock - mutex initial lock or unlocked status
* proxy_extract_callout - MP specific extract callout
*
* Output parameters: NONE
*/
void _CORE_mutex_Initialize(
CORE_mutex_Control *the_mutex,
Objects_Classes the_class,
CORE_mutex_Attributes *the_mutex_attributes,
unsigned32 initial_lock,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 initial_lock
)
{
@@ -84,11 +80,9 @@ void _CORE_mutex_Initialize(
_Thread_queue_Initialize(
&the_mutex->Wait_queue,
the_class,
_CORE_mutex_Is_fifo( the_mutex_attributes ) ?
THREAD_QUEUE_DISCIPLINE_FIFO : THREAD_QUEUE_DISCIPLINE_PRIORITY,
STATES_WAITING_FOR_MUTEX,
proxy_extract_callout,
CORE_MUTEX_TIMEOUT
);
}

View File

@@ -36,20 +36,16 @@
*
* Input parameters:
* the_semaphore - the semaphore control block to initialize
* the_class - the API class of the object
* the_semaphore_attributes - the attributes specified at create time
* initial_value - semaphore's initial value
* proxy_extract_callout - MP specific extract callout
*
* Output parameters: NONE
*/
void _CORE_semaphore_Initialize(
CORE_semaphore_Control *the_semaphore,
Objects_Classes the_class,
CORE_semaphore_Attributes *the_semaphore_attributes,
unsigned32 initial_value,
Thread_queue_Extract_callout proxy_extract_callout
unsigned32 initial_value
)
{
@@ -58,11 +54,9 @@ void _CORE_semaphore_Initialize(
_Thread_queue_Initialize(
&the_semaphore->Wait_queue,
the_class,
_CORE_semaphore_Is_priority( the_semaphore_attributes ) ?
THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
STATES_WAITING_FOR_SEMAPHORE,
proxy_extract_callout,
CORE_SEMAPHORE_TIMEOUT
);
}

View File

@@ -71,18 +71,14 @@ void _MPCI_Handler_initialization(
_CORE_semaphore_Initialize(
&_MPCI_Semaphore,
OBJECTS_NO_CLASS, /* free floating semaphore */
&attributes, /* the_semaphore_attributes */
0, /* initial_value */
NULL /* proxy_extract_callout */
0 /* initial_value */
);
_Thread_queue_Initialize(
&_MPCI_Remote_blocked_threads,
OBJECTS_NO_CLASS,
THREAD_QUEUE_DISCIPLINE_FIFO,
STATES_WAITING_FOR_RPC_REPLY,
NULL,
timeout_status
);
}

View File

@@ -37,13 +37,21 @@ boolean _Objects_Compare_name_raw(
unsigned32 length
)
{
#if 0
unsigned32 *name_1_p = (unsigned32 *) name_1;
unsigned32 *name_2_p = (unsigned32 *) name_2;
unsigned32 tmp_length = length / OBJECTS_NAME_ALIGNMENT;
#endif
if ( name_1 == name_2 )
return TRUE;
return FALSE;
#if 0
while ( tmp_length-- )
if ( *name_1_p++ != *name_2_p++ )
return FALSE;
return TRUE;
#endif
}

View File

@@ -208,9 +208,11 @@ void _Objects_Extend_information(
information->name_table = name_table;
information->local_table = local_table;
information->maximum = maximum;
information->maximum_id =
_Objects_Build_id(
information->the_class, _Objects_Local_node, information->maximum
information->maximum_id = _Objects_Build_id(
information->the_api,
information->the_class,
_Objects_Local_node,
information->maximum
);
_ISR_Enable( level );
@@ -268,9 +270,11 @@ void _Objects_Extend_information(
while ( (the_object = (Objects_Control *) _Chain_Get( &Inactive ) ) != NULL ) {
the_object->id =
_Objects_Build_id(
information->the_class, _Objects_Local_node, index
the_object->id = _Objects_Build_id(
information->the_api,
information->the_class,
_Objects_Local_node,
index
);
the_object->name = (void *) name_area;

View File

@@ -0,0 +1,83 @@
/*
* Object Handler -- Object Get
*
*
* COPYRIGHT (c) 1989-2002.
* 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.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems/system.h>
#include <rtems/score/address.h>
#include <rtems/score/chain.h>
#include <rtems/score/object.h>
#if defined(RTEMS_MULTIPROCESSING)
#include <rtems/score/objectmp.h>
#endif
#include <rtems/score/thread.h>
#include <rtems/score/wkspace.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/isr.h>
/*PAGE
*
* _Objects_Get_no_protection
*
* This routine sets the object pointer for the given
* object id based on the given object information structure.
*
* Input parameters:
* information - pointer to entry in table for this class
* id - object id to search for
* location - address of where to store the location
*
* Output parameters:
* returns - address of object if local
* location - one of the following:
* OBJECTS_ERROR - invalid object ID
* OBJECTS_REMOTE - remote object
* OBJECTS_LOCAL - local object
*/
Objects_Control *_Objects_Get_no_protection(
Objects_Information *information,
Objects_Id id,
Objects_Locations *location
)
{
Objects_Control *the_object;
unsigned32 index;
#if defined(RTEMS_MULTIPROCESSING)
index = id - information->minimum_id + 1;
#else
/* index = _Objects_Get_index( id ); */
index = id & 0x0000ffff;
/* This should work but doesn't always :( */
/* index = (unsigned16) id; */
#endif
if ( information->maximum >= index ) {
if ( (the_object = information->local_table[ index ]) != NULL ) {
*location = OBJECTS_LOCAL;
return the_object;
}
*location = OBJECTS_ERROR;
return NULL;
}
*location = OBJECTS_ERROR;
/*
* Not supported for multiprocessing
*/
#if 0 && defined(RTEMS_MULTIPROCESSING)
_Objects_MP_Is_remote( information, id, location, &the_object );
return the_object;
#endif
return NULL;
}

View File

@@ -32,37 +32,42 @@
*
* Input parameters:
* information - object information table
* the_class - object class
* supports_global - TRUE if this is a global object class
* maximum - maximum objects of this class
* size - size of this object's control block
* is_string - TRUE if names for this object are strings
* maximum_name_length - maximum length of each object's name
* is_thread - TRUE if this class is threads
* When multiprocessing is configured,
* supports_global - TRUE if this is a global object class
* extract_callout - pointer to threadq extract callout if MP
*
* Output parameters: NONE
*/
void _Objects_Initialize_information(
Objects_Information *information,
Objects_Classes the_class,
boolean supports_global,
Objects_APIs the_api,
unsigned32 the_class,
unsigned32 maximum,
unsigned32 size,
boolean is_string,
unsigned32 maximum_name_length,
boolean is_thread
unsigned32 maximum_name_length
#if defined(RTEMS_MULTIPROCESSING)
,
boolean supports_global,
Objects_Thread_queue_Extract_callout *extract
#endif
)
{
static Objects_Control *null_local_table = NULL;
unsigned32 minimum_index;
unsigned32 index;
unsigned32 name_length;
#if defined(RTEMS_MULTIPROCESSING)
unsigned32 index;
#endif
information->the_api = the_api;
information->the_class = the_class;
information->is_string = is_string;
information->is_thread = is_thread;
information->local_table = 0;
information->name_table = 0;
@@ -75,7 +80,7 @@ void _Objects_Initialize_information(
* Set the entry in the object information table.
*/
_Objects_Information_table[ the_class ] = information;
_Objects_Information_table[ the_api ][ the_class ] = information;
/*
* Set the size of the object
@@ -110,7 +115,7 @@ void _Objects_Initialize_information(
else minimum_index = 1;
information->minimum_id =
_Objects_Build_id( the_class, _Objects_Local_node, minimum_index );
_Objects_Build_id( the_api, the_class, _Objects_Local_node, minimum_index );
/*
* Calculate the maximum name length
@@ -153,6 +158,9 @@ void _Objects_Initialize_information(
* Take care of multiprocessing
*/
#if defined(RTEMS_MULTIPROCESSING)
information->extract = extract;
if ( supports_global == TRUE && _System_state_Is_multiprocessing ) {
information->global_table =
@@ -165,4 +173,5 @@ void _Objects_Initialize_information(
}
else
information->global_table = NULL;
#endif
}

View File

@@ -73,9 +73,7 @@ Objects_Name_to_id_errors _Objects_Name_to_id(
else compare_them = _Objects_Compare_name_raw;
for ( index = 1; index <= information->maximum; index++ ) {
the_object = information->local_table[ index ];
if ( !the_object || !the_object->name )
continue;

View File

@@ -90,13 +90,18 @@ void _Thread_Handler_initialization(
_Objects_Initialize_information(
&_Thread_Internal_information,
OBJECTS_INTERNAL_API,
OBJECTS_INTERNAL_THREADS,
FALSE,
( _System_state_Is_multiprocessing ) ? 2 : 1,
sizeof( Thread_Control ),
TRUE,
8,
TRUE
/* size of this object's control block */
TRUE, /* TRUE if names for this object are strings */
8 /* maximum length of each object's name */
#if defined(RTEMS_MULTIPROCESSING)
,
FALSE, /* TRUE if this is a global object class */
NULL /* Proxy extraction support callout */
#endif
);
}

View File

@@ -46,7 +46,6 @@ void _Thread_Close(
_Thread_Set_state( the_thread, STATES_TRANSIENT );
if ( !_Thread_queue_Extract_with_proxy( the_thread ) ) {
if ( _Watchdog_Is_active( &the_thread->Timer ) )
(void) _Watchdog_Remove( &the_thread->Timer );
}

View File

@@ -43,30 +43,41 @@ Thread_Control *_Thread_Get (
Objects_Locations *location
)
{
Objects_Classes the_class;
unsigned32 the_api;
unsigned32 the_class;
Objects_Information *information;
Thread_Control *tp = (Thread_Control *) 0;
if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) {
_Thread_Disable_dispatch();
*location = OBJECTS_LOCAL;
return( _Thread_Executing );
tp = _Thread_Executing;
goto done;
}
the_api = _Objects_Get_API( id );
if ( the_api && the_api > OBJECTS_APIS_LAST ) {
*location = OBJECTS_ERROR;
goto done;
}
the_class = _Objects_Get_class( id );
if ( the_class > OBJECTS_CLASSES_LAST ) {
if ( the_class != 1 ) { /* threads are always first class :) */
*location = OBJECTS_ERROR;
return (Thread_Control *) 0;
goto done;
}
information = _Objects_Information_table[ the_class ];
information = _Objects_Information_table[ the_api ][ the_class ];
if ( !information || !information->is_thread ) {
if ( !information ) {
*location = OBJECTS_ERROR;
return (Thread_Control *) 0;
goto done;
}
return (Thread_Control *) _Objects_Get( information, id, location );
tp = (Thread_Control *) _Objects_Get( information, id, location );
done:
return tp;
}
#endif

View File

@@ -29,10 +29,8 @@
*
* Input parameters:
* the_thread_queue - pointer to a threadq header
* the_class - class of the object to which this belongs
* discipline - queueing discipline
* state - state of waiting threads
* proxy_extract_callout - MP specific callout
* timeout_status - return on a timeout
*
* Output parameters: NONE
@@ -40,17 +38,13 @@
void _Thread_queue_Initialize(
Thread_queue_Control *the_thread_queue,
Objects_Classes the_class,
Thread_queue_Disciplines the_discipline,
States_Control state,
Thread_queue_Extract_callout proxy_extract_callout,
unsigned32 timeout_status
)
{
unsigned32 index;
_Thread_queue_Extract_table[ the_class ] = proxy_extract_callout;
the_thread_queue->state = state;
the_thread_queue->discipline = the_discipline;
the_thread_queue->timeout_status = timeout_status;

View File

@@ -26,7 +26,7 @@
* _Thread_queue_Extract_with_proxy
*
* This routine extracts the_thread from the_thread_queue
* and insures that if there is a proxy for this task on
* and ensures that if there is a proxy for this task on
* another node, it is also dealt with.
*
* XXX
@@ -37,8 +37,8 @@ boolean _Thread_queue_Extract_with_proxy(
)
{
States_Control state;
Objects_Classes the_class;
Thread_queue_Extract_callout proxy_extract_callout;
Objects_Information *the_information;
Objects_Thread_queue_Extract_callout proxy_extract_callout;
state = the_thread->current_state;
@@ -46,9 +46,10 @@ boolean _Thread_queue_Extract_with_proxy(
if ( _States_Is_waiting_for_rpc_reply( state ) &&
_States_Is_locally_blocked( state ) ) {
the_class = _Objects_Get_class( the_thread->Wait.id );
the_information = _Objects_Get_information( the_thread->Wait.id );
proxy_extract_callout = _Thread_queue_Extract_table[ the_class ];
proxy_extract_callout =
(Objects_Thread_queue_Extract_callout) the_information->extract;
if ( proxy_extract_callout )
(*proxy_extract_callout)( the_thread );