summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/capture/capture.c
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2016-08-30 16:46:25 +1000
committerChris Johns <chrisj@rtems.org>2016-09-01 11:11:22 +1000
commit6da06c559f17f33177f59c0f83164bb2d20c8b9f (patch)
tree9f4b23a8f6e5215489ffbb8219c85fd11aa08e6c /cpukit/libmisc/capture/capture.c
parentarm/xilinx_zynq: Start the second core when an SMP build. (diff)
downloadrtems-6da06c559f17f33177f59c0f83164bb2d20c8b9f.tar.bz2
libmisc/capture: Fix the capture engine on SMP.
This patches some issues with the capture engine: 1. Check is the engine is open in ctrace commands. 2. Check all record open and appends for overflow. 3. Fix the record open to take the size of user data and not the record header. 4. Use packed structs for data being written to the per cpu buffers. 5. Remove direct struct access to the capture buffers to avoid misaligned accesses. 6. Add support to extract records, no struct access to the capture buffers. 7. Update ctrace to extract records from the capture buffers. 8. Add support to ctrace to always print the task name if it has one. 9. Add support to manage names or the lack of a name. 10. Range of minor fixes. 11. Fix a long standing bug in ctset's handling of args. Closes #2780.
Diffstat (limited to 'cpukit/libmisc/capture/capture.c')
-rw-r--r--cpukit/libmisc/capture/capture.c475
1 files changed, 257 insertions, 218 deletions
diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 6879a37a81..6cec8a5cf3 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -1,9 +1,8 @@
/*
------------------------------------------------------------------------
- Copyright Objective Design Systems Pty Ltd, 2002
- All rights reserved Objective Design Systems Pty Ltd, 2002
- Chris Johns (ccj@acm.org)
+ Copyright 2002, 2016 Chris Johns <chrisj@rtems.org>.
+ All rights reserved.
COPYRIGHT (c) 1989-2014.
On-Line Applications Research Corporation (OAR).
@@ -187,17 +186,22 @@ rtems_capture_match_name_id (rtems_name lhs_name,
rtems_name rhs_name,
rtems_id rhs_id)
{
+ bool match_name;
+
+ match_name = ((rtems_capture_task_api(lhs_id) != OBJECTS_POSIX_API) &&
+ (rtems_capture_task_api(rhs_id) != OBJECTS_POSIX_API));
+
/*
* The left hand side name or id could be 0 which means a wildcard.
*/
if ((lhs_name == 0) && (lhs_id == rhs_id))
- return 1;
- else if ((lhs_id == 0) || (lhs_id == rhs_id))
+ return true;
+ else if (match_name && ((lhs_id == 0) || (lhs_id == rhs_id)))
{
if (rtems_capture_match_names (lhs_name, rhs_name))
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/*
@@ -265,7 +269,6 @@ static inline rtems_capture_control_t*
rtems_capture_find_control (rtems_name name, rtems_id id)
{
rtems_capture_control_t* control;
-
for (control = capture_controls; control != NULL; control = control->next)
if (rtems_capture_match_name_id (name, id, control->name, control->id))
break;
@@ -279,24 +282,32 @@ rtems_capture_find_control (rtems_name name, rtems_id id)
static void
rtems_capture_initialize_control (rtems_tcb *tcb)
{
- rtems_name name;
- rtems_capture_control_t* control;
+ if (tcb->Capture.control == NULL)
+ {
+ rtems_name name = rtems_build_name(0, 0, 0, 0);
+ rtems_id id;
+ rtems_capture_control_t* control;
- /*
- * We need to scan the default control list to initialise
- * this control.
- */
- rtems_object_get_classic_name( tcb->Object.id, &name );
- control = capture_controls;
- if (rtems_capture_match_name_id (control->name, control->id,
- name, tcb->Object.id))
- tcb->Capture.control = control;
+ /*
+ * We need to scan the default control list to initialise
+ * this control.
+ */
+ id = tcb->Object.id;
+ if (rtems_capture_task_api (id) != OBJECTS_POSIX_API)
+ rtems_object_get_classic_name (id, &name);
+ for (control = capture_controls; control != NULL; control = control->next)
+ {
+ if (rtems_capture_match_name_id (control->name, control->id,
+ name, id))
+ {
+ tcb->Capture.control = control;
+ break;
+ }
+ }
+ }
}
-/*
- * This function creates a capture control for the capture engine.
- */
-static inline rtems_capture_control_t*
+static rtems_capture_control_t*
rtems_capture_create_control (rtems_name name, rtems_id id)
{
rtems_interrupt_lock_context lock_context;
@@ -309,7 +320,7 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
if (control == NULL)
{
- control = malloc( sizeof (*control));
+ control = malloc (sizeof (*control));
if (!control)
{
@@ -330,6 +341,7 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
control->next = capture_controls;
capture_controls = control;
+
rtems_iterate_over_all_threads (rtems_capture_initialize_control);
rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
@@ -338,39 +350,114 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
return control;
}
-void rtems_capture_initialize_task( rtems_tcb* tcb )
+void
+rtems_capture_record_lock (rtems_capture_record_lock_context* context)
+{
+ rtems_capture_per_cpu_data* cpu;
+ cpu = capture_per_cpu_get (rtems_get_current_processor ());
+ rtems_interrupt_lock_interrupt_disable (&context->lock_context);
+ context->lock = &cpu->lock;
+ rtems_interrupt_lock_acquire_isr (&cpu->lock, &context->lock_context);
+}
+
+void
+rtems_capture_record_unlock (rtems_capture_record_lock_context* context)
+{
+ rtems_interrupt_lock_release (context->lock, &context->lock_context);
+}
+
+void*
+rtems_capture_record_open (rtems_tcb* tcb,
+ uint32_t events,
+ size_t size,
+ rtems_capture_record_lock_context* context)
+{
+ rtems_capture_per_cpu_data* cpu;
+ uint8_t* ptr;
+
+ size += sizeof (rtems_capture_record_t);
+
+ cpu = capture_per_cpu_get (rtems_get_current_processor ());
+
+ rtems_capture_record_lock (context);
+
+ ptr = rtems_capture_buffer_allocate (&cpu->records, size);
+ if (ptr != NULL)
+ {
+ rtems_capture_record_t in;
+
+ ++cpu->count;
+
+ if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)
+ tcb->Capture.flags |= RTEMS_CAPTURE_TRACED;
+
+ /*
+ * Create a local copy then copy. The buffer maybe mis-aligned.
+ */
+ in.size = size;
+ in.task_id = tcb->Object.id;
+ in.events = (events |
+ (tcb->real_priority) |
+ (tcb->current_priority << 8));
+
+ rtems_capture_get_time (&in.time);
+
+ ptr = rtems_capture_record_append(ptr, &in, sizeof(in));
+ }
+ else
+ cpu->flags |= RTEMS_CAPTURE_OVERFLOW;
+
+ return ptr;
+}
+
+void
+rtems_capture_record_close (rtems_capture_record_lock_context* context)
+{
+ rtems_capture_record_unlock (context);
+}
+
+void
+rtems_capture_initialize_task( rtems_tcb* tcb )
{
rtems_capture_control_t* control;
- rtems_name name;
+ rtems_name name = rtems_build_name(0, 0, 0, 0);
+ rtems_id id = rtems_capture_task_id (tcb);
rtems_interrupt_lock_context lock_context;
/*
* We need to scan the default control list to initialize
* this control if it is a new task.
*/
-
- rtems_object_get_classic_name( tcb->Object.id, &name );
+ if (rtems_capture_task_api (id) != OBJECTS_POSIX_API)
+ rtems_object_get_classic_name (id, &name);
rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);
+
if (tcb->Capture.control == NULL) {
for (control = capture_controls; control != NULL; control = control->next)
if (rtems_capture_match_name_id (control->name, control->id,
- name, tcb->Object.id))
+ name, id))
tcb->Capture.control = control;
}
tcb->Capture.flags |= RTEMS_CAPTURE_INIT_TASK;
+
rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
}
-void rtems_capture_record_task( rtems_tcb* tcb )
+void rtems_capture_record_task (rtems_tcb* tcb)
{
- rtems_capture_task_record_t rec;
- void* ptr;
- rtems_interrupt_lock_context lock_context;
+ rtems_name name = rtems_build_name (0, 0, 0, 0);
+ rtems_id id = rtems_capture_task_id (tcb);
+ rtems_capture_task_record_t rec;
+ void* ptr;
+ rtems_interrupt_lock_context lock_context;
+ rtems_capture_record_lock_context rec_context;
- rtems_object_get_classic_name( tcb->Object.id, &rec.name );
+ if (rtems_capture_task_api (id) != OBJECTS_POSIX_API)
+ rtems_object_get_classic_name (id, &name);
+ rec.name = name;
rec.stack_size = tcb->Start.Initial_stack.size;
rec.start_priority = rtems_capture_task_start_priority (tcb);
@@ -379,35 +466,20 @@ void rtems_capture_record_task( rtems_tcb* tcb )
rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
/*
- * Log the task information. The first time a task is
- * seen a record is logged. This record can be identified
- * by a 0 in the event identifier.
+ * Log the task information. The first time a task is seen a record is
+ * logged. This record can be identified by a 0 in the event identifier.
*/
- rtems_capture_begin_add_record (tcb, 0, sizeof(rec), &ptr);
- ptr = rtems_capture_append_to_record(
- ptr,
- &rec.name,
- sizeof( rec.name )
- );
- ptr = rtems_capture_append_to_record(
- ptr,
- &rec.start_priority,
- sizeof( rec.start_priority)
- );
- ptr = rtems_capture_append_to_record(
- ptr,
- &rec.stack_size,
- sizeof( rec.stack_size)
- );
- rtems_capture_end_add_record ( ptr );
+ ptr = rtems_capture_record_open (tcb, 0, sizeof(rec), &rec_context);
+ if (ptr != NULL)
+ rtems_capture_record_append(ptr, &rec, sizeof (rec));
+ rtems_capture_record_close (&rec_context);
}
/*
* This function indicates if data should be filtered from the
* log.
*/
-bool rtems_capture_filter( rtems_tcb* tcb,
- uint32_t events)
+bool rtems_capture_filter (rtems_tcb* tcb, uint32_t events)
{
if (tcb &&
((capture_flags_global &
@@ -437,60 +509,11 @@ bool rtems_capture_filter( rtems_tcb* tcb,
}
/*
- * This function records a capture record into the capture buffer.
- */
-void *
-rtems_capture_record_open (rtems_tcb* tcb,
- uint32_t events,
- size_t size,
- rtems_capture_record_context_t* context)
-{
- rtems_capture_per_cpu_data* per_cpu;
- uint8_t* ptr;
- rtems_capture_record_t* capture_in;
-
- rtems_interrupt_lock_interrupt_disable (&context->lock_context);
- per_cpu = capture_per_cpu_get (rtems_get_current_processor ());
- context->lock = &per_cpu->lock;
- rtems_interrupt_lock_acquire_isr (&per_cpu->lock, &context->lock_context);
-
- ptr = rtems_capture_buffer_allocate (&per_cpu->records, size);
- capture_in = (rtems_capture_record_t *) ptr;
- if ( capture_in )
- {
- ++per_cpu->count;
- capture_in->size = size;
- capture_in->task_id = tcb->Object.id;
- capture_in->events = (events |
- (tcb->real_priority) |
- (tcb->current_priority << 8));
-
- if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)
- tcb->Capture.flags |= RTEMS_CAPTURE_TRACED;
-
- rtems_capture_get_time (&capture_in->time);
-
- ptr = ptr + sizeof(*capture_in);
- }
- else
- per_cpu->flags |= RTEMS_CAPTURE_OVERFLOW;
-
- return ptr;
-}
-
-void rtems_capture_record_close( void *rec, rtems_capture_record_context_t* context)
-{
- rtems_interrupt_lock_release (context->lock, &context->lock_context);
-}
-
-/*
* See if we have triggered and if not see if this event is a
* cause of a trigger.
*/
bool
-rtems_capture_trigger (rtems_tcb* ft,
- rtems_tcb* tt,
- uint32_t events)
+rtems_capture_trigger (rtems_tcb* ft, rtems_tcb* tt, uint32_t events)
{
/*
* If we have not triggered then see if this is a trigger condition.
@@ -531,7 +554,7 @@ rtems_capture_trigger (rtems_tcb* ft,
if (from_events || to_events)
{
capture_flags_global |= RTEMS_CAPTURE_TRIGGERED;
- return 1;
+ return true;
}
/*
@@ -542,14 +565,14 @@ rtems_capture_trigger (rtems_tcb* ft,
if (rtems_capture_by_in_to (events, ft, tc))
{
capture_flags_global |= RTEMS_CAPTURE_TRIGGERED;
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/*
@@ -739,38 +762,44 @@ rtems_capture_flush_tcb (rtems_tcb *tcb)
rtems_status_code
rtems_capture_flush (bool prime)
{
- rtems_interrupt_lock_context lock_context_global;
- uint32_t cpu;
+ rtems_status_code sc = RTEMS_NOT_CONFIGURED;
+ if (capture_per_cpu != NULL)
+ {
+ rtems_interrupt_lock_context lock_context_global;
+ uint32_t cpu;
- rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context_global);
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context_global);
- if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
- {
- rtems_interrupt_lock_release (&capture_lock_global, &lock_context_global);
- return RTEMS_UNSATISFIED;
- }
+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+ {
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context_global);
+ return RTEMS_UNSATISFIED;
+ }
- rtems_iterate_over_all_threads (rtems_capture_flush_tcb);
+ rtems_iterate_over_all_threads (rtems_capture_flush_tcb);
- if (prime)
- capture_flags_global &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
- else
- capture_flags_global &= ~RTEMS_CAPTURE_OVERFLOW;
+ if (prime)
+ capture_flags_global &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
+ else
+ capture_flags_global &= ~RTEMS_CAPTURE_OVERFLOW;
- for (cpu=0; cpu < rtems_get_processor_count(); cpu++) {
- RTEMS_INTERRUPT_LOCK_REFERENCE( lock, &(capture_lock_on_cpu( cpu )) )
- rtems_interrupt_lock_context lock_context_per_cpu;
+ for (cpu=0; cpu < rtems_get_processor_count(); cpu++) {
+ RTEMS_INTERRUPT_LOCK_REFERENCE( lock, &(capture_lock_on_cpu( cpu )) )
+ rtems_interrupt_lock_context lock_context_per_cpu;
- rtems_interrupt_lock_acquire (lock, &lock_context_per_cpu);
- capture_count_on_cpu(cpu) = 0;
- if (capture_records_on_cpu(cpu).buffer)
- rtems_capture_buffer_flush( &capture_records_on_cpu(cpu) );
- rtems_interrupt_lock_release (lock, &lock_context_per_cpu);
- }
+ rtems_interrupt_lock_acquire (lock, &lock_context_per_cpu);
+ capture_count_on_cpu(cpu) = 0;
+ if (capture_records_on_cpu(cpu).buffer)
+ rtems_capture_buffer_flush( &capture_records_on_cpu(cpu) );
+ rtems_interrupt_lock_release (lock, &lock_context_per_cpu);
+ }
- rtems_interrupt_lock_release (&capture_lock_global, &lock_context_global);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context_global);
- return RTEMS_SUCCESSFUL;
+ sc = RTEMS_SUCCESSFUL;
+ }
+
+ return sc;
}
/*
@@ -1164,23 +1193,22 @@ rtems_capture_clear_trigger (rtems_name from_name,
return RTEMS_SUCCESSFUL;
}
-static inline uint32_t rtems_capture_count_records( void* recs, size_t size )
+static inline uint32_t
+rtems_capture_count_records (const void* records, size_t size)
{
- rtems_capture_record_t* rec;
- uint8_t* ptr = recs;
- uint32_t rec_count = 0;
- size_t byte_count = 0;
-
+ const uint8_t* ptr = records;
+ uint32_t recs = 0;
+ size_t bytes = 0;
- while (byte_count < size) {
- rec = (rtems_capture_record_t*) ptr;
- rec_count++;
- _Assert( rec->size >= sizeof(*rec) );
+ while (bytes < size)
+ {
+ const rtems_capture_record_t* rec = (const rtems_capture_record_t*) ptr;
+ recs++;
ptr += rec->size;
- byte_count += rec->size;
- };
+ bytes += rec->size;
+ }
- return rec_count;
+ return recs;
}
/*
@@ -1198,45 +1226,51 @@ static inline uint32_t rtems_capture_count_records( void* recs, size_t size )
* result in at least the same number of records being released.
*/
rtems_status_code
-rtems_capture_read (uint32_t cpu,
- uint32_t* read,
- rtems_capture_record_t** recs)
+rtems_capture_read (uint32_t cpu, size_t* read, const void** recs)
{
- rtems_interrupt_lock_context lock_context;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- size_t recs_size = 0;
- RTEMS_INTERRUPT_LOCK_REFERENCE( lock, &(capture_lock_on_cpu( cpu )) )
- rtems_capture_buffer_t* records = &(capture_records_on_cpu( cpu ));
- uint32_t* flags = &(capture_flags_on_cpu( cpu ));
+ rtems_status_code sc = RTEMS_NOT_CONFIGURED;
+ if (capture_per_cpu != NULL)
+ {
+ RTEMS_INTERRUPT_LOCK_REFERENCE (lock, &(capture_lock_on_cpu (cpu)))
+ rtems_interrupt_lock_context lock_context;
+ size_t recs_size = 0;
+ rtems_capture_buffer_t* records;
+ uint32_t* flags;
- *read = 0;
- *recs = NULL;
+ *read = 0;
+ *recs = NULL;
- rtems_interrupt_lock_acquire (lock, &lock_context);
+ records = &(capture_records_on_cpu (cpu));
+ flags = &(capture_flags_on_cpu (cpu));
- /*
- * Only one reader is allowed.
- */
+ rtems_interrupt_lock_acquire (lock, &lock_context);
- if (*flags & RTEMS_CAPTURE_READER_ACTIVE)
- {
- rtems_interrupt_lock_release (lock, &lock_context);
- return RTEMS_RESOURCE_IN_USE;
- }
+ /*
+ * Only one reader is allowed.
+ */
- if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
- {
- rtems_interrupt_lock_release (lock, &lock_context);
- return RTEMS_UNSATISFIED;
- }
+ if (*flags & RTEMS_CAPTURE_READER_ACTIVE)
+ {
+ rtems_interrupt_lock_release (lock, &lock_context);
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+ {
+ rtems_interrupt_lock_release (lock, &lock_context);
+ return RTEMS_UNSATISFIED;
+ }
+
+ *flags |= RTEMS_CAPTURE_READER_ACTIVE;
- *flags |= RTEMS_CAPTURE_READER_ACTIVE;
+ *recs = rtems_capture_buffer_peek( records, &recs_size );
- *recs = rtems_capture_buffer_peek( records, &recs_size );
+ *read = rtems_capture_count_records( *recs, recs_size );
- *read = rtems_capture_count_records( *recs, recs_size );
+ rtems_interrupt_lock_release (lock, &lock_context);
- rtems_interrupt_lock_release (lock, &lock_context);
+ sc = RTEMS_SUCCESSFUL;
+ }
return sc;
}
@@ -1248,58 +1282,63 @@ rtems_capture_read (uint32_t cpu,
rtems_status_code
rtems_capture_release (uint32_t cpu, uint32_t count)
{
- rtems_interrupt_lock_context lock_context;
- uint8_t* ptr;
- rtems_capture_record_t* rec;
- uint32_t counted;
- size_t ptr_size = 0;
- size_t rel_size = 0;
- rtems_status_code ret_val = RTEMS_SUCCESSFUL;
- RTEMS_INTERRUPT_LOCK_REFERENCE( lock, &(capture_lock_on_cpu( cpu )) )
- rtems_capture_buffer_t* records = &(capture_records_on_cpu( cpu ));
- uint32_t* flags = &(capture_flags_on_cpu( cpu ));
- uint32_t* total = &(capture_count_on_cpu( cpu ));
-
- rtems_interrupt_lock_acquire (lock, &lock_context);
-
- if (count > *total) {
- count = *total;
- }
+ rtems_status_code sc = RTEMS_NOT_CONFIGURED;
+ if (capture_per_cpu != NULL)
+ {
+ rtems_interrupt_lock_context lock_context;
+ uint8_t* ptr;
+ rtems_capture_record_t* rec;
+ uint32_t counted;
+ size_t ptr_size = 0;
+ size_t rel_size = 0;
+ RTEMS_INTERRUPT_LOCK_REFERENCE( lock, &(capture_lock_on_cpu( cpu )) )
+ rtems_capture_buffer_t* records = &(capture_records_on_cpu( cpu ));
+ uint32_t* flags = &(capture_flags_on_cpu( cpu ));
+ uint32_t* total = &(capture_count_on_cpu( cpu ));
- if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 ) {
- rtems_interrupt_lock_release (lock, &lock_context);
- return RTEMS_UNSATISFIED;
- }
+ sc = RTEMS_SUCCESSFUL;
- counted = count;
+ rtems_interrupt_lock_acquire (lock, &lock_context);
- ptr = rtems_capture_buffer_peek( records, &ptr_size );
- _Assert(ptr_size >= (count * sizeof(*rec) ));
+ if (count > *total) {
+ count = *total;
+ }
- rel_size = 0;
- while (counted--) {
- rec = (rtems_capture_record_t*) ptr;
- rel_size += rec->size;
- _Assert( rel_size <= ptr_size );
- ptr += rec->size;
- }
+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 ) {
+ rtems_interrupt_lock_release (lock, &lock_context);
+ return RTEMS_UNSATISFIED;
+ }
- if (rel_size > ptr_size ) {
- ret_val = RTEMS_INVALID_NUMBER;
- rel_size = ptr_size;
- }
+ counted = count;
- *total -= count;
+ ptr = rtems_capture_buffer_peek( records, &ptr_size );
+ _Assert(ptr_size >= (count * sizeof(*rec) ));
- if (count) {
- rtems_capture_buffer_free( records, rel_size );
- }
+ rel_size = 0;
+ while (counted--) {
+ rec = (rtems_capture_record_t*) ptr;
+ rel_size += rec->size;
+ _Assert( rel_size <= ptr_size );
+ ptr += rec->size;
+ }
+
+ if (rel_size > ptr_size ) {
+ sc = RTEMS_INVALID_NUMBER;
+ rel_size = ptr_size;
+ }
- *flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
+ *total -= count;
+
+ if (count) {
+ rtems_capture_buffer_free( records, rel_size );
+ }
- rtems_interrupt_lock_release (lock, &lock_context);
+ *flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
- return ret_val;
+ rtems_interrupt_lock_release (lock, &lock_context);
+ }
+
+ return sc;
}
/*