From 23fec9f0e18dc4913fab818118f836af150b98f3 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 27 Mar 2014 14:16:12 +0100 Subject: score: PR2152: Use allocator mutex for objects Use allocator mutex for objects allocate/free. This prevents that the thread dispatch latency depends on the workspace/heap fragmentation. --- cpukit/libcsupport/src/resource_snapshot.c | 24 ++-- cpukit/posix/include/rtems/posix/pthreadimpl.h | 21 +--- cpukit/posix/include/rtems/posix/semaphoreimpl.h | 13 +- cpukit/posix/src/conddestroy.c | 8 +- cpukit/posix/src/condinit.c | 6 +- cpukit/posix/src/keycreate.c | 6 +- cpukit/posix/src/keydelete.c | 4 + cpukit/posix/src/mqueueclose.c | 4 + cpukit/posix/src/mqueuecreatesupp.c | 12 +- cpukit/posix/src/mqueueopen.c | 14 +-- cpukit/posix/src/mqueueunlink.c | 3 + cpukit/posix/src/mutexdestroy.c | 10 +- cpukit/posix/src/mutexinit.c | 9 +- cpukit/posix/src/pbarrierdestroy.c | 7 +- cpukit/posix/src/pbarrierinit.c | 12 +- cpukit/posix/src/prwlockdestroy.c | 8 +- cpukit/posix/src/prwlockinit.c | 9 +- cpukit/posix/src/pspindestroy.c | 7 +- cpukit/posix/src/pspininit.c | 7 +- cpukit/posix/src/pthreadcreate.c | 13 +- cpukit/posix/src/semaphorecreatesupp.c | 7 +- cpukit/posix/src/semclose.c | 4 + cpukit/posix/src/semdestroy.c | 4 + cpukit/posix/src/seminit.c | 2 + cpukit/posix/src/semopen.c | 11 +- cpukit/posix/src/semunlink.c | 11 +- cpukit/posix/src/timercreate.c | 8 +- cpukit/posix/src/timerdelete.c | 7 +- cpukit/rtems/Makefile.am | 1 - cpukit/rtems/include/rtems/rtems/messageimpl.h | 16 +-- cpukit/rtems/include/rtems/rtems/tasksimpl.h | 13 +- cpukit/rtems/src/barriercreate.c | 6 +- cpukit/rtems/src/barrierdelete.c | 8 +- cpukit/rtems/src/dpmemcreate.c | 8 +- cpukit/rtems/src/dpmemdelete.c | 6 +- cpukit/rtems/src/msgqallocate.c | 37 ------ cpukit/rtems/src/msgqcreate.c | 10 +- cpukit/rtems/src/msgqdelete.c | 9 +- cpukit/rtems/src/partcreate.c | 10 +- cpukit/rtems/src/partdelete.c | 9 +- cpukit/rtems/src/ratemoncreate.c | 8 +- cpukit/rtems/src/ratemondelete.c | 6 +- cpukit/rtems/src/regioncreate.c | 7 +- cpukit/rtems/src/regiondelete.c | 5 +- cpukit/rtems/src/regionextend.c | 3 +- cpukit/rtems/src/regiongetsegment.c | 3 +- cpukit/rtems/src/regionresizesegment.c | 3 +- cpukit/rtems/src/semcreate.c | 12 +- cpukit/rtems/src/semdelete.c | 11 +- cpukit/rtems/src/taskcreate.c | 13 +- cpukit/rtems/src/timercreate.c | 6 +- cpukit/rtems/src/timerdelete.c | 6 +- cpukit/sapi/src/extensioncreate.c | 8 +- cpukit/sapi/src/extensiondelete.c | 6 +- cpukit/score/include/rtems/score/objectimpl.h | 147 +++++++++++++++++++++-- cpukit/score/include/rtems/score/threadimpl.h | 7 +- cpukit/score/src/apimutex.c | 3 +- cpukit/score/src/objectactivecount.c | 10 +- cpukit/score/src/objectallocate.c | 27 ++++- cpukit/score/src/objectextendinformation.c | 49 ++++---- cpukit/score/src/objectfree.c | 5 +- cpukit/score/src/objectshrinkinformation.c | 5 +- testsuites/sptests/spobjgetnext/init.c | 2 + 63 files changed, 419 insertions(+), 317 deletions(-) delete mode 100644 cpukit/rtems/src/msgqallocate.c diff --git a/cpukit/libcsupport/src/resource_snapshot.c b/cpukit/libcsupport/src/resource_snapshot.c index 8c66f0f7c2..6f5038de31 100644 --- a/cpukit/libcsupport/src/resource_snapshot.c +++ b/cpukit/libcsupport/src/resource_snapshot.c @@ -98,38 +98,28 @@ static int open_files(void) return (int) rtems_libio_number_iops - free_count; } -static void free_all_delayed_blocks(void) -{ - #ifdef HEAP_PROTECTION - _RTEMS_Lock_allocator(); - _Thread_Disable_dispatch(); - _Heap_Protection_free_all_delayed_blocks( RTEMS_Malloc_Heap ); - _Heap_Protection_free_all_delayed_blocks( &_Workspace_Area ); - _Thread_Enable_dispatch(); - _RTEMS_Unlock_allocator(); - #endif -} - void rtems_resource_snapshot_take(rtems_resource_snapshot *snapshot) { uint32_t *active = &snapshot->rtems_api.active_barriers; size_t i; - free_all_delayed_blocks(); + _RTEMS_Lock_allocator(); _Thread_Kill_zombies(); - _Protected_heap_Get_information(RTEMS_Malloc_Heap, &snapshot->heap_info); - - _Thread_Disable_dispatch(); + #ifdef HEAP_PROTECTION + _Heap_Protection_free_all_delayed_blocks(RTEMS_Malloc_Heap); + _Heap_Protection_free_all_delayed_blocks(&_Workspace_Area); + #endif + _Heap_Get_information(RTEMS_Malloc_Heap, &snapshot->heap_info); _Heap_Get_information(&_Workspace_Area, &snapshot->workspace_info); for (i = 0; i < RTEMS_ARRAY_SIZE(objects_info_table); ++i) { active [i] = _Objects_Active_count(objects_info_table[i]); } - _Thread_Enable_dispatch(); + _RTEMS_Unlock_allocator(); #ifndef RTEMS_POSIX_API memset(&snapshot->posix_api, 0, sizeof(snapshot->posix_api)); diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h index 02d8bca0f5..d4a04e1281 100644 --- a/cpukit/posix/include/rtems/posix/pthreadimpl.h +++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h @@ -67,16 +67,6 @@ extern void (*_POSIX_Threads_Initialize_user_threads_p)(void); */ void _POSIX_Threads_Manager_initialization(void); -/** - * @brief Allocate POSIX thread control block. - * - * This function allocates a pthread control block from - * the inactive chain of free pthread control blocks. - * - * @return This method returns a newly allocated thread. - */ -RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void ); - /** * @brief Copy POSIX Thread attribute structure. * @@ -211,15 +201,14 @@ int rtems_pthread_attribute_compare( const pthread_attr_t *attr2 ); -/* - * _POSIX_Threads_Allocate - */ - -RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void ) +RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate(void) { + _Objects_Allocator_lock(); + _Thread_Kill_zombies(); - return (Thread_Control *) _Objects_Allocate( &_POSIX_Threads_Information ); + return (Thread_Control *) + _Objects_Allocate_unprotected( &_POSIX_Threads_Information ); } /* diff --git a/cpukit/posix/include/rtems/posix/semaphoreimpl.h b/cpukit/posix/include/rtems/posix/semaphoreimpl.h index 7754ee9ad7..df5e5238de 100644 --- a/cpukit/posix/include/rtems/posix/semaphoreimpl.h +++ b/cpukit/posix/include/rtems/posix/semaphoreimpl.h @@ -48,20 +48,13 @@ extern const int */ void _POSIX_Semaphore_Manager_initialization(void); -/** - * @brief POSIX Semaphore Allocate - * - * This function allocates a semaphore control block from - * the inactive chain of free semaphore control blocks. - */ - -RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Allocate( void ) +RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control * + _POSIX_Semaphore_Allocate_unprotected( void ) { return (POSIX_Semaphore_Control *) - _Objects_Allocate( &_POSIX_Semaphore_Information ); + _Objects_Allocate_unprotected( &_POSIX_Semaphore_Information ); } - /** * @brief POSIX Semaphore Free * diff --git a/cpukit/posix/src/conddestroy.c b/cpukit/posix/src/conddestroy.c index 75bf4cd621..cd437a9114 100644 --- a/cpukit/posix/src/conddestroy.c +++ b/cpukit/posix/src/conddestroy.c @@ -38,6 +38,7 @@ int pthread_cond_destroy( POSIX_Condition_variables_Control *the_cond; Objects_Locations location; + _Objects_Allocator_lock(); the_cond = _POSIX_Condition_variables_Get( cond, &location ); switch ( location ) { @@ -45,6 +46,7 @@ int pthread_cond_destroy( if ( _Thread_queue_First( &the_cond->Wait_queue ) ) { _Objects_Put( &the_cond->Object ); + _Objects_Allocator_unlock(); return EBUSY; } @@ -52,9 +54,9 @@ int pthread_cond_destroy( &_POSIX_Condition_variables_Information, &the_cond->Object ); - - _POSIX_Condition_variables_Free( the_cond ); _Objects_Put( &the_cond->Object ); + _POSIX_Condition_variables_Free( the_cond ); + _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -64,5 +66,7 @@ int pthread_cond_destroy( break; } + _Objects_Allocator_unlock(); + return EINVAL; } diff --git a/cpukit/posix/src/condinit.c b/cpukit/posix/src/condinit.c index a69bc8cfdc..81575f2b17 100644 --- a/cpukit/posix/src/condinit.c +++ b/cpukit/posix/src/condinit.c @@ -51,12 +51,10 @@ int pthread_cond_init( if ( !the_attr->is_initialized ) return EINVAL; - _Thread_Disable_dispatch(); - the_cond = _POSIX_Condition_variables_Allocate(); if ( !the_cond ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return ENOMEM; } @@ -79,7 +77,7 @@ int pthread_cond_init( *cond = the_cond->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/keycreate.c b/cpukit/posix/src/keycreate.c index a7f6c915cc..245ac9e3f3 100644 --- a/cpukit/posix/src/keycreate.c +++ b/cpukit/posix/src/keycreate.c @@ -38,18 +38,16 @@ int pthread_key_create( { POSIX_Keys_Control *the_key; - _Thread_Disable_dispatch(); - the_key = _POSIX_Keys_Allocate(); if ( !the_key ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return EAGAIN; } the_key->destructor = destructor; _Objects_Open_u32( &_POSIX_Keys_Information, &the_key->Object, 0 ); *key = the_key->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/keydelete.c b/cpukit/posix/src/keydelete.c index cd2b39802d..392558f0f8 100644 --- a/cpukit/posix/src/keydelete.c +++ b/cpukit/posix/src/keydelete.c @@ -38,6 +38,7 @@ int pthread_key_delete( POSIX_Keys_Control *the_key; Objects_Locations location; + _Objects_Allocator_lock(); the_key = _POSIX_Keys_Get( key, &location ); switch ( location ) { @@ -50,6 +51,7 @@ int pthread_key_delete( */ _POSIX_Keys_Free( the_key ); _Objects_Put(&the_key->Object); + _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -59,5 +61,7 @@ int pthread_key_delete( break; } + _Objects_Allocator_unlock(); + return EINVAL; } diff --git a/cpukit/posix/src/mqueueclose.c b/cpukit/posix/src/mqueueclose.c index 152fc7ec46..72a7cdc40e 100644 --- a/cpukit/posix/src/mqueueclose.c +++ b/cpukit/posix/src/mqueueclose.c @@ -57,6 +57,7 @@ int mq_close( POSIX_Message_queue_Control_fd *the_mq_fd; Objects_Locations location; + _Objects_Allocator_lock(); the_mq_fd = _POSIX_Message_queue_Get_fd( mqdes, &location ); if ( location == OBJECTS_LOCAL ) { /* OBJECTS_LOCAL: @@ -79,9 +80,12 @@ int mq_close( _POSIX_Message_queue_Free_fd( the_mq_fd ); _Objects_Put( &the_mq_fd->Object ); + _Objects_Allocator_unlock(); return 0; } + _Objects_Allocator_unlock(); + /* * OBJECTS_REMOTE: * OBJECTS_ERROR: diff --git a/cpukit/posix/src/mqueuecreatesupp.c b/cpukit/posix/src/mqueuecreatesupp.c index 056d35df1b..3be64b4cc4 100644 --- a/cpukit/posix/src/mqueuecreatesupp.c +++ b/cpukit/posix/src/mqueuecreatesupp.c @@ -62,8 +62,6 @@ int _POSIX_Message_queue_Create_support( /* length of name has already been validated */ - _Thread_Disable_dispatch(); - /* * There is no real basis for the default values. They will work * but were not compared against any existing implementation for @@ -75,12 +73,10 @@ int _POSIX_Message_queue_Create_support( attr.mq_msgsize = 16; } else { if ( attr_ptr->mq_maxmsg <= 0 ){ - _Thread_Enable_dispatch(); rtems_set_errno_and_return_minus_one( EINVAL ); } if ( attr_ptr->mq_msgsize <= 0 ){ - _Thread_Enable_dispatch(); rtems_set_errno_and_return_minus_one( EINVAL ); } @@ -89,7 +85,7 @@ int _POSIX_Message_queue_Create_support( the_mq = _POSIX_Message_queue_Allocate(); if ( !the_mq ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( ENFILE ); } @@ -100,7 +96,7 @@ int _POSIX_Message_queue_Create_support( name = _Workspace_String_duplicate( name_arg, name_len ); if ( !name ) { _POSIX_Message_queue_Free( the_mq ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( ENOMEM ); } @@ -128,7 +124,7 @@ int _POSIX_Message_queue_Create_support( _POSIX_Message_queue_Free( the_mq ); _Workspace_Free(name); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( ENOSPC ); } @@ -140,6 +136,6 @@ int _POSIX_Message_queue_Create_support( *message_queue = the_mq; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/mqueueopen.c b/cpukit/posix/src/mqueueopen.c index b33fc95d7a..43e4082b63 100644 --- a/cpukit/posix/src/mqueueopen.c +++ b/cpukit/posix/src/mqueueopen.c @@ -72,8 +72,6 @@ mqd_t mq_open( Objects_Locations location; size_t name_len; - _Thread_Disable_dispatch(); - if ( oflag & O_CREAT ) { va_start(arg, oflag); mode = va_arg( arg, mode_t ); @@ -83,7 +81,7 @@ mqd_t mq_open( the_mq_fd = _POSIX_Message_queue_Allocate_fd(); if ( !the_mq_fd ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( ENFILE ); } the_mq_fd->oflag = oflag; @@ -103,7 +101,7 @@ mqd_t mq_open( */ if ( !( status == ENOENT && (oflag & O_CREAT) ) ) { _POSIX_Message_queue_Free_fd( the_mq_fd ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one_cast( status, mqd_t ); } @@ -113,7 +111,7 @@ mqd_t mq_open( */ if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) { _POSIX_Message_queue_Free_fd( the_mq_fd ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one_cast( EEXIST, mqd_t ); } @@ -130,7 +128,7 @@ mqd_t mq_open( NULL ); _Thread_Enable_dispatch(); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return (mqd_t)the_mq_fd->Object.id; } @@ -152,7 +150,7 @@ mqd_t mq_open( */ if ( status == -1 ) { _POSIX_Message_queue_Free_fd( the_mq_fd ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return (mqd_t) -1; } @@ -163,7 +161,7 @@ mqd_t mq_open( NULL ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return (mqd_t) the_mq_fd->Object.id; } diff --git a/cpukit/posix/src/mqueueunlink.c b/cpukit/posix/src/mqueueunlink.c index 47a0f5a368..92b1976a43 100644 --- a/cpukit/posix/src/mqueueunlink.c +++ b/cpukit/posix/src/mqueueunlink.c @@ -46,11 +46,13 @@ int mq_unlink( Objects_Id the_mq_id; size_t name_len; + _Objects_Allocator_lock(); _Thread_Disable_dispatch(); status = _POSIX_Message_queue_Name_to_id( name, &the_mq_id, &name_len ); if ( status != 0 ) { _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( status ); } @@ -64,5 +66,6 @@ int mq_unlink( _POSIX_Message_queue_Delete( the_mq ); _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/mutexdestroy.c b/cpukit/posix/src/mutexdestroy.c index 0fad9a915f..fce78af715 100644 --- a/cpukit/posix/src/mutexdestroy.c +++ b/cpukit/posix/src/mutexdestroy.c @@ -39,6 +39,7 @@ int pthread_mutex_destroy( register POSIX_Mutex_Control *the_mutex; Objects_Locations location; + _Objects_Allocator_lock(); the_mutex = _POSIX_Mutex_Get( mutex, &location ); switch ( location ) { @@ -50,15 +51,16 @@ int pthread_mutex_destroy( if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) { _Objects_Put( &the_mutex->Object ); + _Objects_Allocator_unlock(); return EBUSY; } _Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object ); - _CORE_mutex_Flush( &the_mutex->Mutex, NULL, EINVAL ); - - _POSIX_Mutex_Free( the_mutex ); _Objects_Put( &the_mutex->Object ); + _POSIX_Mutex_Free( the_mutex ); + _Objects_Allocator_unlock(); + return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -68,5 +70,7 @@ int pthread_mutex_destroy( break; } + _Objects_Allocator_unlock(); + return EINVAL; } diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c index d41b4c79ba..73d3101b28 100644 --- a/cpukit/posix/src/mutexinit.c +++ b/cpukit/posix/src/mutexinit.c @@ -149,15 +149,10 @@ int pthread_mutex_init( } #endif - /* - * Enter a dispatching critical section and begin to do the real work. - */ - _Thread_Disable_dispatch(); - the_mutex = _POSIX_Mutex_Allocate(); if ( !the_mutex ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return EAGAIN; } @@ -188,6 +183,6 @@ int pthread_mutex_init( *mutex = the_mutex->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/pbarrierdestroy.c b/cpukit/posix/src/pbarrierdestroy.c index d2eb50530d..4b9a0fdca9 100644 --- a/cpukit/posix/src/pbarrierdestroy.c +++ b/cpukit/posix/src/pbarrierdestroy.c @@ -45,6 +45,7 @@ int pthread_barrier_destroy( if ( !barrier ) return EINVAL; + _Objects_Allocator_lock(); the_barrier = _POSIX_Barrier_Get( barrier, &location ); switch ( location ) { @@ -55,10 +56,10 @@ int pthread_barrier_destroy( } _Objects_Close( &_POSIX_Barrier_Information, &the_barrier->Object ); + _Objects_Put( &the_barrier->Object ); _POSIX_Barrier_Free( the_barrier ); - - _Objects_Put( &the_barrier->Object ); + _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -68,5 +69,7 @@ int pthread_barrier_destroy( break; } + _Objects_Allocator_unlock(); + return EINVAL; } diff --git a/cpukit/posix/src/pbarrierinit.c b/cpukit/posix/src/pbarrierinit.c index f2dda7827b..956085658b 100644 --- a/cpukit/posix/src/pbarrierinit.c +++ b/cpukit/posix/src/pbarrierinit.c @@ -92,15 +92,10 @@ int pthread_barrier_init( the_attributes.discipline = CORE_BARRIER_AUTOMATIC_RELEASE; the_attributes.maximum_count = count; - /* - * Enter dispatching critical section to allocate and initialize barrier - */ - _Thread_Disable_dispatch(); /* prevents deletion */ - the_barrier = _POSIX_Barrier_Allocate(); if ( !the_barrier ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return EAGAIN; } @@ -112,10 +107,7 @@ int pthread_barrier_init( 0 ); - /* - * Exit the critical section and return the user an operational barrier - */ *barrier = the_barrier->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/prwlockdestroy.c b/cpukit/posix/src/prwlockdestroy.c index 9054e921de..d1261ca4fb 100644 --- a/cpukit/posix/src/prwlockdestroy.c +++ b/cpukit/posix/src/prwlockdestroy.c @@ -44,6 +44,7 @@ int pthread_rwlock_destroy( if ( !rwlock ) return EINVAL; + _Objects_Allocator_lock(); the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); switch ( location ) { @@ -53,6 +54,7 @@ int pthread_rwlock_destroy( */ if ( _Thread_queue_First( &the_rwlock->RWLock.Wait_queue ) != NULL ) { _Objects_Put( &the_rwlock->Object ); + _Objects_Allocator_unlock(); return EBUSY; } @@ -61,10 +63,10 @@ int pthread_rwlock_destroy( */ _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object ); - + _Objects_Put( &the_rwlock->Object ); _POSIX_RWLock_Free( the_rwlock ); + _Objects_Allocator_unlock(); - _Objects_Put( &the_rwlock->Object ); return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -74,5 +76,7 @@ int pthread_rwlock_destroy( break; } + _Objects_Allocator_unlock(); + return EINVAL; } diff --git a/cpukit/posix/src/prwlockinit.c b/cpukit/posix/src/prwlockinit.c index 488b46b8c4..94973f6b78 100644 --- a/cpukit/posix/src/prwlockinit.c +++ b/cpukit/posix/src/prwlockinit.c @@ -88,15 +88,10 @@ int pthread_rwlock_init( */ _CORE_RWLock_Initialize_attributes( &the_attributes ); - /* - * Enter dispatching critical section to allocate and initialize RWLock - */ - _Thread_Disable_dispatch(); /* prevents deletion */ - the_rwlock = _POSIX_RWLock_Allocate(); if ( !the_rwlock ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return EAGAIN; } @@ -110,6 +105,6 @@ int pthread_rwlock_init( *rwlock = the_rwlock->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/pspindestroy.c b/cpukit/posix/src/pspindestroy.c index 7795a33764..ab45ad1e92 100644 --- a/cpukit/posix/src/pspindestroy.c +++ b/cpukit/posix/src/pspindestroy.c @@ -45,6 +45,7 @@ int pthread_spin_destroy( if ( !spinlock ) return EINVAL; + _Objects_Allocator_lock(); the_spinlock = _POSIX_Spinlock_Get( spinlock, &location ); switch ( location ) { @@ -55,10 +56,10 @@ int pthread_spin_destroy( } _Objects_Close( &_POSIX_Spinlock_Information, &the_spinlock->Object ); - + _Objects_Put( &the_spinlock->Object ); _POSIX_Spinlock_Free( the_spinlock ); + _Objects_Allocator_unlock(); - _Objects_Put( &the_spinlock->Object ); return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -68,5 +69,7 @@ int pthread_spin_destroy( break; } + _Objects_Allocator_unlock(); + return EINVAL; } diff --git a/cpukit/posix/src/pspininit.c b/cpukit/posix/src/pspininit.c index 6030ed00e5..02b07c8468 100644 --- a/cpukit/posix/src/pspininit.c +++ b/cpukit/posix/src/pspininit.c @@ -49,7 +49,6 @@ int pthread_spin_init( POSIX_Spinlock_Control *the_spinlock; CORE_spinlock_Attributes attributes; - if ( !spinlock ) return EINVAL; @@ -61,12 +60,10 @@ int pthread_spin_init( return EINVAL; } - _Thread_Disable_dispatch(); /* prevents deletion */ - the_spinlock = _POSIX_Spinlock_Allocate(); if ( !the_spinlock ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return EAGAIN; } @@ -78,6 +75,6 @@ int pthread_spin_init( *spinlock = the_spinlock->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index 5a6d929959..8d031335cc 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -155,11 +155,6 @@ int pthread_create( is_fp = false; #endif - /* - * Lock the allocator mutex for protection - */ - _RTEMS_Lock_allocator(); - /* * Allocate the thread control block. * @@ -167,7 +162,7 @@ int pthread_create( */ the_thread = _POSIX_Threads_Allocate(); if ( !the_thread ) { - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); return EAGAIN; } @@ -190,7 +185,7 @@ int pthread_create( ); if ( !status ) { _POSIX_Threads_Free( the_thread ); - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); return EAGAIN; } @@ -235,7 +230,7 @@ int pthread_create( if ( !status ) { _Thread_Enable_dispatch(); _POSIX_Threads_Free( the_thread ); - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); return EINVAL; } #endif @@ -254,6 +249,6 @@ int pthread_create( */ *thread = the_thread->Object.id; - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/semaphorecreatesupp.c b/cpukit/posix/src/semaphorecreatesupp.c index 54b5b46aee..7751a58c0e 100644 --- a/cpukit/posix/src/semaphorecreatesupp.c +++ b/cpukit/posix/src/semaphorecreatesupp.c @@ -56,11 +56,8 @@ int _POSIX_Semaphore_Create_support( if (pshared != 0) rtems_set_errno_and_return_minus_one( ENOSYS ); - _Thread_Disable_dispatch(); - - the_semaphore = _POSIX_Semaphore_Allocate(); + the_semaphore = _POSIX_Semaphore_Allocate_unprotected(); if ( !the_semaphore ) { - _Thread_Enable_dispatch(); rtems_set_errno_and_return_minus_one( ENOSPC ); } @@ -72,7 +69,6 @@ int _POSIX_Semaphore_Create_support( name = _Workspace_String_duplicate( name_arg, name_len ); if ( !name ) { _POSIX_Semaphore_Free( the_semaphore ); - _Thread_Enable_dispatch(); rtems_set_errno_and_return_minus_one( ENOMEM ); } } else { @@ -120,6 +116,5 @@ int _POSIX_Semaphore_Create_support( *the_sem = the_semaphore; - _Thread_Enable_dispatch(); return 0; } diff --git a/cpukit/posix/src/semclose.c b/cpukit/posix/src/semclose.c index 1c205bfb36..9dedc34c1a 100644 --- a/cpukit/posix/src/semclose.c +++ b/cpukit/posix/src/semclose.c @@ -38,6 +38,7 @@ int sem_close( POSIX_Semaphore_Control *the_semaphore; Objects_Locations location; + _Objects_Allocator_lock(); the_semaphore = _POSIX_Semaphore_Get( sem, &location ); switch ( location ) { @@ -45,6 +46,7 @@ int sem_close( the_semaphore->open_count -= 1; _POSIX_Semaphore_Delete( the_semaphore ); _Objects_Put( &the_semaphore->Object ); + _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -54,5 +56,7 @@ int sem_close( break; } + _Objects_Allocator_unlock(); + rtems_set_errno_and_return_minus_one( EINVAL ); } diff --git a/cpukit/posix/src/semdestroy.c b/cpukit/posix/src/semdestroy.c index 8c3f079f64..1c695bb837 100644 --- a/cpukit/posix/src/semdestroy.c +++ b/cpukit/posix/src/semdestroy.c @@ -38,6 +38,7 @@ int sem_destroy( POSIX_Semaphore_Control *the_semaphore; Objects_Locations location; + _Objects_Allocator_lock(); the_semaphore = _POSIX_Semaphore_Get( sem, &location ); switch ( location ) { @@ -53,6 +54,7 @@ int sem_destroy( _POSIX_Semaphore_Delete( the_semaphore ); _Objects_Put( &the_semaphore->Object ); + _Objects_Allocator_unlock(); return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -62,5 +64,7 @@ int sem_destroy( break; } + _Objects_Allocator_unlock(); + rtems_set_errno_and_return_minus_one( EINVAL ); } diff --git a/cpukit/posix/src/seminit.c b/cpukit/posix/src/seminit.c index 466b2d0a0c..a55a1c4e1b 100644 --- a/cpukit/posix/src/seminit.c +++ b/cpukit/posix/src/seminit.c @@ -47,6 +47,7 @@ int sem_init( if ( !sem ) rtems_set_errno_and_return_minus_one( EINVAL ); + _Objects_Allocator_lock(); status = _POSIX_Semaphore_Create_support( NULL, 0, @@ -54,6 +55,7 @@ int sem_init( value, &the_semaphore ); + _Objects_Allocator_unlock(); if ( status != -1 ) *sem = the_semaphore->Object.id; diff --git a/cpukit/posix/src/semopen.c b/cpukit/posix/src/semopen.c index 20e2e92c7b..0b98ca60f9 100644 --- a/cpukit/posix/src/semopen.c +++ b/cpukit/posix/src/semopen.c @@ -66,8 +66,6 @@ sem_t *sem_open( Objects_Locations location; size_t name_len; - _Thread_Disable_dispatch(); - if ( oflag & O_CREAT ) { va_start(arg, oflag); mode = va_arg( arg, mode_t ); @@ -75,6 +73,7 @@ sem_t *sem_open( va_end(arg); } + _Objects_Allocator_lock(); status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id, &name_len ); /* @@ -92,7 +91,7 @@ sem_t *sem_open( */ if ( !( status == ENOENT && (oflag & O_CREAT) ) ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one_cast( status, sem_t * ); } } else { @@ -102,14 +101,14 @@ sem_t *sem_open( */ if ( (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL) ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one_cast( EEXIST, sem_t * ); } the_semaphore = _POSIX_Semaphore_Get( (sem_t *) &the_semaphore_id, &location ); the_semaphore->open_count += 1; _Thread_Enable_dispatch(); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); goto return_id; } @@ -130,7 +129,7 @@ sem_t *sem_open( * errno was set by Create_support, so don't set it again. */ - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); if ( status == -1 ) return SEM_FAILED; diff --git a/cpukit/posix/src/semunlink.c b/cpukit/posix/src/semunlink.c index 180facc381..40d5660350 100644 --- a/cpukit/posix/src/semunlink.c +++ b/cpukit/posix/src/semunlink.c @@ -35,11 +35,12 @@ int sem_unlink( const char *name ) { - int status; - POSIX_Semaphore_Control *the_semaphore; - Objects_Id the_semaphore_id; - size_t name_len; + int status; + POSIX_Semaphore_Control *the_semaphore; + Objects_Id the_semaphore_id; + size_t name_len; + _Objects_Allocator_lock(); _Thread_Disable_dispatch(); status = _POSIX_Semaphore_Name_to_id( name, &the_semaphore_id, &name_len ); @@ -58,5 +59,7 @@ int sem_unlink( _POSIX_Semaphore_Delete( the_semaphore ); _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); + return 0; } diff --git a/cpukit/posix/src/timercreate.c b/cpukit/posix/src/timercreate.c index f55e2db8d6..6d822b3928 100644 --- a/cpukit/posix/src/timercreate.c +++ b/cpukit/posix/src/timercreate.c @@ -66,21 +66,19 @@ int timer_create( rtems_set_errno_and_return_minus_one( EINVAL ); } - _Thread_Disable_dispatch(); /* to prevent deletion */ - /* * Allocate a timer */ ptimer = _POSIX_Timer_Allocate(); if ( !ptimer ) { - _Objects_Put( &ptimer->Object ); + _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( EAGAIN ); } /* The data of the created timer are stored to use them later */ ptimer->state = POSIX_TIMER_STATE_CREATE_NEW; - ptimer->thread_id = _Thread_Executing->Object.id; + ptimer->thread_id = _Thread_Get_executing()->Object.id; if ( evp != NULL ) { ptimer->inf.sigev_notify = evp->sigev_notify; @@ -98,6 +96,6 @@ int timer_create( _Objects_Open_u32(&_POSIX_Timer_Information, &ptimer->Object, 0); *timerid = ptimer->Object.id; - _Objects_Put( &ptimer->Object ); + _Objects_Allocator_unlock(); return 0; } diff --git a/cpukit/posix/src/timerdelete.c b/cpukit/posix/src/timerdelete.c index 5ebf8f8660..71b25faed9 100644 --- a/cpukit/posix/src/timerdelete.c +++ b/cpukit/posix/src/timerdelete.c @@ -47,6 +47,7 @@ int timer_delete( POSIX_Timer_Control *ptimer; Objects_Locations location; + _Objects_Allocator_lock(); ptimer = _POSIX_Timer_Get( timerid, &location ); switch ( location ) { @@ -54,8 +55,10 @@ int timer_delete( _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object ); ptimer->state = POSIX_TIMER_STATE_FREE; (void) _Watchdog_Remove( &ptimer->Timer ); - _POSIX_Timer_Free( ptimer ); _Objects_Put( &ptimer->Object ); + _POSIX_Timer_Free( ptimer ); + _Objects_Allocator_unlock(); + return 0; #if defined(RTEMS_MULTIPROCESSING) @@ -65,5 +68,7 @@ int timer_delete( break; } + _Objects_Allocator_unlock(); + rtems_set_errno_and_return_minus_one( EINVAL ); } diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am index f89a896f2d..cf8ca3bb67 100644 --- a/cpukit/rtems/Makefile.am +++ b/cpukit/rtems/Makefile.am @@ -175,7 +175,6 @@ librtems_a_SOURCES += src/rtemstimerdata.c ## MESSAGE_QUEUE_C_FILES librtems_a_SOURCES += src/msg.c -librtems_a_SOURCES += src/msgqallocate.c librtems_a_SOURCES += src/msgqbroadcast.c librtems_a_SOURCES += src/msgqcreate.c librtems_a_SOURCES += src/msgqdelete.c diff --git a/cpukit/rtems/include/rtems/rtems/messageimpl.h b/cpukit/rtems/include/rtems/rtems/messageimpl.h index da87fd1d6f..714fb617dc 100644 --- a/cpukit/rtems/include/rtems/rtems/messageimpl.h +++ b/cpukit/rtems/include/rtems/rtems/messageimpl.h @@ -89,16 +89,6 @@ rtems_status_code _Message_queue_Submit( Message_queue_Submit_types submit_type ); -/** - * @brief Message Queue Allocate - * - * This function allocates a message queue control block from - * the inactive chain of free message queue control blocks. - * - * @retval the_message_queue filled in if successful, NULL otherwise - */ -Message_queue_Control *_Message_queue_Allocate (void); - /** * @brief Message queue Translate Core Message Queue Return Code * @@ -162,6 +152,12 @@ RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Get ( _Objects_Get( &_Message_queue_Information, id, location ); } +RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Allocate( void ) +{ + return (Message_queue_Control *) + _Objects_Allocate( &_Message_queue_Information ); +} + /**@}*/ #ifdef __cplusplus diff --git a/cpukit/rtems/include/rtems/rtems/tasksimpl.h b/cpukit/rtems/include/rtems/rtems/tasksimpl.h index 2a99812e26..c86d5914c2 100644 --- a/cpukit/rtems/include/rtems/rtems/tasksimpl.h +++ b/cpukit/rtems/include/rtems/rtems/tasksimpl.h @@ -77,17 +77,14 @@ void _RTEMS_Tasks_Invoke_task_variable_dtor( rtems_task_variable_t *tvp ); -/** - * @brief Allocates a task control block. - * - * This function allocates a task control block from - * the inactive chain of free task control blocks. - */ -RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate( void ) +RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate(void) { + _Objects_Allocator_lock(); + _Thread_Kill_zombies(); - return (Thread_Control *) _Objects_Allocate( &_RTEMS_tasks_Information ); + return (Thread_Control *) + _Objects_Allocate_unprotected( &_RTEMS_tasks_Information ); } /** diff --git a/cpukit/rtems/src/barriercreate.c b/cpukit/rtems/src/barriercreate.c index e865774b17..12a917fe60 100644 --- a/cpukit/rtems/src/barriercreate.c +++ b/cpukit/rtems/src/barriercreate.c @@ -68,12 +68,10 @@ rtems_status_code rtems_barrier_create( the_attributes.discipline = CORE_BARRIER_MANUAL_RELEASE; the_attributes.maximum_count = maximum_waiters; - _Thread_Disable_dispatch(); /* prevents deletion */ - the_barrier = _Barrier_Allocate(); if ( !the_barrier ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } @@ -89,6 +87,6 @@ rtems_status_code rtems_barrier_create( *id = the_barrier->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/barrierdelete.c b/cpukit/rtems/src/barrierdelete.c index 90fff5e8ef..2ea15502b3 100644 --- a/cpukit/rtems/src/barrierdelete.c +++ b/cpukit/rtems/src/barrierdelete.c @@ -28,6 +28,7 @@ rtems_status_code rtems_barrier_delete( Barrier_Control *the_barrier; Objects_Locations location; + _Objects_Allocator_lock(); the_barrier = _Barrier_Get( id, &location ); switch ( location ) { @@ -39,10 +40,9 @@ rtems_status_code rtems_barrier_delete( ); _Objects_Close( &_Barrier_Information, &the_barrier->Object ); - - _Barrier_Free( the_barrier ); - _Objects_Put( &the_barrier->Object ); + _Barrier_Free( the_barrier ); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) @@ -52,5 +52,7 @@ rtems_status_code rtems_barrier_delete( break; } + _Objects_Allocator_unlock(); + return RTEMS_INVALID_ID; } diff --git a/cpukit/rtems/src/dpmemcreate.c b/cpukit/rtems/src/dpmemcreate.c index 9ad1588a10..206a199c00 100644 --- a/cpukit/rtems/src/dpmemcreate.c +++ b/cpukit/rtems/src/dpmemcreate.c @@ -33,7 +33,7 @@ rtems_status_code rtems_port_create( rtems_id *id ) { - Dual_ported_memory_Control *the_port; + Dual_ported_memory_Control *the_port; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; @@ -45,12 +45,10 @@ rtems_status_code rtems_port_create( !_Addresses_Is_aligned( external_start ) ) return RTEMS_INVALID_ADDRESS; - _Thread_Disable_dispatch(); /* to prevent deletion */ - the_port = _Dual_ported_memory_Allocate(); if ( !the_port ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } @@ -65,6 +63,6 @@ rtems_status_code rtems_port_create( ); *id = the_port->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/dpmemdelete.c b/cpukit/rtems/src/dpmemdelete.c index d6b42ffcc0..6f11a53a0b 100644 --- a/cpukit/rtems/src/dpmemdelete.c +++ b/cpukit/rtems/src/dpmemdelete.c @@ -32,13 +32,15 @@ rtems_status_code rtems_port_delete( Dual_ported_memory_Control *the_port; Objects_Locations location; + _Objects_Allocator_lock(); the_port = _Dual_ported_memory_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object ); - _Dual_ported_memory_Free( the_port ); _Objects_Put( &the_port->Object ); + _Dual_ported_memory_Free( the_port ); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) @@ -48,5 +50,7 @@ rtems_status_code rtems_port_delete( break; } + _Objects_Allocator_unlock(); + return RTEMS_INVALID_ID; } diff --git a/cpukit/rtems/src/msgqallocate.c b/cpukit/rtems/src/msgqallocate.c deleted file mode 100644 index f5776f1687..0000000000 --- a/cpukit/rtems/src/msgqallocate.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file - * - * @brief Message Queue Allocate - * @ingroup ClassicMessageQueue - */ - -/* - * COPYRIGHT (c) 1989-1999. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Message_queue_Control *_Message_queue_Allocate(void) -{ - return (Message_queue_Control *) - _Objects_Allocate(&_Message_queue_Information); -} diff --git a/cpukit/rtems/src/msgqcreate.c b/cpukit/rtems/src/msgqcreate.c index 6f60773458..b18f3b2591 100644 --- a/cpukit/rtems/src/msgqcreate.c +++ b/cpukit/rtems/src/msgqcreate.c @@ -81,12 +81,10 @@ rtems_status_code rtems_message_queue_create( #endif #endif - _Thread_Disable_dispatch(); /* protects object pointer */ - the_message_queue = _Message_queue_Allocate(); if ( !the_message_queue ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } @@ -95,7 +93,7 @@ rtems_status_code rtems_message_queue_create( !( _Objects_MP_Allocate_and_open( &_Message_queue_Information, name, the_message_queue->Object.id, false ) ) ) { _Message_queue_Free( the_message_queue ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } #endif @@ -120,7 +118,7 @@ rtems_status_code rtems_message_queue_create( #endif _Message_queue_Free( the_message_queue ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_UNSATISFIED; } @@ -142,6 +140,6 @@ rtems_status_code rtems_message_queue_create( ); #endif - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/msgqdelete.c b/cpukit/rtems/src/msgqdelete.c index d3c07679f4..e2df2b9d9a 100644 --- a/cpukit/rtems/src/msgqdelete.c +++ b/cpukit/rtems/src/msgqdelete.c @@ -37,6 +37,7 @@ rtems_status_code rtems_message_queue_delete( Message_queue_Control *the_message_queue; Objects_Locations location; + _Objects_Allocator_lock(); the_message_queue = _Message_queue_Get( id, &location ); switch ( location ) { @@ -54,8 +55,6 @@ rtems_status_code rtems_message_queue_delete( CORE_MESSAGE_QUEUE_STATUS_WAS_DELETED ); - _Message_queue_Free( the_message_queue ); - #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( the_message_queue->attribute_set ) ) { _Objects_MP_Close( @@ -72,11 +71,13 @@ rtems_status_code rtems_message_queue_delete( } #endif _Objects_Put( &the_message_queue->Object ); + _Message_queue_Free( the_message_queue ); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: - _Thread_Dispatch(); + _Objects_Allocator_unlock(); return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; #endif @@ -84,5 +85,7 @@ rtems_status_code rtems_message_queue_delete( break; } + _Objects_Allocator_unlock(); + return RTEMS_INVALID_ID; } diff --git a/cpukit/rtems/src/partcreate.c b/cpukit/rtems/src/partcreate.c index 32758f8f65..e3544e71b2 100644 --- a/cpukit/rtems/src/partcreate.c +++ b/cpukit/rtems/src/partcreate.c @@ -53,7 +53,7 @@ rtems_status_code rtems_partition_create( rtems_id *id ) { - Partition_Control *the_partition; + Partition_Control *the_partition; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; @@ -77,12 +77,10 @@ rtems_status_code rtems_partition_create( return RTEMS_MP_NOT_CONFIGURED; #endif - _Thread_Disable_dispatch(); /* prevents deletion */ - the_partition = _Partition_Allocate(); if ( !the_partition ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } @@ -91,7 +89,7 @@ rtems_status_code rtems_partition_create( !( _Objects_MP_Allocate_and_open( &_Partition_Information, name, the_partition->Object.id, false ) ) ) { _Partition_Free( the_partition ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } #endif @@ -122,6 +120,6 @@ rtems_status_code rtems_partition_create( ); #endif - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/partdelete.c b/cpukit/rtems/src/partdelete.c index cc10abcded..032f73d3d0 100644 --- a/cpukit/rtems/src/partdelete.c +++ b/cpukit/rtems/src/partdelete.c @@ -29,13 +29,13 @@ rtems_status_code rtems_partition_delete( Partition_Control *the_partition; Objects_Locations location; + _Objects_Allocator_lock(); the_partition = _Partition_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: if ( the_partition->number_of_used_blocks == 0 ) { _Objects_Close( &_Partition_Information, &the_partition->Object ); - _Partition_Free( the_partition ); #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( the_partition->attribute_set ) ) { @@ -54,14 +54,17 @@ rtems_status_code rtems_partition_delete( #endif _Objects_Put( &the_partition->Object ); + _Partition_Free( the_partition ); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } _Objects_Put( &the_partition->Object ); + _Objects_Allocator_unlock(); return RTEMS_RESOURCE_IN_USE; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: - _Thread_Dispatch(); + _Objects_Allocator_unlock(); return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; #endif @@ -69,5 +72,7 @@ rtems_status_code rtems_partition_delete( break; } + _Objects_Allocator_unlock(); + return RTEMS_INVALID_ID; } diff --git a/cpukit/rtems/src/ratemoncreate.c b/cpukit/rtems/src/ratemoncreate.c index ce0e1de26b..1f597ec944 100644 --- a/cpukit/rtems/src/ratemoncreate.c +++ b/cpukit/rtems/src/ratemoncreate.c @@ -55,16 +55,14 @@ rtems_status_code rtems_rate_monotonic_create( if ( !id ) return RTEMS_INVALID_ADDRESS; - _Thread_Disable_dispatch(); /* to prevent deletion */ - the_period = _Rate_monotonic_Allocate(); if ( !the_period ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } - the_period->owner = _Thread_Executing; + the_period->owner = _Thread_Get_executing(); the_period->state = RATE_MONOTONIC_INACTIVE; _Watchdog_Initialize( &the_period->Timer, NULL, 0, NULL ); @@ -78,6 +76,6 @@ rtems_status_code rtems_rate_monotonic_create( ); *id = the_period->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/ratemondelete.c b/cpukit/rtems/src/ratemondelete.c index 0a9e6a49e2..36480beab1 100644 --- a/cpukit/rtems/src/ratemondelete.c +++ b/cpukit/rtems/src/ratemondelete.c @@ -30,6 +30,7 @@ rtems_status_code rtems_rate_monotonic_delete( Rate_monotonic_Control *the_period; Objects_Locations location; + _Objects_Allocator_lock(); the_period = _Rate_monotonic_Get( id, &location ); switch ( location ) { @@ -38,8 +39,9 @@ rtems_status_code rtems_rate_monotonic_delete( _Objects_Close( &_Rate_monotonic_Information, &the_period->Object ); (void) _Watchdog_Remove( &the_period->Timer ); the_period->state = RATE_MONOTONIC_INACTIVE; - _Rate_monotonic_Free( the_period ); _Objects_Put( &the_period->Object ); + _Rate_monotonic_Free( the_period ); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) @@ -49,5 +51,7 @@ rtems_status_code rtems_rate_monotonic_delete( break; } + _Objects_Allocator_unlock(); + return RTEMS_INVALID_ID; } diff --git a/cpukit/rtems/src/regioncreate.c b/cpukit/rtems/src/regioncreate.c index 3b4325e436..6c623c8250 100644 --- a/cpukit/rtems/src/regioncreate.c +++ b/cpukit/rtems/src/regioncreate.c @@ -66,9 +66,7 @@ rtems_status_code rtems_region_create( if ( !id ) return RTEMS_INVALID_ADDRESS; - _RTEMS_Lock_allocator(); /* to prevent deletion */ - - the_region = _Region_Allocate(); + the_region = _Region_Allocate(); if ( !the_region ) return_status = RTEMS_TOO_MANY; @@ -111,6 +109,7 @@ rtems_status_code rtems_region_create( } } - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); + return return_status; } diff --git a/cpukit/rtems/src/regiondelete.c b/cpukit/rtems/src/regiondelete.c index 5144db0464..5a2df7c009 100644 --- a/cpukit/rtems/src/regiondelete.c +++ b/cpukit/rtems/src/regiondelete.c @@ -34,7 +34,7 @@ rtems_status_code rtems_region_delete( rtems_status_code return_status; Region_Control *the_region; - _RTEMS_Lock_allocator(); + _Objects_Allocator_lock(); the_region = _Region_Get( id, &location ); switch ( location ) { @@ -61,6 +61,7 @@ rtems_status_code rtems_region_delete( break; } - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); + return return_status; } diff --git a/cpukit/rtems/src/regionextend.c b/cpukit/rtems/src/regionextend.c index 289377db91..65b68cdf1a 100644 --- a/cpukit/rtems/src/regionextend.c +++ b/cpukit/rtems/src/regionextend.c @@ -40,7 +40,7 @@ rtems_status_code rtems_region_extend( if ( !starting_address ) return RTEMS_INVALID_ADDRESS; - _RTEMS_Lock_allocator(); /* to prevent deletion */ + _RTEMS_Lock_allocator(); /* to prevent deletion */ the_region = _Region_Get( id, &location ); switch ( location ) { @@ -75,5 +75,6 @@ rtems_status_code rtems_region_extend( } _RTEMS_Unlock_allocator(); + return return_status; } diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c index 92b3a94b6d..4bd244551a 100644 --- a/cpukit/rtems/src/regiongetsegment.c +++ b/cpukit/rtems/src/regiongetsegment.c @@ -47,7 +47,7 @@ rtems_status_code rtems_region_get_segment( _RTEMS_Lock_allocator(); - executing = _Thread_Executing; + executing = _Thread_Get_executing(); the_region = _Region_Get( id, &location ); switch ( location ) { @@ -110,5 +110,6 @@ rtems_status_code rtems_region_get_segment( } _RTEMS_Unlock_allocator(); + return return_status; } diff --git a/cpukit/rtems/src/regionresizesegment.c b/cpukit/rtems/src/regionresizesegment.c index ff45215118..ee3499a729 100644 --- a/cpukit/rtems/src/regionresizesegment.c +++ b/cpukit/rtems/src/regionresizesegment.c @@ -64,7 +64,8 @@ rtems_status_code rtems_region_resize_segment( _Region_Debug_Walk( the_region, 8 ); if ( status == HEAP_RESIZE_SUCCESSFUL ) - _Region_Process_queue( the_region ); /* unlocks allocator */ + /* unlocks allocator */ + _Region_Process_queue( the_region ); else _RTEMS_Unlock_allocator(); diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c index bf9229e2ee..5cd9568a46 100644 --- a/cpukit/rtems/src/semcreate.c +++ b/cpukit/rtems/src/semcreate.c @@ -100,12 +100,10 @@ rtems_status_code rtems_semaphore_create( if ( !_Attributes_Is_counting_semaphore( attribute_set ) && ( count > 1 ) ) return RTEMS_INVALID_NUMBER; - _Thread_Disable_dispatch(); /* prevents deletion */ - the_semaphore = _Semaphore_Allocate(); if ( !the_semaphore ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } @@ -114,7 +112,7 @@ rtems_status_code rtems_semaphore_create( ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name, the_semaphore->Object.id, false ) ) ) { _Semaphore_Free( the_semaphore ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } #endif @@ -179,14 +177,14 @@ rtems_status_code rtems_semaphore_create( mutex_status = _CORE_mutex_Initialize( &the_semaphore->Core_control.mutex, - _Thread_Executing, + _Thread_Get_executing(), &the_mutex_attr, (count == 1) ? CORE_MUTEX_UNLOCKED : CORE_MUTEX_LOCKED ); if ( mutex_status == CORE_MUTEX_STATUS_CEILING_VIOLATED ) { _Semaphore_Free( the_semaphore ); - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_INVALID_PRIORITY; } } @@ -212,6 +210,6 @@ rtems_status_code rtems_semaphore_create( 0 /* Not used */ ); #endif - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c index ea82b7757d..6e7c5eafad 100644 --- a/cpukit/rtems/src/semdelete.c +++ b/cpukit/rtems/src/semdelete.c @@ -44,6 +44,8 @@ rtems_status_code rtems_semaphore_delete( Semaphore_Control *the_semaphore; Objects_Locations location; + _Objects_Allocator_lock(); + the_semaphore = _Semaphore_Get( id, &location ); switch ( location ) { @@ -53,6 +55,7 @@ rtems_status_code rtems_semaphore_delete( !_Attributes_Is_simple_binary_semaphore( the_semaphore->attribute_set ) ) { _Objects_Put( &the_semaphore->Object ); + _Objects_Allocator_unlock(); return RTEMS_RESOURCE_IN_USE; } _CORE_mutex_Flush( @@ -70,8 +73,6 @@ rtems_status_code rtems_semaphore_delete( _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); - _Semaphore_Free( the_semaphore ); - #if defined(RTEMS_MULTIPROCESSING) if ( _Attributes_Is_global( the_semaphore->attribute_set ) ) { @@ -85,12 +86,15 @@ rtems_status_code rtems_semaphore_delete( ); } #endif + _Objects_Put( &the_semaphore->Object ); + _Semaphore_Free( the_semaphore ); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: - _Thread_Dispatch(); + _Objects_Allocator_unlock(); return RTEMS_ILLEGAL_ON_REMOTE_OBJECT; #endif @@ -98,5 +102,6 @@ rtems_status_code rtems_semaphore_delete( break; } + _Objects_Allocator_unlock(); return RTEMS_INVALID_ID; } diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c index ae4e1883e4..35dd37c4e5 100644 --- a/cpukit/rtems/src/taskcreate.c +++ b/cpukit/rtems/src/taskcreate.c @@ -104,11 +104,6 @@ rtems_status_code rtems_task_create( * Make sure system is MP if this task is global */ - /* - * Lock the allocator mutex for protection - */ - _RTEMS_Lock_allocator(); - /* * Allocate the thread control block and -- if the task is global -- * allocate a global object control block. @@ -122,7 +117,7 @@ rtems_status_code rtems_task_create( the_thread = _RTEMS_tasks_Allocate(); if ( !the_thread ) { - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } @@ -132,7 +127,7 @@ rtems_status_code rtems_task_create( if ( _Objects_MP_Is_null_global_object( the_global_object ) ) { _RTEMS_tasks_Free( the_thread ); - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } } @@ -164,7 +159,7 @@ rtems_status_code rtems_task_create( _Objects_MP_Free_global_object( the_global_object ); #endif _RTEMS_tasks_Free( the_thread ); - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); return RTEMS_UNSATISFIED; } @@ -195,6 +190,6 @@ rtems_status_code rtems_task_create( } #endif - _RTEMS_Unlock_allocator(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/timercreate.c b/cpukit/rtems/src/timercreate.c index 35cdfab7fa..0b1c44bdc2 100644 --- a/cpukit/rtems/src/timercreate.c +++ b/cpukit/rtems/src/timercreate.c @@ -38,12 +38,10 @@ rtems_status_code rtems_timer_create( if ( !id ) return RTEMS_INVALID_ADDRESS; - _Thread_Disable_dispatch(); /* to prevent deletion */ - the_timer = _Timer_Allocate(); if ( !the_timer ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } @@ -57,6 +55,6 @@ rtems_status_code rtems_timer_create( ); *id = the_timer->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/timerdelete.c b/cpukit/rtems/src/timerdelete.c index a3cf52a978..19232c8096 100644 --- a/cpukit/rtems/src/timerdelete.c +++ b/cpukit/rtems/src/timerdelete.c @@ -32,14 +32,16 @@ rtems_status_code rtems_timer_delete( Timer_Control *the_timer; Objects_Locations location; + _Objects_Allocator_lock(); the_timer = _Timer_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _Objects_Close( &_Timer_Information, &the_timer->Object ); (void) _Watchdog_Remove( &the_timer->Ticker ); - _Timer_Free( the_timer ); _Objects_Put( &the_timer->Object ); + _Timer_Free( the_timer ); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) @@ -49,5 +51,7 @@ rtems_status_code rtems_timer_delete( break; } + _Objects_Allocator_unlock(); + return RTEMS_INVALID_ID; } diff --git a/cpukit/sapi/src/extensioncreate.c b/cpukit/sapi/src/extensioncreate.c index 1d7232f8c2..8442096527 100644 --- a/cpukit/sapi/src/extensioncreate.c +++ b/cpukit/sapi/src/extensioncreate.c @@ -39,16 +39,16 @@ rtems_status_code rtems_extension_create( if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; - _Thread_Disable_dispatch(); /* to prevent deletion */ - the_extension = _Extension_Allocate(); if ( !the_extension ) { - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_TOO_MANY; } + _Thread_Disable_dispatch(); _User_extensions_Add_set_with_table( &the_extension->Extension, extension_table ); + _Thread_Enable_dispatch(); _Objects_Open( &_Extension_Information, @@ -57,6 +57,6 @@ rtems_status_code rtems_extension_create( ); *id = the_extension->Object.id; - _Thread_Enable_dispatch(); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/sapi/src/extensiondelete.c b/cpukit/sapi/src/extensiondelete.c index 0eaaffd103..f851ea06c2 100644 --- a/cpukit/sapi/src/extensiondelete.c +++ b/cpukit/sapi/src/extensiondelete.c @@ -30,13 +30,15 @@ rtems_status_code rtems_extension_delete( Extension_Control *the_extension; Objects_Locations location; + _Objects_Allocator_lock(); the_extension = _Extension_Get( id, &location ); switch ( location ) { case OBJECTS_LOCAL: _User_extensions_Remove_set( &the_extension->Extension ); _Objects_Close( &_Extension_Information, &the_extension->Object ); - _Extension_Free( the_extension ); _Objects_Put( &the_extension->Object ); + _Extension_Free( the_extension ); + _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) @@ -46,5 +48,7 @@ rtems_status_code rtems_extension_delete( break; } + _Objects_Allocator_unlock(); + return RTEMS_INVALID_ID; } diff --git a/cpukit/score/include/rtems/score/objectimpl.h b/cpukit/score/include/rtems/score/objectimpl.h index 119f11d829..383f0a738b 100644 --- a/cpukit/score/include/rtems/score/objectimpl.h +++ b/cpukit/score/include/rtems/score/objectimpl.h @@ -20,6 +20,7 @@ #define _RTEMS_SCORE_OBJECTIMPL_H #include +#include #include #include @@ -264,25 +265,120 @@ unsigned int _Objects_API_maximum_class( ); /** - * @brief Allocate an object. + * @brief Allocates an object without locking the allocator mutex. * - * This function allocates an object control block from - * the inactive chain of free object control blocks. + * This function can be called in two contexts + * - the executing thread is the owner of the object allocator mutex, or + * - in case the system state is not up, e.g. during sequential system + * initialization. * - * @param[in] information points to an object class information block. + * @param[in] information The object information block. + * + * @retval NULL No object available. + * @retval object The allocated object. + * + * @see _Objects_Allocate() and _Objects_Free(). */ -Objects_Control *_Objects_Allocate( +Objects_Control *_Objects_Allocate_unprotected( Objects_Information *information ); /** - * @brief Free an object. + * @brief Allocates an object. * - * This function frees an object control block to the - * inactive chain of free object control blocks. + * This function locks the object allocator mutex via + * _Objects_Allocator_lock(). The caller must later unlock the object + * allocator mutex via _Objects_Allocator_unlock(). The caller must unlock the + * mutex in any case, even if the allocation failed due to resource shortage. * - * @param[in] information points to an object class information block. - * @param[in] the_object points to the object to deallocate. + * A typical object allocation code looks like this: + * @code + * rtems_status_code some_create( rtems_id *id ) + * { + * rtems_status_code sc; + * Some_Control *some; + * + * // The object allocator mutex protects the executing thread from + * // asynchronous thread restart and deletion. + * some = (Some_Control *) _Objects_Allocate( &_Some_Information ); + * + * if ( some != NULL ) { + * _Some_Initialize( some ); + * sc = RTEMS_SUCCESSFUL; + * } else { + * sc = RTEMS_TOO_MANY; + * } + * + * _Objects_Allocator_unlock(); + * + * return sc; + * } + * @endcode + * + * @param[in] information The object information block. + * + * @retval NULL No object available. + * @retval object The allocated object. + * + * @see _Objects_Free(). + */ +Objects_Control *_Objects_Allocate( Objects_Information *information ); + +/** + * @brief Frees an object. + * + * Appends the object to the chain of inactive objects. + * + * @param[in] information The object information block. + * @param[in] the_object The object to free. + * + * @see _Objects_Allocate(). + * + * A typical object deletion code looks like this: + * @code + * rtems_status_code some_delete( rtems_id id ) + * { + * rtems_status_code sc; + * Some_Control *some; + * Objects_Locations location; + * + * // The object allocator mutex protects the executing thread from + * // asynchronous thread restart and deletion. + * _Objects_Allocator_lock(); + * + * // This will disable thread dispatching, so this starts a thread dispatch + * // critical section. + * some = (Semaphore_Control *) + * _Objects_Get( &_Some_Information, id, &location ); + * + * switch ( location ) { + * case OBJECTS_LOCAL: + * // After the object close an object get with this identifier will + * // fail. + * _Objects_Close( &_Some_Information, &some->Object ); + * + * _Some_Delete( some ); + * + * // This enables thread dispatching, so the thread dispatch critical + * // section ends here. + * _Objects_Put( &some->Object ); + * + * // Thread dispatching is enabled. The object free is only protected + * // by the object allocator mutex. + * _Objects_Free( &_Some_Information, &some->Object ); + * + * sc = RTEMS_SUCCESSFUL; + * break; + * default: + * sc = RTEMS_INVALID_ID; + * break; + * } + * + * _Objects_Allocator_unlock(); + * + * return sc; + * } + * @endcode */ void _Objects_Free( Objects_Information *information, @@ -892,6 +988,37 @@ RTEMS_INLINE_ROUTINE void _Objects_Put_for_get_isr_disable( #endif } +/** + * @brief Locks the object allocator mutex. + * + * While holding the allocator mutex the executing thread is protected from + * asynchronous thread restart and deletion. + * + * The usage of the object allocator mutex with the thread life protection + * makes it possible to allocate and free objects without thread dispatching + * disabled. The usage of a unified workspace and unlimited objects may lead + * to heap fragmentation. Thus the execution time of the _Objects_Allocate() + * function may increase during system run-time. + * + * @see _Objects_Allocator_unlock() and _Objects_Allocate(). + */ +RTEMS_INLINE_ROUTINE void _Objects_Allocator_lock( void ) +{ + _RTEMS_Lock_allocator(); +} + +/** + * @brief Unlocks the object allocator mutex. + * + * In case the mutex is fully unlocked, then this function restores the + * previous thread life protection state and thus may not return if the + * executing thread was restarted or deleted in the mean-time. + */ +RTEMS_INLINE_ROUTINE void _Objects_Allocator_unlock( void ) +{ + _RTEMS_Unlock_allocator(); +} + /** @} */ #ifdef __cplusplus diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index d0c7933aa3..2ac8344577 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -590,13 +590,10 @@ RTEMS_INLINE_ROUTINE uint32_t _Thread_Get_maximum_internal_threads(void) return maximum_internal_threads; } -/** - * This routine allocates an internal thread. - */ - RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void ) { - return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information ); + return (Thread_Control *) + _Objects_Allocate_unprotected( &_Thread_Internal_information ); } RTEMS_INLINE_ROUTINE void _Thread_Request_dispatch_if_executing( diff --git a/cpukit/score/src/apimutex.c b/cpukit/score/src/apimutex.c index 18ac2db864..7899934183 100644 --- a/cpukit/score/src/apimutex.c +++ b/cpukit/score/src/apimutex.c @@ -58,7 +58,8 @@ void _API_Mutex_Allocate( 0 }; - mutex = (API_Mutex_Control *) _Objects_Allocate( &_API_Mutex_Information ); + mutex = (API_Mutex_Control *) + _Objects_Allocate_unprotected( &_API_Mutex_Information ); _CORE_mutex_Initialize( &mutex->Mutex, NULL, &attr, CORE_MUTEX_UNLOCKED ); diff --git a/cpukit/score/src/objectactivecount.c b/cpukit/score/src/objectactivecount.c index de34212f29..de3243afcb 100644 --- a/cpukit/score/src/objectactivecount.c +++ b/cpukit/score/src/objectactivecount.c @@ -17,14 +17,20 @@ #endif #include +#include #include Objects_Maximum _Objects_Active_count( const Objects_Information *information ) { - size_t inactive = _Chain_Node_count_unprotected( &information->Inactive ); - size_t maximum = information->maximum; + size_t inactive; + size_t maximum; + + _Assert( _Debug_Is_owner_of_allocator() ); + + inactive = _Chain_Node_count_unprotected( &information->Inactive ); + maximum = information->maximum; return (Objects_Maximum) ( maximum - inactive ); } diff --git a/cpukit/score/src/objectallocate.c b/cpukit/score/src/objectallocate.c index 842c49d77a..40a7cae82c 100644 --- a/cpukit/score/src/objectallocate.c +++ b/cpukit/score/src/objectallocate.c @@ -19,7 +19,9 @@ #endif #include +#include #include +#include /* #define RTEMS_DEBUG_OBJECT_ALLOCATION */ @@ -27,12 +29,24 @@ #include #endif -Objects_Control *_Objects_Allocate( +static Objects_Control *_Objects_Get_inactive( + Objects_Information *information +) +{ + return (Objects_Control *) _Chain_Get_unprotected( &information->Inactive ); +} + +Objects_Control *_Objects_Allocate_unprotected( Objects_Information *information ) { Objects_Control *the_object; + _Assert( + _Debug_Is_owner_of_allocator() + || !_System_state_Is_up( _System_state_Get() ) + ); + /* * If the application is using the optional manager stubs and * still attempts to create the object, the information block @@ -46,7 +60,7 @@ Objects_Control *_Objects_Allocate( * OK. The manager should be initialized and configured to have objects. * With any luck, it is safe to attempt to allocate an object. */ - the_object = (Objects_Control *) _Chain_Get( &information->Inactive ); + the_object = _Objects_Get_inactive( information ); if ( information->auto_extend ) { /* @@ -56,7 +70,7 @@ Objects_Control *_Objects_Allocate( if ( !the_object ) { _Objects_Extend_information( information ); - the_object = (Objects_Control *) _Chain_Get( &information->Inactive ); + the_object = _Objects_Get_inactive( information ); } if ( the_object ) { @@ -83,3 +97,10 @@ Objects_Control *_Objects_Allocate( return the_object; } + +Objects_Control *_Objects_Allocate( Objects_Information *information ) +{ + _RTEMS_Lock_allocator(); + + return _Objects_Allocate_unprotected( information ); +} diff --git a/cpukit/score/src/objectextendinformation.c b/cpukit/score/src/objectextendinformation.c index d11f927588..b1fcec7617 100644 --- a/cpukit/score/src/objectextendinformation.c +++ b/cpukit/score/src/objectextendinformation.c @@ -20,8 +20,10 @@ #include #include +#include #include #include +#include #include #include /* for memcpy() */ @@ -42,10 +44,10 @@ void _Objects_Extend_information( ) { Objects_Control *the_object; - Chain_Control Inactive; uint32_t block_count; uint32_t block; uint32_t index_base; + uint32_t index_end; uint32_t minimum_index; uint32_t index; uint32_t maximum; @@ -53,6 +55,11 @@ void _Objects_Extend_information( void *new_object_block; bool do_extend; + _Assert( + _Debug_Is_owner_of_allocator() + || !_System_state_Is_up( _System_state_Get() ) + ); + /* * Search for a free block of indexes. If we do NOT need to allocate or * extend the block table, then we will change do_extend. @@ -76,6 +83,7 @@ void _Objects_Extend_information( index_base += information->allocation_size; } } + index_end = index_base + information->allocation_size; maximum = (uint32_t) information->maximum + information->allocation_size; @@ -213,12 +221,11 @@ void _Objects_Extend_information( object_blocks[block_count] = NULL; inactive_per_block[block_count] = 0; - for ( index=index_base ; - index < ( information->allocation_size + index_base ); - index++ ) { + for ( index = index_base ; index < index_end ; ++index ) { local_table[ index ] = NULL; } + _Thread_Disable_dispatch(); _ISR_Disable( level ); old_tables = information->object_blocks; @@ -235,6 +242,7 @@ void _Objects_Extend_information( ); _ISR_Enable( level ); + _Thread_Enable_dispatch(); _Workspace_Free( old_tables ); @@ -247,32 +255,21 @@ void _Objects_Extend_information( information->object_blocks[ block ] = new_object_block; /* - * Initialize objects .. add to a local chain first. + * Append to inactive chain. */ - _Chain_Initialize( - &Inactive, - information->object_blocks[ block ], - information->allocation_size, - information->size - ); - - /* - * Move from the local chain, initialise, then append to the inactive chain - */ - index = index_base; - - while ((the_object = (Objects_Control *) _Chain_Get( &Inactive )) != NULL ) { - + the_object = information->object_blocks[ block ]; + for ( index = index_base ; index < index_end ; ++index ) { the_object->id = _Objects_Build_id( - information->the_api, - information->the_class, - _Objects_Local_node, - index - ); + information->the_api, + information->the_class, + _Objects_Local_node, + index + ); - _Chain_Append( &information->Inactive, &the_object->Node ); + _Chain_Append_unprotected( &information->Inactive, &the_object->Node ); - index++; + the_object = (Objects_Control *) + ( (char *) the_object + information->size ); } information->inactive_per_block[ block ] = information->allocation_size; diff --git a/cpukit/score/src/objectfree.c b/cpukit/score/src/objectfree.c index cc2fbac5a5..f1c0ee49b2 100644 --- a/cpukit/score/src/objectfree.c +++ b/cpukit/score/src/objectfree.c @@ -19,6 +19,7 @@ #endif #include +#include #include void _Objects_Free( @@ -28,7 +29,9 @@ void _Objects_Free( { uint32_t allocation_size = information->allocation_size; - _Chain_Append( &information->Inactive, &the_object->Node ); + _Assert( _Debug_Is_owner_of_allocator() ); + + _Chain_Append_unprotected( &information->Inactive, &the_object->Node ); if ( information->auto_extend ) { uint32_t block; diff --git a/cpukit/score/src/objectshrinkinformation.c b/cpukit/score/src/objectshrinkinformation.c index 9731c2179d..2f64cd2502 100644 --- a/cpukit/score/src/objectshrinkinformation.c +++ b/cpukit/score/src/objectshrinkinformation.c @@ -19,6 +19,7 @@ #endif #include +#include #include #include @@ -30,6 +31,8 @@ void _Objects_Shrink_information( uint32_t block; uint32_t index_base; + _Assert( _Debug_Is_owner_of_allocator() ); + /* * Search the list to find block or chunk with all objects inactive. */ @@ -55,7 +58,7 @@ void _Objects_Shrink_information( node = _Chain_Next( node ); if ( index >= index_base && index < index_end ) { - _Chain_Extract( &object->Node ); + _Chain_Extract_unprotected( &object->Node ); } } diff --git a/testsuites/sptests/spobjgetnext/init.c b/testsuites/sptests/spobjgetnext/init.c index 9682c346fe..2695190239 100644 --- a/testsuites/sptests/spobjgetnext/init.c +++ b/testsuites/sptests/spobjgetnext/init.c @@ -108,7 +108,9 @@ rtems_task Init( /* XXX try with a manager with no objects created */ puts( "Init - _Objects_Active_count" ); + _Objects_Allocator_lock(); active_count = _Objects_Active_count( info ); + _Objects_Allocator_unlock(); rtems_test_assert( active_count == 1 ); TEST_END(); -- cgit v1.2.3