forked from Imagelibrary/rtems
score: Add ISR lock to Objects_Control
This enables per-object SMP locks on SMP configurations and is the first step to support fine-grained locking. On uni-processor configuration there will be no overhead. The _Objects_Acquire() is intended to replace _Objects_Get_isr_disable(). Update #2273.
This commit is contained in:
@@ -202,6 +202,7 @@ libscore_a_SOURCES += src/objectallocate.c src/objectclose.c \
|
|||||||
src/objectgetinfo.c src/objectgetinfoid.c src/objectapimaximumclass.c \
|
src/objectgetinfo.c src/objectgetinfoid.c src/objectapimaximumclass.c \
|
||||||
src/objectnamespaceremove.c \
|
src/objectnamespaceremove.c \
|
||||||
src/objectactivecount.c
|
src/objectactivecount.c
|
||||||
|
libscore_a_SOURCES += src/objectacquire.c
|
||||||
|
|
||||||
## SCHEDULER_C_FILES
|
## SCHEDULER_C_FILES
|
||||||
libscore_a_SOURCES += src/log2table.c
|
libscore_a_SOURCES += src/log2table.c
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <rtems/score/basedefs.h>
|
#include <rtems/score/basedefs.h>
|
||||||
#include <rtems/score/cpu.h>
|
#include <rtems/score/cpu.h>
|
||||||
#include <rtems/score/chain.h>
|
#include <rtems/score/chain.h>
|
||||||
|
#include <rtems/score/isrlock.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -236,6 +237,8 @@ typedef struct {
|
|||||||
Objects_Id id;
|
Objects_Id id;
|
||||||
/** This is the object's name. */
|
/** This is the object's name. */
|
||||||
Objects_Name name;
|
Objects_Name name;
|
||||||
|
/** This is the object's ISR lock. */
|
||||||
|
ISR_LOCK_MEMBER( Lock )
|
||||||
} Objects_Control;
|
} Objects_Control;
|
||||||
|
|
||||||
#if defined( RTEMS_MULTIPROCESSING )
|
#if defined( RTEMS_MULTIPROCESSING )
|
||||||
|
|||||||
@@ -590,6 +590,83 @@ Objects_Control *_Objects_Get_no_protection(
|
|||||||
Objects_Locations *location
|
Objects_Locations *location
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Acquires an object by its identifier.
|
||||||
|
*
|
||||||
|
* This function is similar to _Objects_Get_isr_disable(). It acquires the
|
||||||
|
* object specific ISR lock for local objects. Thread dispatching is not
|
||||||
|
* disabled for local objects. For remote objects thread dispatching is
|
||||||
|
* disabled.
|
||||||
|
*
|
||||||
|
* @param[in] information The object information.
|
||||||
|
* @param[in] id The object identifier.
|
||||||
|
* @param[in] location The location of the object.
|
||||||
|
* @param[in] lock_context The lock context for local objects.
|
||||||
|
*
|
||||||
|
* @retval object The object corresponding to the identifier.
|
||||||
|
* @retval NULL No object exists in this domain for this identifer.
|
||||||
|
*
|
||||||
|
* @see _Objects_Release(), _Objects_Release_and_ISR_enable(), and
|
||||||
|
* _Objects_Release_and_thread_dispatch_disable().
|
||||||
|
*/
|
||||||
|
Objects_Control *_Objects_Acquire(
|
||||||
|
const Objects_Information *information,
|
||||||
|
Objects_Id id,
|
||||||
|
Objects_Locations *location,
|
||||||
|
ISR_lock_Context *lock_context
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Releases a local object.
|
||||||
|
*
|
||||||
|
* @param[in] the_object The local object acquired by _Objects_Acquire().
|
||||||
|
* @param[in] lock_context The lock context initialized by _Objects_Acquire().
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void _Objects_Release(
|
||||||
|
Objects_Control *the_object,
|
||||||
|
ISR_lock_Context *lock_context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_ISR_lock_Release( &the_object->Lock, lock_context );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Releases a local object and restores the interrupt level.
|
||||||
|
*
|
||||||
|
* @param[in] the_object The local object acquired by _Objects_Acquire().
|
||||||
|
* @param[in] lock_context The lock context initialized by _Objects_Acquire().
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE void _Objects_Release_and_ISR_enable(
|
||||||
|
Objects_Control *the_object,
|
||||||
|
ISR_lock_Context *lock_context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &the_object->Lock, lock_context );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Releases a local object, disables thread dispatching and restores the
|
||||||
|
* interrupt level.
|
||||||
|
*
|
||||||
|
* @param[in] the_object The local object acquired by _Objects_Acquire().
|
||||||
|
* @param[in] lock_context The lock context initialized by _Objects_Acquire().
|
||||||
|
*
|
||||||
|
* @return The current processor.
|
||||||
|
*/
|
||||||
|
RTEMS_INLINE_ROUTINE Per_CPU_Control *
|
||||||
|
_Objects_Release_and_thread_dispatch_disable(
|
||||||
|
Objects_Control *the_object,
|
||||||
|
ISR_lock_Context *lock_context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Per_CPU_Control *cpu_self = _Per_CPU_Get();
|
||||||
|
|
||||||
|
_Thread_Dispatch_disable_critical( cpu_self );
|
||||||
|
_Objects_Release_and_ISR_enable( the_object, lock_context );
|
||||||
|
|
||||||
|
return cpu_self;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like @ref _Objects_Get, but is used to find "next" open object.
|
* Like @ref _Objects_Get, but is used to find "next" open object.
|
||||||
*
|
*
|
||||||
@@ -903,6 +980,7 @@ RTEMS_INLINE_ROUTINE void _Objects_Open(
|
|||||||
_Assert( the_object != NULL );
|
_Assert( the_object != NULL );
|
||||||
|
|
||||||
the_object->name = name;
|
the_object->name = name;
|
||||||
|
_ISR_lock_Initialize( &the_object->Lock, "Object" );
|
||||||
|
|
||||||
_Objects_Set_local_object(
|
_Objects_Set_local_object(
|
||||||
information,
|
information,
|
||||||
@@ -927,6 +1005,7 @@ RTEMS_INLINE_ROUTINE void _Objects_Open_u32(
|
|||||||
{
|
{
|
||||||
/* ASSERT: information->is_string == false */
|
/* ASSERT: information->is_string == false */
|
||||||
the_object->name.name_u32 = name;
|
the_object->name.name_u32 = name;
|
||||||
|
_ISR_lock_Initialize( &the_object->Lock, "Object" );
|
||||||
|
|
||||||
_Objects_Set_local_object(
|
_Objects_Set_local_object(
|
||||||
information,
|
information,
|
||||||
@@ -953,6 +1032,7 @@ RTEMS_INLINE_ROUTINE void _Objects_Open_string(
|
|||||||
/* ASSERT: information->is_string */
|
/* ASSERT: information->is_string */
|
||||||
the_object->name.name_p = name;
|
the_object->name.name_p = name;
|
||||||
#endif
|
#endif
|
||||||
|
_ISR_lock_Initialize( &the_object->Lock, "Object" );
|
||||||
|
|
||||||
_Objects_Set_local_object(
|
_Objects_Set_local_object(
|
||||||
information,
|
information,
|
||||||
|
|||||||
80
cpukit/score/src/objectacquire.c
Normal file
80
cpukit/score/src/objectacquire.c
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @brief Object Acquire
|
||||||
|
*
|
||||||
|
* @ingroup ScoreObject
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* 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 <rtems/score/objectimpl.h>
|
||||||
|
|
||||||
|
Objects_Control *_Objects_Acquire(
|
||||||
|
const Objects_Information *information,
|
||||||
|
Objects_Id id,
|
||||||
|
Objects_Locations *location,
|
||||||
|
ISR_lock_Context *lock_context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Objects_Control *the_object;
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
index = id - information->minimum_id + 1;
|
||||||
|
|
||||||
|
if ( information->maximum >= index ) {
|
||||||
|
/*
|
||||||
|
* On uni-processor configurations we disable interrupts before we use the
|
||||||
|
* local table. This prevents use of freed memory in case the object
|
||||||
|
* information is extended in between. On SMP configurations bad things
|
||||||
|
* can happen, see https://devel.rtems.org/ticket/2280.
|
||||||
|
*/
|
||||||
|
#if !defined(RTEMS_SMP)
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_Disable( level );
|
||||||
|
#endif
|
||||||
|
if ( ( the_object = information->local_table[ index ] ) != NULL ) {
|
||||||
|
*location = OBJECTS_LOCAL;
|
||||||
|
#if defined(RTEMS_SMP)
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &the_object->Lock, lock_context );
|
||||||
|
#else
|
||||||
|
lock_context->isr_level = level;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return the_object;
|
||||||
|
}
|
||||||
|
#if !defined(RTEMS_SMP)
|
||||||
|
_ISR_Enable( level );
|
||||||
|
#endif
|
||||||
|
*location = OBJECTS_ERROR;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*location = OBJECTS_ERROR;
|
||||||
|
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
_Objects_MP_Is_remote( information, id, location, &the_object );
|
||||||
|
|
||||||
|
return the_object;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -28,4 +28,6 @@ void _Objects_Close(
|
|||||||
_Objects_Invalidate_Id( information, the_object );
|
_Objects_Invalidate_Id( information, the_object );
|
||||||
|
|
||||||
_Objects_Namespace_remove( information, the_object );
|
_Objects_Namespace_remove( information, the_object );
|
||||||
|
|
||||||
|
_ISR_lock_Destroy( &the_object->Lock );
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user