Discussion:
[PATCH 1/2] capture: Move logging of task record to occur after filter check.
Jennifer Averett
2014-10-07 18:43:22 UTC
Permalink
---
cpukit/libmisc/capture/capture.c | 39 +++++++++++++------
cpukit/libmisc/capture/capture.h | 24 +++++++++++-
cpukit/libmisc/capture/capture_user_extension.c | 51 +++++++++++++------------
3 files changed, 78 insertions(+), 36 deletions(-)

diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 8bece88..74b563d 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -313,26 +313,35 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
return control;
}

-void rtems_capture_record_task( rtems_tcb* tcb )
+void rtems_capture_initialize_task( rtems_tcb* tcb )
{
rtems_capture_control_t* control;
- rtems_capture_task_record_t rec;
- void* ptr;
+ rtems_name name;

- rtems_object_get_classic_name( tcb->Object.id, &rec.name );
-
/*
* We need to scan the default control list to initialise
* this control if it is a new task.
*/

+ rtems_object_get_classic_name( tcb->Object.id, &name );
+
if (tcb->Capture.control == NULL) {
for (control = capture_controls; control != NULL; control = control->next)
if (rtems_capture_match_name_id (control->name, control->id,
- rec.name, tcb->Object.id))
+ name, tcb->Object.id))
tcb->Capture.control = control;
}

+ tcb->Capture.flags |= RTEMS_CAPTURE_INIT_TASK;
+}
+
+void rtems_capture_record_task( rtems_tcb* tcb )
+{
+ rtems_capture_task_record_t rec;
+ void* ptr;
+
+ rtems_object_get_classic_name( tcb->Object.id, &rec.name );
+
rec.stack_size = tcb->Start.Initial_stack.size;
rec.start_priority = _RTEMS_tasks_Priority_from_Core(
tcb->Start.initial_priority
@@ -1224,6 +1233,8 @@ rtems_capture_release (uint32_t count)
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_acquire (&capture_lock, &lock_context);

@@ -1237,26 +1248,32 @@ rtems_capture_release (uint32_t count)
ptr = rtems_capture_buffer_peek( &capture_records, &ptr_size );
_Assert(ptr_size >= (count * sizeof(*rec) ));

- ptr_size = 0;
+ rel_size = 0;
while (counted--)
- {
+ {
rec = (rtems_capture_record_t*) ptr;
- ptr_size += rec->size;
+ rel_size += rec->size;
+ _Assert( rel_size <= ptr_size );
ptr += rec->size;
}

rtems_interrupt_lock_acquire (&capture_lock, &lock_context);

+ if (rel_size > ptr_size ) {
+ ret_val = RTEMS_INVALID_NUMBER;
+ rel_size = ptr_size;
+ }
+
capture_count -= count;

if (count)
- rtems_capture_buffer_free( &capture_records, ptr_size );
+ rtems_capture_buffer_free( &capture_records, rel_size );

capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;

rtems_interrupt_lock_release (&capture_lock, &lock_context);

- return RTEMS_SUCCESSFUL;
+ return ret_val;
}

/*
diff --git a/cpukit/libmisc/capture/capture.h b/cpukit/libmisc/capture/capture.h
index c4edc16..8e0bd1a 100644
--- a/cpukit/libmisc/capture/capture.h
+++ b/cpukit/libmisc/capture/capture.h
@@ -141,7 +141,8 @@ typedef struct rtems_capture_control_s
* Task flags.
*/
#define RTEMS_CAPTURE_TRACED (1U << 0)
-#define RTEMS_CAPTURE_RECORD_TASK (1U << 1)
+#define RTEMS_CAPTURE_INIT_TASK (1U << 1)
+#define RTEMS_CAPTURE_RECORD_TASK (1U << 2)

/*
* @brief Capture record.
@@ -598,6 +599,15 @@ const char*
rtems_capture_event_text (int event);

/**
+ * @brief Capture initialize task
+ *
+ * This function initializes capture control in the tcb.
+ *
+ * @param[in] tcb is the task control block for the task
+ */
+void rtems_capture_initialize_task( rtems_tcb* tcb );
+
+/**
* @brief Capture record task.
*
* This function records a new capture task record.
@@ -619,6 +629,18 @@ static inline bool rtems_capture_task_recorded( rtems_tcb* tcb ) {
}

/**
+ * @brief Capture task initialized
+ *
+ * This function returns true if this task information has been
+ * initialized.
+ *
+ * @param[in] tcb is the task control block for the task
+ */
+static inline bool rtems_capture_task_initialized( rtems_tcb* tcb ) {
+ return ( (tcb->Capture.flags & RTEMS_CAPTURE_INIT_TASK) != 0 );
+}
+
+/**
* @brief Capture get task id.
*
* This function returns the task id.
diff --git a/cpukit/libmisc/capture/capture_user_extension.c b/cpukit/libmisc/capture/capture_user_extension.c
index 4c7bc1d..69b8d48 100644
--- a/cpukit/libmisc/capture/capture_user_extension.c
+++ b/cpukit/libmisc/capture/capture_user_extension.c
@@ -95,6 +95,9 @@ static inline void rtems_capture_record (

if (rtems_capture_filter( tcb, events) )
return;
+
+ if (!rtems_capture_task_recorded (tcb))
+ rtems_capture_record_task (tcb);

rtems_capture_begin_add_record (tcb, events, size, &ptr);
rtems_capture_end_add_record ( ptr );
@@ -141,13 +144,13 @@ rtems_capture_create_task (rtems_tcb* ct,
* been created before the capture engine was open. Add them.
*/

- if (!rtems_capture_task_recorded (ct))
- rtems_capture_record_task (ct);
+ if (!rtems_capture_task_initialized (ct))
+ rtems_capture_initialize_task (ct);

/*
* Create the new task's capture control block.
*/
- rtems_capture_record_task (nt);
+ rtems_capture_initialize_task (nt);

if (rtems_capture_trigger (ct, nt, RTEMS_CAPTURE_CREATE))
{
@@ -170,11 +173,11 @@ rtems_capture_start_task (rtems_tcb* ct,
* been created before the capture engine was open. Add them.
*/

- if (!rtems_capture_task_recorded (ct))
- rtems_capture_record_task (ct);
+ if (!rtems_capture_task_initialized (ct))
+ rtems_capture_initialize_task (ct);

if (st == NULL)
- rtems_capture_record_task (st);
+ rtems_capture_initialize_task (st);

if (rtems_capture_trigger (ct, st, RTEMS_CAPTURE_START))
{
@@ -195,11 +198,11 @@ rtems_capture_restart_task (rtems_tcb* ct,
* been created before the capture engine was open. Add them.
*/

- if (!rtems_capture_task_recorded (ct))
- rtems_capture_record_task (ct);
+ if (!rtems_capture_task_initialized (ct))
+ rtems_capture_initialize_task (ct);

- if (!rtems_capture_task_recorded (rt))
- rtems_capture_record_task (rt);
+ if (!rtems_capture_task_initialized (rt))
+ rtems_capture_initialize_task (rt);

if (rtems_capture_trigger (ct, rt, RTEMS_CAPTURE_RESTART))
{
@@ -215,11 +218,11 @@ static void
rtems_capture_delete_task (rtems_tcb* ct,
rtems_tcb* dt)
{
- if (!rtems_capture_task_recorded (ct))
- rtems_capture_record_task (ct);
+ if (!rtems_capture_task_initialized (ct))
+ rtems_capture_initialize_task (ct);

- if (!rtems_capture_task_recorded (dt))
- rtems_capture_record_task (dt);
+ if (!rtems_capture_task_initialized (dt))
+ rtems_capture_initialize_task (dt);

if (rtems_capture_trigger (ct, dt, RTEMS_CAPTURE_DELETE))
{
@@ -239,8 +242,8 @@ rtems_capture_begin_task (rtems_tcb* bt)
* been created before the capture engine was open. Add them.
*/

- if (!rtems_capture_task_recorded (bt))
- rtems_capture_record_task (bt);
+ if (!rtems_capture_task_initialized (bt))
+ rtems_capture_initialize_task (bt);

if (rtems_capture_trigger (NULL, bt, RTEMS_CAPTURE_BEGIN))
rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT);
@@ -258,8 +261,8 @@ rtems_capture_exitted_task (rtems_tcb* et)
* been created before the capture engine was open. Add them.
*/

- if (!rtems_capture_task_recorded (et))
- rtems_capture_record_task (et);
+ if (!rtems_capture_task_initialized (et))
+ rtems_capture_initialize_task (et);

if (rtems_capture_trigger (NULL, et, RTEMS_CAPTURE_EXITTED))
rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT);
@@ -276,8 +279,8 @@ rtems_capture_terminated_task (rtems_tcb* tt)
* been created before the capture engine was open. Add them.
*/

- if (!rtems_capture_task_recorded (tt))
- rtems_capture_record_task (tt);
+ if (!rtems_capture_task_initialized (tt))
+ rtems_capture_initialize_task (tt);

if (rtems_capture_trigger (NULL, tt, RTEMS_CAPTURE_TERMINATED))
rtems_capture_record (tt, RTEMS_CAPTURE_TERMINATED_EVENT);
@@ -300,11 +303,11 @@ rtems_capture_switch_task (rtems_tcb* ct,
{
rtems_capture_time_t time;

- if (!rtems_capture_task_recorded (ct))
- rtems_capture_record_task (ct);
+ if (!rtems_capture_task_initialized (ct))
+ rtems_capture_initialize_task (ct);

- if (!rtems_capture_task_recorded (ht))
- rtems_capture_record_task (ht);
+ if (!rtems_capture_task_initialized (ht))
+ rtems_capture_initialize_task (ht);

/*
* Update the execution time. Assume the time will not overflow
--
1.8.1.4
Jennifer Averett
2014-10-07 18:43:23 UTC
Permalink
This patch is not to be committed but is for discussion purposes.
Adding percpu instances will be implemented prior to committing.
---
cpukit/libmisc/capture/capture.c | 243 +++++++++++++++++++++++------------
cpukit/libmisc/capture/captureimpl.h | 19 ++-
2 files changed, 171 insertions(+), 91 deletions(-)

diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 74b563d..153b340 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -5,7 +5,7 @@
All rights reserved Objective Design Systems Pty Ltd, 2002
Chris Johns (ccj-***@public.gmane.org)

- COPYRIGHT (c) 1989-2009.
+ COPYRIGHT (c) 1989-2014.
On-Line Applications Research Corporation (OAR).

The license and distribution terms for this file may be
@@ -59,21 +59,49 @@
#define RTEMS_CAPTURE_RECORD_EVENTS (0)
#endif

+typedef struct {
+ rtems_capture_buffer_t records;
+ uint32_t count;
+ rtems_id reader;
+ rtems_interrupt_lock lock;
+ uint32_t flags;
+} rtems_capture_per_cpu_data_t;
+
+typedef struct {
+ uint32_t flags;
+ rtems_capture_control_t* controls;
+ int extension_index;
+ rtems_capture_timestamp timestamp;
+ rtems_task_priority ceiling;
+ rtems_task_priority floor;
+ rtems_interrupt_lock lock;
+} rtems_capture_global_data_t;
+
+static rtems_capture_per_cpu_data_t capture_per_cpu = {
+ {NULL, 0, 0, 0, 0, 0},
+ 0,
+ 0,
+ RTEMS_INTERRUPT_LOCK_INITIALIZER("capture")
+};

+static rtems_capture_global_data_t capture_global;
+
/*
* RTEMS Capture Data.
*/
-static rtems_capture_buffer_t capture_records = {NULL, 0, 0, 0, 0, 0};
-static uint32_t capture_count;
-static uint32_t capture_flags;
-static rtems_capture_control_t* capture_controls;
-static int capture_extension_index;
-static rtems_capture_timestamp capture_timestamp;
-static rtems_task_priority capture_ceiling;
-static rtems_task_priority capture_floor;
-static rtems_id capture_reader;
-static rtems_interrupt_lock capture_lock =
- RTEMS_INTERRUPT_LOCK_INITIALIZER("capture");
+
+#define capture_records capture_per_cpu.records
+#define capture_count capture_per_cpu.count
+#define capture_flags_per_cpu capture_per_cpu.flags
+#define capture_flags_global capture_global.flags
+#define capture_controls capture_global.controls
+#define capture_extension_index capture_global.extension_index
+#define capture_timestamp capture_global.timestamp
+#define capture_ceiling capture_global.ceiling
+#define capture_floor capture_global.floor
+#define capture_reader capture_per_cpu.reader
+#define capture_lock_per_cpu capture_per_cpu.lock
+#define capture_lock_global capture_global.lock

/*
* RTEMS Event text.
@@ -106,14 +134,18 @@ int rtems_capture_get_extension_index(void)
return capture_extension_index;
}

+/*
+ * XXX - Do both global and per_cpu flags
+ * need outside access?
+ */
uint32_t rtems_capture_get_flags(void)
{
- return capture_flags;
+ return capture_flags_global;
}

void rtems_capture_set_flags(uint32_t mask)
{
- capture_flags |= mask;
+ capture_flags_global |= mask;
}

/*
@@ -288,7 +320,7 @@ rtems_capture_create_control (rtems_name name, rtems_id id)

if (!ok)
{
- capture_flags |= RTEMS_CAPTURE_NO_MEMORY;
+ capture_flags_global |= RTEMS_CAPTURE_NO_MEMORY;
return NULL;
}

@@ -301,13 +333,13 @@ rtems_capture_create_control (rtems_name name, rtems_id id)

memset (control->by, 0, sizeof (control->by));

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);

control->next = capture_controls;
capture_controls = control;
rtems_iterate_over_all_threads (rtems_capture_initialize_control);

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
}

return control;
@@ -319,7 +351,7 @@ void rtems_capture_initialize_task( rtems_tcb* tcb )
rtems_name name;

/*
- * We need to scan the default control list to initialise
+ * We need to scan the default control list to initialize
* this control if it is a new task.
*/

@@ -382,7 +414,7 @@ bool rtems_capture_filter( rtems_tcb* tcb,
uint32_t events)
{
if (tcb &&
- ((capture_flags &
+ ((capture_flags_global &
(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_ONLY_MONITOR)) ==
RTEMS_CAPTURE_TRIGGERED))
{
@@ -398,7 +430,7 @@ bool rtems_capture_filter( rtems_tcb* tcb,
if ((events & RTEMS_CAPTURE_RECORD_EVENTS) ||
((tcb->real_priority >= capture_ceiling) &&
(tcb->real_priority <= capture_floor) &&
- ((capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH) ||
+ ((capture_flags_global & RTEMS_CAPTURE_GLOBAL_WATCH) ||
(control && (control->flags & RTEMS_CAPTURE_WATCH)))))
{
return false;
@@ -420,7 +452,7 @@ rtems_capture_record_open (rtems_tcb* tcb,
uint8_t* ptr;
rtems_capture_record_t* capture_in;

- rtems_interrupt_lock_acquire (&capture_lock, lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_per_cpu, lock_context);

ptr = rtems_capture_buffer_allocate(&capture_records, size);
capture_in = (rtems_capture_record_t *) ptr;
@@ -441,14 +473,14 @@ rtems_capture_record_open (rtems_tcb* tcb,
ptr = ptr + sizeof(*capture_in);
}
else
- capture_flags |= RTEMS_CAPTURE_OVERFLOW;
+ capture_flags_per_cpu |= RTEMS_CAPTURE_OVERFLOW;

return ptr;
}

void rtems_capture_record_close( void *rec, rtems_interrupt_lock_context* lock_context)
{
- rtems_interrupt_lock_release (&capture_lock, lock_context);
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, lock_context);
}

/*
@@ -464,7 +496,7 @@ rtems_capture_trigger (rtems_tcb* ft,
/*
* If we have not triggered then see if this is a trigger condition.
*/
- if (!(capture_flags & RTEMS_CAPTURE_TRIGGERED))
+ if (!(capture_flags_global & RTEMS_CAPTURE_TRIGGERED))
{
rtems_capture_control_t* fc = NULL;
rtems_capture_control_t* tc = NULL;
@@ -499,7 +531,7 @@ rtems_capture_trigger (rtems_tcb* ft,
*/
if (from_events || to_events)
{
- capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+ capture_flags_global |= RTEMS_CAPTURE_TRIGGERED;
return 1;
}

@@ -510,7 +542,7 @@ rtems_capture_trigger (rtems_tcb* ft,
{
if (rtems_capture_by_in_to (events, ft, tc))
{
- capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+ capture_flags_global |= RTEMS_CAPTURE_TRIGGERED;
return 1;
}
}
@@ -523,7 +555,7 @@ rtems_capture_trigger (rtems_tcb* ft,

/*
* This function initialises the realtime capture engine allocating the trace
- * buffer. It is assumed we have a working heap at stage of initialisation.
+ * buffer. It is assumed we have a working heap at stage of initialization.
*/
rtems_status_code
rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribute__((unused)))
@@ -534,7 +566,7 @@ rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribu
* See if the capture engine is already open.
*/

- if (capture_records.buffer)
+ if ((capture_flags_global & RTEMS_CAPTURE_INIT) == RTEMS_CAPTURE_INIT)
return RTEMS_RESOURCE_IN_USE;

rtems_capture_buffer_create( &capture_records, size );
@@ -543,7 +575,8 @@ rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribu
return RTEMS_NO_MEMORY;

capture_count = 0;
- capture_flags = 0;
+ capture_flags_global = 0;
+ capture_flags_per_cpu = 0;
capture_ceiling = 0;
capture_floor = 255;

@@ -554,16 +587,14 @@ rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribu
rtems_capture_buffer_destroy( &capture_records);
}

- /*
- * Iterate over the list of existing tasks.
- */
+ capture_flags_global |= RTEMS_CAPTURE_INIT;

return sc;
}

/*
* This function shutdowns the capture engine and release any claimed
- * resources.
+ * resources. Capture control must be disabled prior to calling a close.
*/
rtems_status_code
rtems_capture_close (void)
@@ -572,17 +603,24 @@ rtems_capture_close (void)
rtems_capture_control_t* control;
rtems_status_code sc;

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);

- if (!capture_records.buffer)
+ if ((capture_flags_global & RTEMS_CAPTURE_INIT) != RTEMS_CAPTURE_INIT)
{
- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
return RTEMS_SUCCESSFUL;
}
+
+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+ {
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
+ return RTEMS_UNSATISFIED;
+ }

- capture_flags &= ~(RTEMS_CAPTURE_ON | RTEMS_CAPTURE_ONLY_MONITOR);
+ capture_flags_global &=
+ ~(RTEMS_CAPTURE_ON | RTEMS_CAPTURE_ONLY_MONITOR | RTEMS_CAPTURE_INIT);

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);

/*
* Delete the extension first. This means we are now able to
@@ -604,7 +642,6 @@ rtems_capture_close (void)
}

capture_controls = NULL;
-
if (capture_records.buffer)
{
rtems_capture_buffer_destroy( &capture_records);
@@ -618,20 +655,20 @@ rtems_capture_control (bool enable)
{
rtems_interrupt_lock_context lock_context;

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);

- if (!capture_records.buffer)
+ if ((capture_flags_global & RTEMS_CAPTURE_INIT) != RTEMS_CAPTURE_INIT)
{
- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
return RTEMS_UNSATISFIED;
}

if (enable)
- capture_flags |= RTEMS_CAPTURE_ON;
+ capture_flags_global |= RTEMS_CAPTURE_ON;
else
- capture_flags &= ~RTEMS_CAPTURE_ON;
+ capture_flags_global &= ~RTEMS_CAPTURE_ON;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);

return RTEMS_SUCCESSFUL;
}
@@ -646,20 +683,20 @@ rtems_capture_monitor (bool enable)
{
rtems_interrupt_lock_context lock_context;

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);

- if (!capture_records.buffer)
+ if ((capture_flags_global & RTEMS_CAPTURE_INIT) != RTEMS_CAPTURE_INIT)
{
- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);
return RTEMS_UNSATISFIED;
}

if (enable)
- capture_flags |= RTEMS_CAPTURE_ONLY_MONITOR;
+ capture_flags_global |= RTEMS_CAPTURE_ONLY_MONITOR;
else
- capture_flags &= ~RTEMS_CAPTURE_ONLY_MONITOR;
+ capture_flags_global &= ~RTEMS_CAPTURE_ONLY_MONITOR;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);

return RTEMS_SUCCESSFUL;
}
@@ -681,21 +718,31 @@ rtems_capture_flush_tcb (rtems_tcb *tcb)
rtems_status_code
rtems_capture_flush (bool prime)
{
- rtems_interrupt_lock_context lock_context;
+ rtems_interrupt_lock_context lock_context_global;
+ rtems_interrupt_lock_context lock_context_per_cpu;
+
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context_global);

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ 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);

if (prime)
- capture_flags &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
+ capture_flags_global &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
else
- capture_flags &= ~RTEMS_CAPTURE_OVERFLOW;
+ capture_flags_global &= ~RTEMS_CAPTURE_OVERFLOW;
+
+ rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context_per_cpu);

rtems_capture_buffer_flush( &capture_records );
capture_count = 0;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context_per_cpu);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context_global);

return RTEMS_SUCCESSFUL;
}
@@ -704,13 +751,16 @@ rtems_capture_flush (bool prime)
* This function defines a watch for a specific task given a name. A watch
* causes it to be traced either in or out of context. The watch can be
* optionally enabled or disabled with the set routine. It is disabled by
- * default.
+ * default. A watch can only be defined when capture control is disabled
*/
rtems_status_code
rtems_capture_watch_add (rtems_name name, rtems_id id)
{
rtems_capture_control_t* control;

+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+ return RTEMS_UNSATISFIED;
+
if ((name == 0) && (id == 0))
return RTEMS_UNSATISFIED;

@@ -731,7 +781,8 @@ rtems_capture_watch_add (rtems_name name, rtems_id id)
/*
* This function removes a watch for a specific task given a name. The task
* description will still exist if referenced by a trace record in the trace
- * buffer or a global watch is defined.
+ * buffer or a global watch is defined. A watch can only be deleted when
+ * capture control is disabled.
*/
rtems_status_code
rtems_capture_watch_del (rtems_name name, rtems_id id)
@@ -741,6 +792,9 @@ rtems_capture_watch_del (rtems_name name, rtems_id id)
rtems_capture_control_t** prev_control;
bool found = false;

+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+ return RTEMS_UNSATISFIED;
+
/*
* Should this test be for wildcards ?
*/
@@ -750,11 +804,11 @@ rtems_capture_watch_del (rtems_name name, rtems_id id)
{
if (rtems_capture_match_name_id (control->name, control->id, name, id))
{
- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);

*prev_control = control->next;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);

rtems_workspace_free (control);

@@ -786,6 +840,9 @@ rtems_capture_watch_ctrl (rtems_name name, rtems_id id, bool enable)
rtems_capture_control_t* control;
bool found = false;

+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+ return RTEMS_UNSATISFIED;
+
/*
* Find the control and then set the watch. It must exist before it can
* be controlled.
@@ -794,14 +851,14 @@ rtems_capture_watch_ctrl (rtems_name name, rtems_id id, bool enable)
{
if (rtems_capture_match_name_id (control->name, control->id, name, id))
{
- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);

if (enable)
control->flags |= RTEMS_CAPTURE_WATCH;
else
control->flags &= ~RTEMS_CAPTURE_WATCH;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);

found = true;
}
@@ -823,18 +880,18 @@ rtems_capture_watch_global (bool enable)
{
rtems_interrupt_lock_context lock_context;

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_global, &lock_context);

/*
* We need to keep specific and global watches separate so
* a global enable/disable does not lose a specific watch.
*/
if (enable)
- capture_flags |= RTEMS_CAPTURE_GLOBAL_WATCH;
+ capture_flags_global |= RTEMS_CAPTURE_GLOBAL_WATCH;
else
- capture_flags &= ~RTEMS_CAPTURE_GLOBAL_WATCH;
+ capture_flags_global &= ~RTEMS_CAPTURE_GLOBAL_WATCH;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_global, &lock_context);

return RTEMS_SUCCESSFUL;
}
@@ -845,7 +902,7 @@ rtems_capture_watch_global (bool enable)
bool
rtems_capture_watch_global_on (void)
{
- return capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH ? 1 : 0;
+ return capture_flags_global & RTEMS_CAPTURE_GLOBAL_WATCH ? 1 : 0;
}

/*
@@ -1126,6 +1183,10 @@ static inline uint32_t rtems_capture_count_records( void* recs, size_t size )
*
* The 'timeout' parameter is in micro-seconds. A value of 0 will disable
* the timeout.
+ *
+ * XXX - When per_cpu is implemented threshold and timeout will be removed as
+ * parameters. The capture on flag must not be set when this command is called.
+ * A cpu index will be added to indicate which per_cpu buffer is needed.
*/
rtems_status_code
rtems_capture_read (uint32_t threshold,
@@ -1141,24 +1202,31 @@ rtems_capture_read (uint32_t threshold,
*read = 0;
*recs = NULL;

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);

/*
* Only one reader is allowed.
*/

- if (capture_flags & RTEMS_CAPTURE_READER_ACTIVE)
+ if (capture_flags_per_cpu & RTEMS_CAPTURE_READER_ACTIVE)
{
- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
return RTEMS_RESOURCE_IN_USE;
}

- capture_flags |= RTEMS_CAPTURE_READER_ACTIVE;
+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+ {
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
+ return RTEMS_UNSATISFIED;
+ }
+
+ capture_flags_per_cpu |= RTEMS_CAPTURE_READER_ACTIVE;

*recs = rtems_capture_buffer_peek( &capture_records, &recs_size );
+
*read = rtems_capture_count_records( *recs, recs_size );

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);

for (;;)
{
@@ -1182,11 +1250,11 @@ rtems_capture_read (uint32_t threshold,

rtems_task_ident (RTEMS_SELF, RTEMS_LOCAL, &capture_reader);

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);

- capture_flags |= RTEMS_CAPTURE_READER_WAITING;
+ capture_flags_per_cpu |= RTEMS_CAPTURE_READER_WAITING;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);

sc = rtems_event_receive (RTEMS_EVENT_0,
RTEMS_WAIT | RTEMS_EVENT_ANY,
@@ -1201,12 +1269,12 @@ rtems_capture_read (uint32_t threshold,
if ((sc != RTEMS_SUCCESSFUL) && (sc != RTEMS_TIMEOUT))
break;

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);

*recs = rtems_capture_buffer_peek( &capture_records, &recs_size );
*read = rtems_capture_count_records( *recs, recs_size );

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);

continue;
}
@@ -1224,6 +1292,9 @@ rtems_capture_read (uint32_t threshold,
/*
* This function releases the requested number of record slots back
* to the capture engine. The count must match the number read.
+ *
+ * XXX - A cpu index to indicate which per_cpu buffer to release data
+ * from will be added.
*/
rtems_status_code
rtems_capture_release (uint32_t count)
@@ -1236,12 +1307,18 @@ rtems_capture_release (uint32_t count)
size_t rel_size = 0;
rtems_status_code ret_val = RTEMS_SUCCESSFUL;

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);

if (count > capture_count)
count = capture_count;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ if ( (capture_flags_global & RTEMS_CAPTURE_ON) != 0 )
+ {
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);
+ return RTEMS_UNSATISFIED;
+ }
+
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);

counted = count;

@@ -1257,7 +1334,7 @@ rtems_capture_release (uint32_t count)
ptr += rec->size;
}

- rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
+ rtems_interrupt_lock_acquire (&capture_lock_per_cpu, &lock_context);

if (rel_size > ptr_size ) {
ret_val = RTEMS_INVALID_NUMBER;
@@ -1269,9 +1346,9 @@ rtems_capture_release (uint32_t count)
if (count)
rtems_capture_buffer_free( &capture_records, rel_size );

- capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
+ capture_flags_per_cpu &= ~RTEMS_CAPTURE_READER_ACTIVE;

- rtems_interrupt_lock_release (&capture_lock, &lock_context);
+ rtems_interrupt_lock_release (&capture_lock_per_cpu, &lock_context);

return ret_val;
}
@@ -1308,5 +1385,3 @@ rtems_capture_get_control_list (void)
{
return capture_controls;
}
-
-
diff --git a/cpukit/libmisc/capture/captureimpl.h b/cpukit/libmisc/capture/captureimpl.h
index 3c2f6c3..d9597e0 100644
--- a/cpukit/libmisc/capture/captureimpl.h
+++ b/cpukit/libmisc/capture/captureimpl.h
@@ -43,14 +43,19 @@ extern "C" {
/*
* Global capture flags.
*/
-#define RTEMS_CAPTURE_ON (1U << 0)
-#define RTEMS_CAPTURE_NO_MEMORY (1U << 1)
-#define RTEMS_CAPTURE_OVERFLOW (1U << 2)
+#define RTEMS_CAPTURE_INIT (1u << 0)
+#define RTEMS_CAPTURE_ON (1U << 1)
+#define RTEMS_CAPTURE_NO_MEMORY (1U << 2)
#define RTEMS_CAPTURE_TRIGGERED (1U << 3)
-#define RTEMS_CAPTURE_READER_ACTIVE (1U << 4)
-#define RTEMS_CAPTURE_READER_WAITING (1U << 5)
-#define RTEMS_CAPTURE_GLOBAL_WATCH (1U << 6)
-#define RTEMS_CAPTURE_ONLY_MONITOR (1U << 7)
+#define RTEMS_CAPTURE_GLOBAL_WATCH (1U << 4)
+#define RTEMS_CAPTURE_ONLY_MONITOR (1U << 5)
+
+/*
+ * Per-CPU capture flags.
+ */
+#define RTEMS_CAPTURE_OVERFLOW (1U << 0)
+#define RTEMS_CAPTURE_READER_ACTIVE (1U << 1)
+#define RTEMS_CAPTURE_READER_WAITING (1U << 2)

/**
* @brief Capture set extension index.
--
1.8.1.4
Loading...