summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2007-08-17 00:54:16 +0000
committerChris Johns <chrisj@rtems.org>2007-08-17 00:54:16 +0000
commit1374fd3f072fbb87f0a7af5726fb8a2571a8688e (patch)
tree98a75d741a0c81388858f8ef645265b751270f59 /cpukit
parent2007-08-13 Chris Johns <chrisj@rtems.org> (diff)
downloadrtems-1374fd3f072fbb87f0a7af5726fb8a2571a8688e.tar.bz2
2007-08-17 Chris Johns <chrisj@rtems.org>
* libmisc/capture/README: Minor copyright change. * libmisc/capture/capture-cli.c, libmisc/capture/capture.c, libmisc/capture/capture.h: Fixed the memory leak when lots of tasks are being created and deleted. Improved the trigger interface so all task type actions can be caught.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/ChangeLog7
-rw-r--r--cpukit/libmisc/capture/README2
-rw-r--r--cpukit/libmisc/capture/capture-cli.c866
-rw-r--r--cpukit/libmisc/capture/capture.c724
-rw-r--r--cpukit/libmisc/capture/capture.h344
5 files changed, 1306 insertions, 637 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog
index aff1600c1e..f4a8098c3b 100644
--- a/cpukit/ChangeLog
+++ b/cpukit/ChangeLog
@@ -1,3 +1,10 @@
+2007-08-17 Chris Johns <chrisj@rtems.org>
+ * libmisc/capture/README: Minor copyright change.
+ * libmisc/capture/capture-cli.c, libmisc/capture/capture.c,
+ libmisc/capture/capture.h: Fixed the memory leak when lots of
+ tasks are being created and deleted. Improved the trigger
+ interface so all task type actions can be caught.
+
2007-08-13 Chris Johns <chrisj@rtems.org>
* score/include/rtems/score/object.h: Point the
OBJECTS_RTEMS_CLASSES_LAST macro to the last entry.
diff --git a/cpukit/libmisc/capture/README b/cpukit/libmisc/capture/README
index 2ea76a4cfe..d12b5570d6 100644
--- a/cpukit/libmisc/capture/README
+++ b/cpukit/libmisc/capture/README
@@ -4,7 +4,7 @@
RTEMS Performance Monitoring and Measurement Framework
- Copyright 2002 Chris Johns (ccj@acm.org)
+ Copyright 2002-2007 Chris Johns (chrisj@rtems.org)
23 April 2002
This directory contains the source code for the performance monitoring and
diff --git a/cpukit/libmisc/capture/capture-cli.c b/cpukit/libmisc/capture/capture-cli.c
index 4c019a1958..42480df76b 100644
--- a/cpukit/libmisc/capture/capture-cli.c
+++ b/cpukit/libmisc/capture/capture-cli.c
@@ -38,7 +38,7 @@
#include <rtems/capture-cli.h>
#include <rtems/monitor.h>
-#define RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS (32)
+#define RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS (20)
/*
* The user capture timestamper.
@@ -63,20 +63,19 @@ static volatile int cli_load_thread_active;
static const char* open_usage = "usage: copen [-i] size\n";
static void
-rtems_capture_cli_open (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_open (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
- uint32_t size = 0;
+ uint32_t size = 0;
rtems_boolean enable = 0;
rtems_status_code sc;
int arg;
if (argc <= 1)
{
- fprintf(stdout,open_usage);
+ fprintf (stdout, open_usage);
return;
}
@@ -87,7 +86,7 @@ rtems_capture_cli_open (
if (argv[arg][1] == 'i')
enable = 1;
else
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
}
else
{
@@ -95,7 +94,7 @@ rtems_capture_cli_open (
if (size < 100)
{
- fprintf(stdout,"error: size must be greater than or equal to 100\n");
+ fprintf (stdout, "error: size must be greater than or equal to 100\n");
return;
}
}
@@ -105,11 +104,11 @@ rtems_capture_cli_open (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: open failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: open failed: %s\n", rtems_status_text (sc));
return;
}
- fprintf(stdout,"capture engine opened.\n");
+ fprintf (stdout, "capture engine opened.\n");
if (!enable)
return;
@@ -118,11 +117,11 @@ rtems_capture_cli_open (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: open enable failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: open enable failed: %s\n", rtems_status_text (sc));
return;
}
- fprintf(stdout,"capture engine enabled.\n");
+ fprintf (stdout, "capture engine enabled.\n");
}
/*
@@ -135,11 +134,10 @@ rtems_capture_cli_open (
*/
static void
-rtems_capture_cli_close (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_close (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
@@ -147,11 +145,11 @@ rtems_capture_cli_close (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: close failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: close failed: %s\n", rtems_status_text (sc));
return;
}
- fprintf(stdout,"capture engine closed.\n");
+ fprintf (stdout, "capture engine closed.\n");
}
/*
@@ -164,11 +162,10 @@ rtems_capture_cli_close (
*/
static void
-rtems_capture_cli_enable (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_enable (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
@@ -176,11 +173,11 @@ rtems_capture_cli_enable (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: enable failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: enable failed: %s\n", rtems_status_text (sc));
return;
}
- fprintf(stdout,"capture engine enabled.\n");
+ fprintf (stdout, "capture engine enabled.\n");
}
/*
@@ -193,11 +190,10 @@ rtems_capture_cli_enable (
*/
static void
-rtems_capture_cli_disable (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_disable (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
@@ -205,11 +201,11 @@ rtems_capture_cli_disable (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: disable failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: disable failed: %s\n", rtems_status_text (sc));
return;
}
- fprintf(stdout,"capture engine disabled.\n");
+ fprintf (stdout, "capture engine disabled.\n");
}
/*
@@ -222,17 +218,16 @@ rtems_capture_cli_disable (
*/
static void
-rtems_capture_cli_task_list (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_task_list (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
rtems_task_priority floor = rtems_capture_watch_get_floor ();
rtems_capture_task_t* task = rtems_capture_get_task_list ();
- uint32_t ticks;
- uint32_t tick_offset;
+ uint32_t ticks;
+ uint32_t tick_offset;
unsigned long long total_time;
int count = rtems_capture_task_count ();
@@ -244,9 +239,7 @@ rtems_capture_cli_task_list (
tick_offset = 0;
}
- total_time = (ticks * rtems_capture_task_time (task)) + tick_offset;
-
- fprintf(stdout,"total %i\n", count);
+ fprintf (stdout, "total %i\n", count);
while (task)
{
@@ -254,12 +247,15 @@ rtems_capture_cli_task_list (
int32_t stack_used;
int32_t time_used;
- stack_used = rtems_capture_task_stack_usage (task) * 100;
- stack_used /= rtems_capture_task_stack_size (task);
+ stack_used = rtems_capture_task_stack_usage (task);
+ if (stack_used)
+ stack_used = (stack_used * 100) / stack_used;
if (stack_used > 100)
stack_used = 100;
+ total_time = (ticks * rtems_capture_task_time (task)) + tick_offset;
+
time_used = (rtems_capture_task_time (task) * 100) / total_time;
if (time_used > 100)
@@ -267,32 +263,33 @@ rtems_capture_cli_task_list (
priority = rtems_capture_task_real_priority (task);
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_id (rtems_capture_task_id (task));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_name (rtems_capture_task_name (task));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_priority (rtems_capture_task_start_priority (task));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_priority (rtems_capture_task_real_priority (task));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_priority (rtems_capture_task_curr_priority (task));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_state (rtems_capture_task_state (task));
- fprintf(stdout," %c%c%c%c%c",
- rtems_capture_task_valid (task) ? 'a' : 'd',
- rtems_capture_task_flags (task) & RTEMS_CAPTURE_TRACED ? 't' : '-',
- rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
- rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
- rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
+ fprintf (stdout, " %c%c",
+ rtems_capture_task_valid (task) ? 'a' : 'd',
+ rtems_capture_task_flags (task) & RTEMS_CAPTURE_TRACED ? 't' : '-');
+
if ((floor > ceiling) && (ceiling > priority))
- fprintf(stdout,"--");
+ fprintf (stdout, "--");
else
- fprintf(stdout,"%c%c",
- rtems_capture_task_control (task) ?
- (rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
- rtems_capture_watch_global_on () ? 'g' : '-');
- fprintf(stdout," %3" PRId32 "%% %3" PRId32 "%% (%" PRIu32 ")\n",
+ {
+ uint32_t flags = rtems_capture_task_control_flags (task);
+ fprintf (stdout, "%c%c",
+ rtems_capture_task_control (task) ?
+ (flags & RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
+ rtems_capture_watch_global_on () ? 'g' : '-');
+ }
+ fprintf (stdout, " %3" PRId32 "%% %3" PRId32 "%% (%" PRIu32 ")\n",
stack_used, time_used, rtems_capture_task_ticks (task));
task = rtems_capture_next_task (task);
@@ -314,10 +311,7 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
rtems_task_priority floor = rtems_capture_watch_get_floor ();
int last_count = 0;
-
- fprintf(stdout,"\x1b[2J Press ENTER to exit.\n\n");
- fprintf(stdout," PID NAME RPRI CPRI STATE %%CPU %%STK FLGS EXEC TIME\n");
-
+
for (;;)
{
rtems_capture_task_t* tasks[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
@@ -341,6 +335,8 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
task = rtems_capture_get_task_list ();
+ total_time = 0;
+
while (task)
{
if (rtems_capture_task_valid (task))
@@ -349,6 +345,8 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
count++;
+ total_time += l;
+
for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
{
if (tasks[i])
@@ -371,12 +369,9 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
task = rtems_capture_next_task (task);
}
- fprintf(stdout,"\x1b[4;0H");
-
- total_time = 0;
-
- for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
- total_time += load[i];
+ fprintf (stdout, "\x1b[H\x1b[J Press ENTER to exit.\n\n");
+ fprintf (stdout,
+ " PID NAME RPRI CPRI STATE %%CPU %%STK FLGS EXEC TIME\n");
if (count > last_count)
j = count;
@@ -395,8 +390,9 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
j--;
- stack_used = rtems_capture_task_stack_usage (tasks[i]) * 100;
- stack_used /= rtems_capture_task_stack_size (tasks[i]);
+ stack_used = rtems_capture_task_stack_usage (tasks[i]);
+ if (stack_used)
+ stack_used = (stack_used * 100) / stack_used;
if (stack_used > 100)
stack_used = 100;
@@ -405,33 +401,32 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
priority = rtems_capture_task_real_priority (tasks[i]);
- fprintf(stdout,"\x1b[K");
+ fprintf (stdout, "\x1b[K");
rtems_monitor_dump_id (rtems_capture_task_id (tasks[i]));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_name (rtems_capture_task_name (tasks[i]));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_priority (priority);
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_priority (rtems_capture_task_curr_priority (tasks[i]));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
k = rtems_monitor_dump_state (rtems_capture_task_state (tasks[i]));
- fprintf(stdout,"%*c %3i.%03i%% ", 6 - k, ' ', task_load / 1000, task_load % 1000);
- fprintf(stdout,"%3i%% %c%c%c%c%c", stack_used,
+ fprintf (stdout, "%*c %3i.%03i%% ", 6 - k, ' ',
+ task_load / 1000, task_load % 1000);
+ fprintf (stdout, "%3i%% %c%c", stack_used,
rtems_capture_task_valid (tasks[i]) ? 'a' : 'd',
- rtems_capture_task_flags (tasks[i]) & RTEMS_CAPTURE_TRACED ? 't' : '-',
- rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
- rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
- rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
+ rtems_capture_task_flags (tasks[i]) & RTEMS_CAPTURE_TRACED ? 't' : '-');
+
if ((floor > ceiling) && (ceiling > priority))
- fprintf(stdout,"--");
+ fprintf (stdout, "--");
else
- fprintf(stdout,"%c%c",
+ fprintf (stdout, "%c%c",
rtems_capture_task_control (tasks[i]) ?
(rtems_capture_task_control_flags (tasks[i]) &
RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
rtems_capture_watch_global_on () ? 'g' : '-');
- fprintf(stdout," %qi\n", rtems_capture_task_time (tasks[i]));
+ fprintf (stdout, " %qi\n", rtems_capture_task_time (tasks[i]));
}
if (count < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS)
@@ -439,7 +434,7 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
j = RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS - count;
while (j > 0)
{
- fprintf(stdout,"\x1b[K\n");
+ fprintf (stdout, "\x1b[K\n");
j--;
}
}
@@ -462,11 +457,10 @@ rtems_capture_cli_task_load_thread (rtems_task_argument arg)
*/
static void
-rtems_capture_cli_task_load (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_task_load (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
rtems_task_priority priority;
@@ -477,20 +471,22 @@ rtems_capture_cli_task_load (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: cannot obtain the current priority: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: cannot obtain the current priority: %s\n",
+ rtems_status_text (sc));
return;
}
- memcpy (&name, "CPlt", 4);
-
- sc = rtems_task_create (name, priority, 1024,
+ name = rtems_build_name('C', 'P', 'l', 't');
+
+ sc = rtems_task_create (name, priority, 4 * 1024,
RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
&id);
-
- if (sc != RTEMS_SUCCESSFUL)
+
+ if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: cannot create helper thread: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: cannot create helper thread: %s\n",
+ rtems_status_text (sc));
return;
}
@@ -498,7 +494,8 @@ rtems_capture_cli_task_load (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: cannot start helper thread: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: cannot start helper thread: %s\n",
+ rtems_status_text (sc));
rtems_task_delete (id);
return;
}
@@ -516,7 +513,7 @@ rtems_capture_cli_task_load (
rtems_task_delete (id);
- fprintf(stdout,"load monitoring stopped.\n");
+ fprintf (stdout, "load monitoring stopped.\n");
return;
}
@@ -533,63 +530,81 @@ rtems_capture_cli_task_load (
*/
static void
-rtems_capture_cli_watch_list (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_watch_list (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_capture_control_t* control = rtems_capture_get_control_list ();
rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
rtems_task_priority floor = rtems_capture_watch_get_floor ();
- fprintf(stdout,"watch priority ceiling is %" PRId32 "\n", ceiling);
- fprintf(stdout,"watch priority floor is %" PRId32 "\n", floor);
- fprintf(stdout,"global watch is %s\n",
+ fprintf (stdout, "watch priority ceiling is %" PRId32 "\n", ceiling);
+ fprintf (stdout, "watch priority floor is %" PRId32 "\n", floor);
+ fprintf (stdout, "global watch is %s\n",
rtems_capture_watch_global_on () ? "enabled" : "disabled");
- fprintf(stdout,"total %" PRId32 "\n", rtems_capture_control_count ());
+ fprintf (stdout, "total %" PRId32 "\n", rtems_capture_control_count ());
while (control)
{
- int f;
- int fshowed;
- int lf;
+ uint32_t flags;
+ int f;
+ int fshowed;
+ int lf;
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_id (rtems_capture_control_id (control));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_name (rtems_capture_control_name (control));
- fprintf(stdout," %c%c%c%c%c",
- rtems_capture_control_flags (control) & RTEMS_CAPTURE_WATCH ? 'w' : '-',
- rtems_capture_watch_global_on () ? 'g' : '-',
- rtems_capture_control_flags (control) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
- rtems_capture_control_flags (control) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
- rtems_capture_control_flags (control) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
+ flags = rtems_capture_control_flags (control);
+ fprintf (stdout, " %c%c ",
+ rtems_capture_watch_global_on () ? 'g' : '-',
+ flags & RTEMS_CAPTURE_WATCH ? 'w' : '-');
+ flags = rtems_capture_control_to_triggers (control);
+ fprintf (stdout, " T:%c%c%c%c%c%c%c",
+ flags & RTEMS_CAPTURE_SWITCH ? 'S' : '-',
+ flags & RTEMS_CAPTURE_CREATE ? 'C' : '-',
+ flags & RTEMS_CAPTURE_START ? 'S' : '-',
+ flags & RTEMS_CAPTURE_RESTART ? 'R' : '-',
+ flags & RTEMS_CAPTURE_DELETE ? 'D' : '-',
+ flags & RTEMS_CAPTURE_BEGIN ? 'B' : '-',
+ flags & RTEMS_CAPTURE_EXITTED ? 'E' : '-');
+ flags = rtems_capture_control_from_triggers (control);
+ fprintf (stdout, " F:%c%c%c%c%c",
+ flags & RTEMS_CAPTURE_SWITCH ? 'S' : '-',
+ flags & RTEMS_CAPTURE_CREATE ? 'C' : '-',
+ flags & RTEMS_CAPTURE_START ? 'S' : '-',
+ flags & RTEMS_CAPTURE_RESTART ? 'R' : '-',
+ flags & RTEMS_CAPTURE_DELETE ? 'D' : '-');
for (f = 0, fshowed = 0, lf = 1; f < RTEMS_CAPTURE_TRIGGER_TASKS; f++)
{
- if (lf && ((fshowed % 16) == 0))
+ if (rtems_capture_control_by_valid (control, f))
{
- fprintf(stdout,"\n");
- lf = 0;
- }
+ if (lf && ((fshowed % 3) == 0))
+ {
+ fprintf (stdout, "\n");
+ lf = 0;
+ }
- /*
- * FIXME: name test.
- */
- if (rtems_capture_control_from_name (control, f))
- {
- fprintf(stdout," %2i:", f);
- rtems_monitor_dump_name (rtems_capture_control_from_name (control, f));
- fprintf(stdout,"/");
- rtems_monitor_dump_id (rtems_capture_control_from_id (control, f));
+ fprintf (stdout, " %2i:", f);
+ rtems_monitor_dump_name (rtems_capture_control_by_name (control, f));
+ fprintf (stdout, "/");
+ rtems_monitor_dump_id (rtems_capture_control_by_id (control, f));
+ flags = rtems_capture_control_by_triggers (control, f);
+ fprintf (stdout, ":%c%c%c%c%c",
+ flags & RTEMS_CAPTURE_SWITCH ? 'S' : '-',
+ flags & RTEMS_CAPTURE_CREATE ? 'C' : '-',
+ flags & RTEMS_CAPTURE_START ? 'S' : '-',
+ flags & RTEMS_CAPTURE_RESTART ? 'R' : '-',
+ flags & RTEMS_CAPTURE_DELETE ? 'D' : '-');
fshowed++;
lf = 1;
}
}
if (lf)
- fprintf(stdout,"\n");
+ fprintf (stdout, "\n");
control = rtems_capture_next_control (control);
}
@@ -611,13 +626,12 @@ rtems_capture_cli_get_name_id (char* arg,
rtems_name* name,
rtems_id* id)
{
- uint32_t objclass;
- size_t l;
- size_t i;
+ size_t l;
+ size_t i;
if (*valid_name && *valid_id)
{
- fprintf(stdout,"error: too many arguments\n");
+ fprintf (stdout, "error: too many arguments\n");
return 0;
}
@@ -631,15 +645,26 @@ rtems_capture_cli_get_name_id (char* arg,
if (!isxdigit (arg[i]))
break;
- *id = strtoul (arg, 0, 16);
-
- objclass = _Objects_Get_class (*id);
-
- if ((i == l))
+ if (i == l)
+ {
+ *id = strtoul (arg, 0, 16);
*valid_id = 1;
+ }
else
{
- memcpy (name, arg, sizeof (rtems_name));
+ /*
+ * This is a bit of hack but it should work on all platforms
+ * as it is what the score does with names.
+ *
+ * @warning The extra assigns play with the byte order so do not
+ * remove unless the score has been updated.
+ */
+ Objects_Name object_name;
+ rtems_name rname;
+
+ rname = rtems_build_name(arg[0], arg[1], arg[2], arg[3]);
+ object_name = (Objects_Name) rname;
+ *name = (rtems_name) object_name;
*valid_name = 1;
}
@@ -659,11 +684,10 @@ rtems_capture_cli_get_name_id (char* arg,
static char const * watch_add_usage = "usage: cwadd [task name] [id]\n";
static void
-rtems_capture_cli_watch_add (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_watch_add (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
int arg;
@@ -674,7 +698,7 @@ rtems_capture_cli_watch_add (
if (argc <= 1)
{
- fprintf(stdout,watch_add_usage);
+ fprintf (stdout, watch_add_usage);
return;
}
@@ -682,18 +706,19 @@ rtems_capture_cli_watch_add (
{
if (argv[arg][0] == '-')
{
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
}
else
{
- if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
+ if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id,
+ &name, &id))
return;
}
}
if (!valid_name && !valid_id)
{
- fprintf(stdout,"error: no valid name or task id located\n");
+ fprintf (stdout, "error: no valid name or task id located\n");
return;
}
@@ -701,11 +726,12 @@ rtems_capture_cli_watch_add (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: watch add failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout,
+ "error: watch add failed: %s\n", rtems_status_text (sc));
return;
}
- fprintf(stdout,"watch added.\n");
+ fprintf (stdout, "watch added.\n");
}
/*
@@ -721,11 +747,10 @@ rtems_capture_cli_watch_add (
static char const * watch_del_usage = "usage: cwdel [task name] [id]\n";
static void
-rtems_capture_cli_watch_del (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_watch_del (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
int arg;
@@ -736,7 +761,7 @@ rtems_capture_cli_watch_del (
if (argc <= 1)
{
- fprintf(stdout,watch_del_usage);
+ fprintf (stdout, watch_del_usage);
return;
}
@@ -744,18 +769,19 @@ rtems_capture_cli_watch_del (
{
if (argv[arg][0] == '-')
{
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
}
else
{
- if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
+ if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id,
+ &name, &id))
return;
}
}
if (!valid_name && !valid_id)
{
- fprintf(stdout,"error: no valid name or task id located\n");
+ fprintf (stdout, "error: no valid name or task id located\n");
return;
}
@@ -763,11 +789,12 @@ rtems_capture_cli_watch_del (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: watch delete failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: watch delete failed: %s\n",
+ rtems_status_text (sc));
return;
}
- fprintf(stdout,"watch delete.\n");
+ fprintf (stdout, "watch delete.\n");
}
/*
@@ -782,11 +809,10 @@ rtems_capture_cli_watch_del (
static char const * watch_control_usage = "usage: cwctl [task name] [id] on/off\n";
static void
-rtems_capture_cli_watch_control (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_watch_control (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
int arg;
@@ -798,7 +824,7 @@ rtems_capture_cli_watch_control (
if (argc <= 2)
{
- fprintf(stdout,watch_control_usage);
+ fprintf (stdout, watch_control_usage);
return;
}
@@ -806,7 +832,7 @@ rtems_capture_cli_watch_control (
{
if (argv[arg][0] == '-')
{
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
}
else
{
@@ -814,14 +840,15 @@ rtems_capture_cli_watch_control (
enable = 1;
else if (strcmp (argv[arg], "off") == 0)
enable = 0;
- else if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
+ else if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name,
+ &valid_id, &name, &id))
return;
}
}
if (!valid_name && !valid_id)
{
- fprintf(stdout,"error: no valid name or task id located\n");
+ fprintf (stdout, "error: no valid name or task id located\n");
return;
}
@@ -829,11 +856,12 @@ rtems_capture_cli_watch_control (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: watch control failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: watch control failed: %s\n",
+ rtems_status_text (sc));
return;
}
- fprintf(stdout,"watch %s.\n", enable ? "enabled" : "disabled");
+ fprintf (stdout, "watch %s.\n", enable ? "enabled" : "disabled");
}
/*
@@ -848,11 +876,10 @@ rtems_capture_cli_watch_control (
static char const * watch_global_usage = "usage: cwglob on/off\n";
static void
-rtems_capture_cli_watch_global (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_watch_global (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
int arg;
@@ -860,7 +887,7 @@ rtems_capture_cli_watch_global (
if (argc <= 1)
{
- fprintf(stdout,watch_global_usage);
+ fprintf (stdout, watch_global_usage);
return;
}
@@ -868,7 +895,7 @@ rtems_capture_cli_watch_global (
{
if (argv[arg][0] == '-')
{
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
}
else
{
@@ -883,11 +910,12 @@ rtems_capture_cli_watch_global (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: global watch failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: global watch failed: %s\n",
+ rtems_status_text (sc));
return;
}
- fprintf(stdout,"global watch %s.\n", enable ? "enabled" : "disabled");
+ fprintf (stdout, "global watch %s.\n", enable ? "enabled" : "disabled");
}
/*
@@ -902,11 +930,10 @@ rtems_capture_cli_watch_global (
static char const * watch_ceiling_usage = "usage: cwceil priority\n";
static void
-rtems_capture_cli_watch_ceiling (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_watch_ceiling (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
int arg;
@@ -914,7 +941,7 @@ rtems_capture_cli_watch_ceiling (
if (argc <= 1)
{
- fprintf(stdout,watch_ceiling_usage);
+ fprintf (stdout, watch_ceiling_usage);
return;
}
@@ -922,7 +949,7 @@ rtems_capture_cli_watch_ceiling (
{
if (argv[arg][0] == '-')
{
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
}
else
{
@@ -934,11 +961,12 @@ rtems_capture_cli_watch_ceiling (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: watch ceiling failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: watch ceiling failed: %s\n",
+ rtems_status_text (sc));
return;
}
- fprintf(stdout,"watch ceiling is %" PRId32 ".\n", priority);
+ fprintf (stdout, "watch ceiling is %" PRId32 ".\n", priority);
}
/*
@@ -953,11 +981,10 @@ rtems_capture_cli_watch_ceiling (
static char const * watch_floor_usage = "usage: cwfloor priority\n";
static void
-rtems_capture_cli_watch_floor (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_watch_floor (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
int arg;
@@ -965,7 +992,7 @@ rtems_capture_cli_watch_floor (
if (argc <= 1)
{
- fprintf(stdout,watch_floor_usage);
+ fprintf (stdout, watch_floor_usage);
return;
}
@@ -973,7 +1000,7 @@ rtems_capture_cli_watch_floor (
{
if (argv[arg][0] == '-')
{
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
}
else
{
@@ -985,169 +1012,277 @@ rtems_capture_cli_watch_floor (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: watch floor failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: watch floor failed: %s\n",
+ rtems_status_text (sc));
return;
}
- fprintf(stdout,"watch floor is %" PRId32 ".\n", priority);
+ fprintf (stdout, "watch floor is %" PRId32 ".\n", priority);
}
/*
- * rtems_capture_cli_trigger_set
+ * rtems_capture_cli_trigger_worker
*
* DESCRIPTION:
*
- * This function is a monitor command that sets a trigger.
+ * This function is a monitor command that sets or clears a trigger.
*
*/
-static char const *trigger_set_usage = "usage: ctrig type [from] [fromid] [to] [to id]\n";
+static char const *trigger_set_usage =
+ "usage: %s [-?] type [to name/id] [from] [from name/id]\n";
+
+static char const *trigger_set_types =
+ " You can say 'type TASK' or 'type TO from FROM'\n" \
+ " where TASK is the task the event is happening to\n" \
+ " or you can say the event TO this task FROM this task.\n" \
+ " No type defaults to 'switch'.\n" \
+ " switch : context switch TASK or FROM or FROM->TO\n" \
+ " create : create TASK, or create TO from FROM\n" \
+ " start : start TASK, or start TO from FROM\n" \
+ " restart : restart TASK, or restart TO from FROM\n" \
+ " delete : delete TASK or delete TO from FROM\n" \
+ " begin : begin TASK\n" \
+ " exitted : exitted TASK\n";
-static void
-rtems_capture_cli_trigger_set (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+/*
+ * Structure to handle the parsing of the trigger command line.
+ */
+typedef struct rtems_capture_cli_triggers_s
{
- rtems_status_code sc;
- int arg;
- rtems_capture_trigger_t trigger = rtems_capture_from_to;
- rtems_boolean trigger_set = 0;
- rtems_name name = 0;
- rtems_id id = 0;
- rtems_boolean valid_name = 0;
- rtems_boolean valid_id = 0;
- rtems_name from_name = 0;
- rtems_id from_id = 0;
- rtems_boolean from_valid_name = 0;
- rtems_boolean from_valid_id = 0;
- rtems_name to_name = 0;
- rtems_id to_id = 0;
- rtems_boolean to_valid_name = 0;
- rtems_boolean to_valid_id = 0;
+ char const * name;
+ rtems_capture_trigger_t type;
+ int to_only;
+} rtems_capture_cli_triggers_t;
- if (argc <= 2)
- {
- fprintf(stdout,trigger_set_usage);
- return;
- }
+static rtems_capture_cli_triggers_t rtems_capture_cli_triggers[] =
+{
+ { "switch", rtems_capture_switch, 0 }, /* must be first */
+ { "create", rtems_capture_create, 0 },
+ { "start", rtems_capture_start, 0 },
+ { "restart", rtems_capture_restart, 0 },
+ { "delete", rtems_capture_delete, 0 },
+ { "begin", rtems_capture_begin, 1 },
+ { "exitted", rtems_capture_exitted, 1 }
+};
+
+typedef enum rtems_capture_cli_trig_state_e
+{
+ trig_type,
+ trig_to,
+ trig_from_from,
+ trig_from
+} rtems_capture_cli_trig_state_t;
+
+#define RTEMS_CAPTURE_CLI_TRIGGERS_NUM \
+ (sizeof (rtems_capture_cli_triggers) / sizeof (rtems_capture_cli_triggers_t))
+
+static void
+rtems_capture_cli_trigger_worker (int set, int argc, char** argv)
+{
+ rtems_status_code sc;
+ int arg;
+ int trigger = 0; /* switch */
+ rtems_capture_trigger_mode_t trigger_mode = rtems_capture_from_any;
+ rtems_boolean trigger_set = 0;
+ rtems_boolean is_from = 0;
+ rtems_name name = 0;
+ rtems_id id = 0;
+ rtems_boolean valid_name = 0;
+ rtems_boolean valid_id = 0;
+ rtems_name from_name = 0;
+ rtems_id from_id = 0;
+ rtems_boolean from_valid_name = 0;
+ rtems_boolean from_valid_id = 0;
+ rtems_name to_name = 0;
+ rtems_id to_id = 0;
+ rtems_boolean to_valid_name = 0;
+ rtems_boolean to_valid_id = 0;
for (arg = 1; arg < argc; arg++)
{
if (argv[arg][0] == '-')
{
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ switch (argv[arg][1])
+ {
+ case '?':
+ fprintf (stdout, trigger_set_usage, set ? "ctset" : "ctclear");
+ fprintf (stdout, trigger_set_types);
+ return;
+ default:
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
+ break;
+ }
}
else
{
if (!trigger_set)
{
- if (strcmp (argv[arg], "from") == 0)
- trigger = rtems_capture_to_any;
- else if (strcmp (argv[arg], "to") == 0)
- trigger = rtems_capture_from_any;
- else if (strcmp (argv[arg], "edge") == 0)
- trigger = rtems_capture_from_any;
- else
- {
- fprintf(stdout,"error: the first argument is the trigger type (from/to/edge)\n");
- return;
- }
+ rtems_boolean found = 0;
+ int t;
+
+ for (t = 0; t < RTEMS_CAPTURE_CLI_TRIGGERS_NUM; t++)
+ if (strcmp (argv[arg], rtems_capture_cli_triggers[t].name) == 0)
+ {
+ trigger = t;
+ found = 1;
+ break;
+ }
+
trigger_set = 1;
+
+ /*
+ * If a trigger was not found assume the default and
+ * assume the parameter is a task name or id.
+ */
+ if (found)
+ continue;
}
- else
+
+ if (strcmp (arg[argv], "from") == 0)
+ {
+ if (is_from)
+ fprintf (stdout, "warning: extra 'from' ignored\n");
+
+ is_from = 1;
+ continue;
+ }
+
+ if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id,
+ &name, &id))
+ return;
+
+ if (valid_name)
{
- if (trigger == rtems_capture_to_any)
+ if (is_from)
{
- if (from_valid_name && from_valid_id)
- fprintf(stdout,"warning: extra arguments ignored\n");
- else if (!rtems_capture_cli_get_name_id (argv[arg], &from_valid_name, &from_valid_id,
- &from_name, &from_id))
- return;
+ if (!from_valid_name && !from_valid_id)
+ {
+ from_valid_name = 1;
+ from_name = name;
+ }
+ else
+ fprintf (stdout, "warning: extra arguments ignored\n");
}
- else if (trigger == rtems_capture_from_any)
+ else if (!to_valid_name && !to_valid_id)
{
- if (to_valid_name && to_valid_id)
- fprintf(stdout,"warning: extra arguments ignored\n");
- else if (!rtems_capture_cli_get_name_id (argv[arg], &to_valid_name, &to_valid_id,
- &to_name, &to_id))
- return;
+ to_valid_name = 1;
+ to_name = name;
}
- else if (trigger == rtems_capture_from_to)
+ else
+ fprintf (stdout, "warning: extra arguments ignored\n");
+ }
+
+ if (valid_id)
+ {
+ if (is_from)
{
- if (from_valid_name && from_valid_id && to_valid_name && to_valid_id)
- fprintf(stdout,"warning: extra arguments ignored\n");
- else
+ if (!from_valid_name && !from_valid_id)
{
- if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id,
- &name, &id))
- return;
-
- if (valid_name)
- {
- if (!from_valid_name && !from_valid_id)
- {
- from_valid_name = 1;
- from_name = name;
- }
- else if (to_valid_name)
- fprintf(stdout,"warning: extra arguments ignored\n");
- else
- {
- to_valid_name = 1;
- to_name = name;
- }
- }
- if (valid_id)
- {
- if (!from_valid_id && !to_valid_name)
- {
- from_valid_id = 1;
- from_id = id;
- }
- else if (to_valid_id)
- fprintf(stdout,"warning: extra arguments ignored\n");
- else
- {
- to_valid_id = 1;
- to_id = id;
- }
- }
+ from_valid_id = 1;
+ from_id = id;
}
+ else
+ fprintf (stdout, "warning: extra arguments ignored\n");
+ }
+ else if (!to_valid_name && !to_valid_id)
+ {
+ to_valid_id = 1;
+ to_id = id;
}
+ else
+ fprintf (stdout, "warning: extra arguments ignored\n");
}
}
}
- if ((trigger == rtems_capture_to_any) && !from_valid_name && !from_valid_id)
+ if (is_from && rtems_capture_cli_triggers[trigger].to_only)
+ {
+ fprintf (stdout, "error: a %s trigger can be a TO trigger\n",
+ rtems_capture_cli_triggers[trigger].name);
+ return;
+ }
+
+ if (!to_valid_name && !to_valid_id && !from_valid_name && !from_valid_id)
{
- fprintf(stdout,"error: a from trigger need a to name or id\n");
+ fprintf (stdout, trigger_set_usage);
return;
}
- if ((trigger == rtems_capture_from_any) && !to_valid_name && !to_valid_id)
+ if (!is_from && !to_valid_name && !to_valid_id)
{
- fprintf(stdout,"error: a to trigger need a from name or id\n");
+ fprintf (stdout, "error: a %s trigger needs a TO name or id\n",
+ rtems_capture_cli_triggers[trigger].name);
return;
}
- if ((trigger == rtems_capture_from_to) &&
- ((!from_valid_name && !from_valid_id) || (!to_valid_name && !to_valid_id)))
+ if (is_from && !from_valid_name && !from_valid_id)
{
- fprintf(stdout,"error: an edge trigger need a from and to name or id\n");
+ fprintf (stdout, "error: a %s trigger needs a FROM name or id\n",
+ rtems_capture_cli_triggers[trigger].name);
return;
}
- sc = rtems_capture_set_trigger (from_name, from_id, to_name, to_id, trigger);
+ if ((from_valid_name || from_valid_id) && (to_valid_name || to_valid_id))
+ trigger_mode = rtems_capture_from_to;
+ else if (from_valid_name || from_valid_id)
+ trigger_mode = rtems_capture_to_any;
+ else if (to_valid_name || to_valid_id)
+ trigger_mode = rtems_capture_from_any;
+
+ if (set)
+ sc = rtems_capture_set_trigger (from_name, from_id, to_name, to_id,
+ trigger_mode,
+ rtems_capture_cli_triggers[trigger].type);
+ else
+ sc = rtems_capture_clear_trigger (from_name, from_id, to_name, to_id,
+ trigger_mode,
+ rtems_capture_cli_triggers[trigger].type);
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: setting the trigger failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: %sing the trigger failed: %s\n",
+ set ? "sett" : "clear", rtems_status_text (sc));
return;
}
- fprintf(stdout,"trigger set.\n");
+ fprintf (stdout, "trigger %s.\n", set ? "set" : "cleared");
+}
+
+/*
+ * rtems_capture_cli_trigger_set
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that sets a trigger.
+ *
+ */
+
+static void
+rtems_capture_cli_trigger_set (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
+{
+ rtems_capture_cli_trigger_worker (1, argc, argv);
+}
+
+/*
+ * rtems_capture_cli_trigger_clear
+ *
+ * DESCRIPTION:
+ *
+ * This function is a monitor command that clears a trigger.
+ *
+ */
+
+static void
+rtems_capture_cli_trigger_clear (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
+{
+ rtems_capture_cli_trigger_worker (0, argc, argv);
}
/*
@@ -1160,18 +1295,17 @@ rtems_capture_cli_trigger_set (
*/
static void
-rtems_capture_cli_trace_records (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_trace_records (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
rtems_boolean csv = 0;
- static int dump_total = 32;
+ static int dump_total = 22;
int total;
int count;
- uint32_t read;
+ uint32_t read;
rtems_capture_record_t* rec;
int arg;
@@ -1181,31 +1315,24 @@ rtems_capture_cli_trace_records (
{
if (argv[arg][1] == 'c')
csv = 1;
- else if (argv[arg][1] == 'r')
- {
- int i;
- int l;
+ else
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
+ }
+ else
+ {
+ int i;
+ int l;
+
+ l = strlen (argv[arg]);
- arg++;
- if (arg == argc)
+ for (i = 0; i < l; i++)
+ if (!isdigit (argv[arg][i]))
{
- fprintf(stdout,"error: option -r requires number\n");
+ fprintf (stdout, "error: not a number\n");
return;
}
- l = strlen (argv[arg]);
-
- for (i = 0; i < l; i++)
- if (!isdigit (argv[arg][i]))
- {
- fprintf(stdout,"error: option -r requires number and currently it is not\n");
- return;
- }
-
- dump_total = strtoul (argv[arg], 0, 0);
- }
- else
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ dump_total = strtoul (argv[arg], 0, 0);
}
}
@@ -1217,18 +1344,28 @@ rtems_capture_cli_trace_records (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: trace read failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: trace read failed: %s\n", rtems_status_text (sc));
rtems_capture_flush (0);
return;
}
+ /*
+ * If we have no records then just exist. We still need to release
+ * the reader lock.
+ */
+
if (read == 0)
+ {
+ rtems_capture_release (read);
break;
+ }
- for (count = 0; count < read; count++, rec++)
+ count = total < read ? total : read;
+
+ while (count--)
{
if (csv)
- fprintf(stdout,"%08" PRIx32 ",%03" PRIu32
+ fprintf (stdout, "%08" PRIx32 ",%03" PRIu32
",%03" PRIu32 ",%04" PRIx32 ",%" PRId32 ",%" PRId32 "\n",
(uint32_t) rec->task,
(rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
@@ -1251,12 +1388,12 @@ rtems_capture_cli_trace_records (
{
if (event & 1)
{
- fprintf(stdout,"%9li.%06li ", (unsigned long) (t / 1000000),
+ fprintf (stdout, "%9li.%06li ", (unsigned long) (t / 1000000),
(unsigned long) (t % 1000000));
rtems_monitor_dump_id (rtems_capture_task_id (rec->task));
- fprintf(stdout," ");
+ fprintf (stdout, " ");
rtems_monitor_dump_name (rtems_capture_task_name (rec->task));
- fprintf(stdout," %3" PRId32 " %3" PRId32 " %s\n",
+ fprintf (stdout, " %3" PRId32 " %3" PRId32 " %s\n",
(rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
(rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff,
rtems_capture_event_text (e));
@@ -1264,14 +1401,17 @@ rtems_capture_cli_trace_records (
event >>= 1;
}
}
+ rec++;
}
- if (read < total)
- total -= read;
+ count = total < read ? total : read;
+
+ if (count < total)
+ total -= count;
else
total = 0;
- rtems_capture_release (read);
+ rtems_capture_release (count);
}
}
@@ -1286,11 +1426,10 @@ rtems_capture_cli_trace_records (
*/
static void
-rtems_capture_cli_flush (
- int argc,
- char **argv,
- rtems_monitor_command_arg_t *command_arg,
- boolean verbose )
+rtems_capture_cli_flush (int argc,
+ char** argv,
+ rtems_monitor_command_arg_t* command_arg,
+ boolean verbose)
{
rtems_status_code sc;
rtems_boolean prime = 1;
@@ -1303,7 +1442,7 @@ rtems_capture_cli_flush (
if (argv[arg][1] == 'n')
prime = 0;
else
- fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
+ fprintf (stdout, "warning: option -%c ignored\n", argv[arg][1]);
}
}
@@ -1311,11 +1450,12 @@ rtems_capture_cli_flush (
if (sc != RTEMS_SUCCESSFUL)
{
- fprintf(stdout,"error: flush failed: %s\n", rtems_status_text (sc));
+ fprintf (stdout, "error: flush failed: %s\n", rtems_status_text (sc));
return;
}
- fprintf(stdout,"trace buffer flushed and %s.\n", prime ? "primed" : "not primed");
+ fprintf (stdout, "trace buffer flushed and %s.\n",
+ prime ? "primed" : "not primed");
}
static rtems_monitor_command_entry_t rtems_capture_cli_cmds[] =
@@ -1433,14 +1573,22 @@ static rtems_monitor_command_entry_t rtems_capture_cli_cmds[] =
0
},
{
- "ctrig",
- "usage: ctrig type [from name] [from id] [to name] [to id]\n",
+ "ctset",
+ "usage: ctset -h\n",
0,
rtems_capture_cli_trigger_set,
{ 0 },
0
},
{
+ "ctclear",
+ "usage: ctclear -?\n",
+ 0,
+ rtems_capture_cli_trigger_clear,
+ { 0 },
+ 0
+ },
+ {
"cflush",
"usage: cflush [-n]\n",
0,
diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c
index 3e571382f5..e8c6396490 100644
--- a/cpukit/libmisc/capture/capture.c
+++ b/cpukit/libmisc/capture/capture.c
@@ -38,7 +38,11 @@
/*
* These events are always recorded and are not part of the
* watch filters.
+ *
+ * This feature has been disabled as it becomes confusing when
+ * setting up filters and some event leak.
*/
+#if defined (RTEMS_CAPTURE_ENGINE_ALLOW_RELATED_EVENTS)
#define RTEMS_CAPTURE_RECORD_EVENTS (RTEMS_CAPTURE_CREATED_BY_EVENT | \
RTEMS_CAPTURE_CREATED_EVENT | \
RTEMS_CAPTURE_STARTED_BY_EVENT | \
@@ -49,6 +53,9 @@
RTEMS_CAPTURE_DELETED_EVENT | \
RTEMS_CAPTURE_BEGIN_EVENT | \
RTEMS_CAPTURE_EXITTED_EVENT)
+#else
+#define RTEMS_CAPTURE_RECORD_EVENTS (0)
+#endif
/*
* Global capture flags.
@@ -60,16 +67,17 @@
#define RTEMS_CAPTURE_READER_ACTIVE (1 << 4)
#define RTEMS_CAPTURE_READER_WAITING (1 << 5)
#define RTEMS_CAPTURE_GLOBAL_WATCH (1 << 6)
+#define RTEMS_CAPTURE_ONLY_MONITOR (1 << 7)
/*
* RTEMS Capture Data.
*/
static rtems_capture_record_t* capture_records;
-static uint32_t capture_size;
-static uint32_t capture_count;
+static uint32_t capture_size;
+static uint32_t capture_count;
static rtems_capture_record_t* capture_in;
-static uint32_t capture_out;
-static uint32_t capture_flags;
+static uint32_t capture_out;
+static uint32_t capture_flags;
static rtems_capture_task_t* capture_tasks;
static rtems_capture_control_t* capture_controls;
static int capture_extension_index;
@@ -77,9 +85,8 @@ static rtems_id capture_id;
static rtems_capture_timestamp capture_timestamp;
static rtems_task_priority capture_ceiling;
static rtems_task_priority capture_floor;
-static uint32_t capture_tick_period;
+static uint32_t capture_tick_period;
static rtems_id capture_reader;
-int rtems_capture_free_info_on_task_delete;
/*
* RTEMS Event text.
@@ -109,8 +116,8 @@ static const char* capture_event_text[] =
* This function returns the current time. If a handler is provided
* by the user get the time from that.
*/
-static inline void rtems_capture_get_time (uint32_t * ticks,
- uint32_t * tick_offset)
+static inline void rtems_capture_get_time (uint32_t* ticks,
+ uint32_t* tick_offset)
{
if (capture_timestamp)
capture_timestamp (ticks, tick_offset);
@@ -138,6 +145,48 @@ rtems_capture_match_names (rtems_name lhs, rtems_name rhs)
}
/*
+ * rtems_capture_match_id
+ *
+ * DESCRIPTION:
+ *
+ * This function compares rtems_ids. It protects the
+ * capture engine from a change to the way id are supported
+ * in RTEMS.
+ *
+ */
+static inline rtems_boolean
+rtems_capture_match_ids (rtems_id lhs, rtems_id rhs)
+{
+ return lhs == rhs;
+}
+
+/*
+ * rtems_capture_match_name_id
+ *
+ * DESCRIPTION:
+ *
+ * This function matches a name and/or id.
+ */
+static inline rtems_boolean
+rtems_capture_match_name_id (rtems_name lhs_name,
+ rtems_id lhs_id,
+ rtems_name rhs_name,
+ rtems_id rhs_id)
+{
+ /*
+ * 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))
+ {
+ if (rtems_capture_match_names (lhs_name, rhs_name))
+ return 1;
+ }
+ return 0;
+}
+
+/*
* rtems_capture_dup_name
*
* DESCRIPTION:
@@ -154,50 +203,84 @@ rtems_capture_dup_name (rtems_name* dst, rtems_name src)
}
/*
- * rtems_capture_name_in_group
+ * rtems_capture_by_in_to
*
* DESCRIPTION:
*
- * This function sees if a name is in a group of names.
+ * This function sees if a BY control is in the BY names. The use
+ * of the valid_mask in this way assumes the number of trigger
+ * tasks is the number of bits in uint32_t.
*
*/
static inline rtems_boolean
-rtems_capture_name_in_group (rtems_name task, rtems_name* tasks)
+rtems_capture_by_in_to (uint32_t events,
+ rtems_capture_task_t* by,
+ rtems_capture_control_t* to)
{
- if (tasks)
+ uint32_t valid_mask = RTEMS_CAPTURE_CONTROL_FROM_MASK (0);
+ uint32_t valid_remainder = 0xffffffff;
+ int i;
+
+ for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)
{
- int i;
- for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)
- if (rtems_capture_match_names (task, *tasks++))
+ /*
+ * If there are no more valid BY entries then
+ * we are finished.
+ */
+ if ((valid_remainder & to->by_valid) == 0)
+ break;
+
+ /*
+ * Is the froby entry valid and does its name or id match.
+ */
+ if ((valid_mask & to->by_valid) &&
+ (to->by[i].trigger & events))
+ {
+ /*
+ * We have the BY task on the right hand side so we
+ * match with id's first then labels if the id's are
+ * not set.
+ */
+ if (rtems_capture_match_name_id (to->by[i].name, to->by[i].id,
+ by->name, by->id))
return 1;
+ }
+
+ valid_mask >>= 1;
+ valid_remainder >>= 1;
}
+
return 0;
}
/*
- * rtems_capture_match_name_id
+ * rtems_capture_refcount_up
*
* DESCRIPTION:
*
- * This function matches a name and/or id.
+ * This function raises the reference count.
+ *
*/
-static inline rtems_boolean
-rtems_capture_match_name_id (rtems_name lhs_name,
- rtems_id lhs_id,
- rtems_name rhs_name,
- rtems_id rhs_id)
+static inline void
+rtems_capture_refcount_up (rtems_capture_task_t* task)
{
- /*
- * 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))
- {
- if (rtems_capture_match_names (lhs_name, rhs_name))
- return 1;
- }
- return 0;
+ task->refcount++;
+}
+
+/*
+ * rtems_capture_refcount_down
+ *
+ * DESCRIPTION:
+ *
+ * This function lowers the reference count and if the count
+ * reaches 0 the task control block is returned to the heap.
+ *
+ */
+static inline void
+rtems_capture_refcount_down (rtems_capture_task_t* task)
+{
+ if (task->refcount)
+ task->refcount--;
}
/*
@@ -212,8 +295,8 @@ rtems_capture_init_stack_usage (rtems_capture_task_t* task)
{
if (task->tcb)
{
- uint32_t * s;
- uint32_t i;
+ uint32_t* s;
+ uint32_t i;
task->stack_size = task->tcb->Start.Initial_stack.size;
task->stack_clean = task->stack_size;
@@ -274,12 +357,14 @@ rtems_capture_create_control (rtems_name name, rtems_id id)
return NULL;
}
- control->name = name;
- control->id = id;
- control->flags = 0;
+ control->name = name;
+ control->id = id;
+ control->flags = 0;
+ control->to_triggers = 0;
+ control->from_triggers = 0;
+ control->by_valid = 0;
- memset (control->from, 0, sizeof (control->from));
- memset (control->from_id, 0, sizeof (control->from_id));
+ memset (control->by, 0, sizeof (control->by));
rtems_interrupt_disable (level);
@@ -314,7 +399,8 @@ rtems_capture_create_capture_task (rtems_tcb* new_task)
rtems_interrupt_level level;
rtems_capture_task_t* task;
rtems_capture_control_t* control;
-
+ rtems_name name;
+
task = _Workspace_Allocate (sizeof (rtems_capture_task_t));
if (task == NULL)
@@ -323,11 +409,23 @@ rtems_capture_create_capture_task (rtems_tcb* new_task)
return NULL;
}
- rtems_capture_dup_name (&task->name, ((rtems_name) new_task->Object.name));
-
+ /*
+ * Check the type of name the object has.
+ */
+ if (_Objects_Get_API (new_task->Object.id) == OBJECTS_CLASSIC_API)
+ name = (rtems_name) new_task->Object.name;
+ else
+ name = rtems_build_name (((char*) new_task->Object.name)[0],
+ ((char*) new_task->Object.name)[1],
+ ((char*) new_task->Object.name)[2],
+ ((char*) new_task->Object.name)[3]);
+
+ rtems_capture_dup_name (&task->name, name);
+
task->id = new_task->Object.id;
task->flags = 0;
task->in = 0;
+ task->refcount = 0;
task->out = 0;
task->tcb = new_task;
task->ticks = 0;
@@ -368,6 +466,45 @@ rtems_capture_create_capture_task (rtems_tcb* new_task)
}
/*
+ * rtems_capture_destroy_capture_task
+ *
+ * DESCRIPTION:
+ *
+ * This function destroy the task structure if the reference count
+ * is 0 and the tcb has been cleared signalling the task has been
+ * deleted.
+ *
+ */
+static inline void
+rtems_capture_destroy_capture_task (rtems_capture_task_t* task)
+{
+ if (task)
+ {
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable (level);
+
+ if (task->tcb || task->refcount)
+ task = 0;
+
+ if (task)
+ {
+ if (task->forw)
+ task->forw->back = task->back;
+ if (task->back)
+ task->back->forw = task->forw;
+ else
+ capture_tasks = task->forw;
+ }
+
+ rtems_interrupt_enable (level);
+
+ if (task)
+ _Workspace_Free (task);
+ }
+}
+
+/*
* rtems_capture_record
*
* DESCRIPTION:
@@ -377,13 +514,16 @@ rtems_capture_create_capture_task (rtems_tcb* new_task)
*/
static inline void
rtems_capture_record (rtems_capture_task_t* task,
- uint32_t events)
+ uint32_t events)
{
/*
* Check the watch state if we have a task control, and
* the task's real priority is lower or equal to the ceiling.
*/
- if (task)
+ if (task &&
+ ((capture_flags &
+ (RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_ONLY_MONITOR)) ==
+ RTEMS_CAPTURE_TRIGGERED))
{
rtems_capture_control_t* control;
@@ -422,6 +562,8 @@ rtems_capture_record (rtems_capture_task_t* task,
capture_in = capture_records;
else
capture_in++;
+
+ rtems_capture_refcount_up (task);
}
else
capture_flags |= RTEMS_CAPTURE_OVERFLOW;
@@ -431,6 +573,79 @@ rtems_capture_record (rtems_capture_task_t* task,
}
/*
+ * rtems_capture_trigger
+ *
+ * DESCRIPTION:
+ *
+ * See if we have triggered and if not see if this event is a
+ * cause of a trigger.
+ */
+rtems_boolean
+rtems_capture_trigger (rtems_capture_task_t* ft,
+ rtems_capture_task_t* tt,
+ uint32_t events)
+{
+ /*
+ * If we have not triggered then see if this is a trigger condition.
+ */
+ if (!(capture_flags & RTEMS_CAPTURE_TRIGGERED))
+ {
+ rtems_capture_control_t* fc = NULL;
+ rtems_capture_control_t* tc = NULL;
+ uint32_t from_events = 0;
+ uint32_t to_events = 0;
+ uint32_t from_to_events = 0;
+
+ if (ft)
+ {
+ fc = ft->control;
+ if (fc)
+ from_events = fc->from_triggers & events;
+ }
+
+ if (tt)
+ {
+ tc = tt->control;
+ if (tc)
+ {
+ to_events = tc->to_triggers & events;
+ if (ft && tc->by_valid)
+ from_to_events = tc->by_triggers & events;
+ }
+ }
+
+ /*
+ * Check if we have any from or to events. These are the
+ * from any or to any type triggers. All from/to triggers are
+ * listed in the to's control with the from in the from list.
+ *
+ * The masking above means any flag set is a trigger.
+ */
+ if (from_events || to_events)
+ {
+ capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+ return 1;
+ }
+
+ /*
+ * Check the from->to events.
+ */
+ if (from_to_events)
+ {
+ if (rtems_capture_by_in_to (events, ft, tc))
+ {
+ capture_flags |= RTEMS_CAPTURE_TRIGGERED;
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
* rtems_capture_create_task
*
* DESCRIPTION:
@@ -448,7 +663,7 @@ rtems_capture_create_task (rtems_tcb* current_task,
ct = current_task->extensions[capture_extension_index];
/*
- * The task ponters may not be known as the task may have
+ * The task pointers may not be known as the task may have
* been created before the capture engine was open. Add them.
*/
@@ -460,11 +675,11 @@ rtems_capture_create_task (rtems_tcb* current_task,
*/
nt = rtems_capture_create_capture_task (new_task);
- /*
- * If we are logging then record this fact.
- */
- rtems_capture_record (ct, RTEMS_CAPTURE_CREATED_BY_EVENT);
- rtems_capture_record (nt, RTEMS_CAPTURE_CREATED_EVENT);
+ if (rtems_capture_trigger (ct, nt, RTEMS_CAPTURE_CREATE))
+ {
+ rtems_capture_record (ct, RTEMS_CAPTURE_CREATED_BY_EVENT);
+ rtems_capture_record (nt, RTEMS_CAPTURE_CREATED_EVENT);
+ }
return 1 == 1;
}
@@ -492,7 +707,7 @@ rtems_capture_start_task (rtems_tcb* current_task,
st = started_task->extensions[capture_extension_index];
/*
- * The task ponters may not be known as the task may have
+ * The task pointers may not be known as the task may have
* been created before the capture engine was open. Add them.
*/
@@ -501,9 +716,12 @@ rtems_capture_start_task (rtems_tcb* current_task,
if (st == NULL)
st = rtems_capture_create_capture_task (started_task);
-
- rtems_capture_record (ct, RTEMS_CAPTURE_STARTED_BY_EVENT);
- rtems_capture_record (st, RTEMS_CAPTURE_STARTED_EVENT);
+
+ if (rtems_capture_trigger (ct, st, RTEMS_CAPTURE_START))
+ {
+ rtems_capture_record (ct, RTEMS_CAPTURE_STARTED_BY_EVENT);
+ rtems_capture_record (st, RTEMS_CAPTURE_STARTED_EVENT);
+ }
rtems_capture_init_stack_usage (st);
}
@@ -531,7 +749,7 @@ rtems_capture_restart_task (rtems_tcb* current_task,
rt = restarted_task->extensions[capture_extension_index];
/*
- * The task ponters may not be known as the task may have
+ * The task pointers may not be known as the task may have
* been created before the capture engine was open. Add them.
*/
@@ -541,8 +759,11 @@ rtems_capture_restart_task (rtems_tcb* current_task,
if (rt == NULL)
rt = rtems_capture_create_capture_task (restarted_task);
- rtems_capture_record (ct, RTEMS_CAPTURE_RESTARTED_BY_EVENT);
- rtems_capture_record (rt, RTEMS_CAPTURE_RESTARTED_EVENT);
+ if (rtems_capture_trigger (ct, rt, RTEMS_CAPTURE_RESTART))
+ {
+ rtems_capture_record (ct, RTEMS_CAPTURE_RESTARTED_BY_EVENT);
+ rtems_capture_record (rt, RTEMS_CAPTURE_RESTARTED_EVENT);
+ }
rtems_capture_task_stack_usage (rt);
rtems_capture_init_stack_usage (rt);
@@ -568,7 +789,7 @@ rtems_capture_delete_task (rtems_tcb* current_task,
rtems_capture_task_t* dt;
/*
- * The task ponters may not be known as the task may have
+ * The task pointers may not be known as the task may have
* been created before the capture engine was open. Add them.
*/
@@ -581,28 +802,21 @@ rtems_capture_delete_task (rtems_tcb* current_task,
if (dt == NULL)
dt = rtems_capture_create_capture_task (deleted_task);
- rtems_capture_record (ct, RTEMS_CAPTURE_DELETED_BY_EVENT);
- rtems_capture_record (dt, RTEMS_CAPTURE_DELETED_EVENT);
-
+ if (rtems_capture_trigger (ct, dt, RTEMS_CAPTURE_DELETE))
+ {
+ rtems_capture_record (ct, RTEMS_CAPTURE_DELETED_BY_EVENT);
+ rtems_capture_record (dt, RTEMS_CAPTURE_DELETED_EVENT);
+ }
+
rtems_capture_task_stack_usage (dt);
/*
- * This task's tcb will be invalid.
+ * This task's tcb will be invalid. This signals the
+ * task has been deleted.
*/
dt->tcb = 0;
- /*
- * Unlink
- */
- if (rtems_capture_free_info_on_task_delete) {
- if (dt->forw)
- dt->forw->back = dt->back;
- if (dt->back)
- dt->back->forw = dt->forw;
- else
- capture_tasks = dt->forw;
- _Workspace_Free (dt);
- }
+ rtems_capture_destroy_capture_task (dt);
}
/*
@@ -625,14 +839,15 @@ rtems_capture_begin_task (rtems_tcb* begin_task)
bt = begin_task->extensions[capture_extension_index];
/*
- * The task ponters may not be known as the task may have
+ * The task pointers may not be known as the task may have
* been created before the capture engine was open. Add them.
*/
if (bt == NULL)
bt = rtems_capture_create_capture_task (begin_task);
- rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT);
+ if (rtems_capture_trigger (NULL, bt, RTEMS_CAPTURE_BEGIN))
+ rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT);
}
/*
@@ -656,14 +871,15 @@ rtems_capture_exitted_task (rtems_tcb* exitted_task)
et = exitted_task->extensions[capture_extension_index];
/*
- * The task ponters may not be known as the task may have
+ * The task pointers may not be known as the task may have
* been created before the capture engine was open. Add them.
*/
if (et == NULL)
et = rtems_capture_create_capture_task (exitted_task);
- rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT);
+ if (rtems_capture_trigger (NULL, et, RTEMS_CAPTURE_EXITTED))
+ rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT);
rtems_capture_task_stack_usage (et);
}
@@ -686,13 +902,13 @@ rtems_capture_switch_task (rtems_tcb* current_task,
*/
if (capture_flags & RTEMS_CAPTURE_ON)
{
- uint32_t ticks;
- uint32_t tick_offset;
+ uint32_t ticks;
+ uint32_t tick_offset;
/*
* Get the cpature task control block so we can update the
- * reference anbd perform any watch or trigger functions.
- * The task ponters may not be known as the task may have
+ * reference and perform any watch or trigger functions.
+ * The task pointers may not be known as the task may have
* been created before the capture engine was open. Add them.
*/
rtems_capture_task_t* ct;
@@ -760,57 +976,8 @@ rtems_capture_switch_task (rtems_tcb* current_task,
}
}
- /*
- * If we have not triggered then see if this is a trigger condition.
- */
- if (!(capture_flags & RTEMS_CAPTURE_TRIGGERED))
- {
- rtems_capture_control_t* cc = NULL;
- rtems_capture_control_t* hc = NULL;
-
- if (ct)
- {
- cc = ct->control;
-
- /*
- * Check the current task for a TO_ANY trigger.
- */
- if (cc && (cc->flags & RTEMS_CAPTURE_TO_ANY))
- {
- capture_flags |= RTEMS_CAPTURE_TRIGGERED;
- goto triggered;
- }
- }
-
- if (ht)
- {
- hc = ht->control;
-
- /*
- * Check the next task for a FROM_ANY.
- */
- if (hc && (hc->flags & RTEMS_CAPTURE_FROM_ANY))
- {
- capture_flags |= RTEMS_CAPTURE_TRIGGERED;
- goto triggered;
- }
- }
-
- /*
- * Check is the trigger is from the current task
- * to the next task.
- */
- if (cc && hc && (hc->flags & RTEMS_CAPTURE_FROM_TO))
- if (rtems_capture_name_in_group (cc->name, hc->from))
- {
- capture_flags |= RTEMS_CAPTURE_TRIGGERED;
- goto triggered;
- }
- }
- else
+ if (rtems_capture_trigger (ct, ht, RTEMS_CAPTURE_SWITCH))
{
-triggered:
-
rtems_capture_record (ct, RTEMS_CAPTURE_SWITCHED_OUT_EVENT);
rtems_capture_record (ht, RTEMS_CAPTURE_SWITCHED_IN_EVENT);
}
@@ -921,7 +1088,7 @@ rtems_capture_close ()
return RTEMS_SUCCESSFUL;
}
- capture_flags &= ~RTEMS_CAPTURE_ON;
+ capture_flags &= ~(RTEMS_CAPTURE_ON | RTEMS_CAPTURE_ONLY_MONITOR);
records = capture_records;
capture_records = NULL;
@@ -1000,6 +1167,38 @@ rtems_capture_control (rtems_boolean enable)
}
/*
+ * rtems_capture_monitor
+ *
+ * DESCRIPTION:
+ *
+ * This function enable the monitor mode. When in the monitor mode
+ * the tasks are monitored but no data is saved. This can be used
+ * to profile the load on a system.
+ */
+rtems_status_code
+rtems_capture_monitor (rtems_boolean enable)
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable (level);
+
+ if (!capture_records)
+ {
+ rtems_interrupt_enable (level);
+ return RTEMS_UNSATISFIED;
+ }
+
+ if (enable)
+ capture_flags |= RTEMS_CAPTURE_ONLY_MONITOR;
+ else
+ capture_flags &= ~RTEMS_CAPTURE_ONLY_MONITOR;
+
+ rtems_interrupt_enable (level);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+/*
* rtems_capture_flush
*
* DESCRIPTION:
@@ -1016,18 +1215,31 @@ rtems_capture_flush (rtems_boolean prime)
rtems_interrupt_disable (level);
for (task = capture_tasks; task != NULL; task = task->forw)
+ {
task->flags &= ~RTEMS_CAPTURE_TRACED;
+ task->refcount = 0;
+ }
if (prime)
capture_flags &= ~(RTEMS_CAPTURE_TRIGGERED | RTEMS_CAPTURE_OVERFLOW);
else
capture_flags &= ~RTEMS_CAPTURE_OVERFLOW;
- capture_in = capture_records;
- capture_out = 0;
-
+ capture_count = 0;
+ capture_in = capture_records;
+ capture_out = 0;
+
rtems_interrupt_enable (level);
+ task = capture_tasks;
+
+ while (task)
+ {
+ rtems_capture_task_t* check = task;
+ task = task->forw;
+ rtems_capture_destroy_capture_task (check);
+ }
+
return RTEMS_SUCCESSFUL;
}
@@ -1088,7 +1300,7 @@ rtems_capture_watch_del (rtems_name name, rtems_id id)
for (prev_control = &capture_controls, control = capture_controls;
control != NULL; )
{
- if (rtems_capture_match_name_id (name, id, control->name, control->id))
+ if (rtems_capture_match_name_id (control->name, control->id, name, id))
{
rtems_interrupt_disable (level);
@@ -1110,7 +1322,7 @@ rtems_capture_watch_del (rtems_name name, rtems_id id)
{
prev_control = &control->next;
control = control->next;
- }
+ }
}
if (found)
@@ -1140,7 +1352,7 @@ rtems_capture_watch_ctrl (rtems_name name, rtems_id id, rtems_boolean enable)
*/
for (control = capture_controls; control != NULL; control = control->next)
{
- if (rtems_capture_match_name_id (name, id, control->name, control->id))
+ if (rtems_capture_match_name_id (control->name, control->id, name, id))
{
rtems_interrupt_disable (level);
@@ -1265,18 +1477,47 @@ rtems_capture_watch_get_floor ()
}
/*
- * rtems_capture_set_trigger
+ * rtems_capture_map_trigger
*
* DESCRIPTION:
*
- * This function sets an edge trigger. Left is the left side of
- * the edge and right is right side of the edge. The trigger type
- * can be -
+ * Map the trigger to a bit mask.
*
- * FROM_ANY : a switch from any task to the right side of the edge.
- * TO_ANY : a switch from the left side of the edge to any task.
- * FROM_TO : a switch from the left side of the edge to the right
- * side of the edge.
+ */
+uint32_t
+rtems_capture_map_trigger (rtems_capture_trigger_t trigger)
+{
+ /*
+ * Transform the mode and trigger to a bit map.
+ */
+ switch (trigger)
+ {
+ case rtems_capture_switch:
+ return RTEMS_CAPTURE_SWITCH;
+ case rtems_capture_create:
+ return RTEMS_CAPTURE_CREATE;
+ case rtems_capture_start:
+ return RTEMS_CAPTURE_START;
+ case rtems_capture_restart:
+ return RTEMS_CAPTURE_RESTART;
+ case rtems_capture_delete:
+ return RTEMS_CAPTURE_DELETE;
+ case rtems_capture_begin:
+ return RTEMS_CAPTURE_BEGIN;
+ case rtems_capture_exitted:
+ return RTEMS_CAPTURE_EXITTED;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
+ * rtems_capture_set_trigger
+ *
+ * DESCRIPTION:
+ *
+ * This function sets a trigger.
*
* This set trigger routine will create a capture control for the
* target task. The task list is searched and any existing tasks
@@ -1287,48 +1528,149 @@ rtems_capture_watch_get_floor ()
* linked to single control.
*/
rtems_status_code
-rtems_capture_set_trigger (rtems_name from,
- rtems_id from_id,
- rtems_name to,
- rtems_id to_id,
- rtems_capture_trigger_t trigger)
+rtems_capture_set_trigger (rtems_name from_name,
+ rtems_id from_id,
+ rtems_name to_name,
+ rtems_id to_id,
+ rtems_capture_trigger_mode_t mode,
+ rtems_capture_trigger_t trigger)
{
rtems_capture_control_t* control;
- int i;
+ uint32_t flags;
+
+ flags = rtems_capture_map_trigger (trigger);
/*
- * Find the capture control blocks for the from and to
- * tasks.
+ * The mode sets the opposite type of trigger. For example
+ * FROM ANY means trigger when the event happens TO this
+ * task. TO ANY means FROM this task.
*/
- if (trigger == rtems_capture_to_any)
+
+ if (mode == rtems_capture_to_any)
{
- control = rtems_capture_create_control (from, from_id);
+ control = rtems_capture_create_control (from_name, from_id);
if (control == NULL)
return RTEMS_NO_MEMORY;
- control->flags |= RTEMS_CAPTURE_TO_ANY;
+ control->from_triggers |= flags & RTEMS_CAPTURE_FROM_TRIGS;
}
-
- if ((trigger == rtems_capture_from_to) ||
- (trigger == rtems_capture_from_any))
+ else
{
- control = rtems_capture_create_control (to, to_id);
+ control = rtems_capture_create_control (to_name, to_id);
if (control == NULL)
return RTEMS_NO_MEMORY;
+ if (mode == rtems_capture_from_any)
+ control->to_triggers |= flags;
+ else
+ {
+ rtems_boolean done = 0;
+ int i;
+
+ control->by_triggers |= flags;
+
+ for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)
+ {
+ if (rtems_capture_control_by_valid (control, i) &&
+ ((control->by[i].name == from_name) ||
+ (from_id && (control->by[i].id == from_id))))
+ {
+ control->by[i].trigger |= flags;
+ done = 1;
+ break;
+ }
+ }
+
+ if (!done)
+ {
+ for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)
+ {
+ if (!rtems_capture_control_by_valid (control, i))
+ {
+ control->by_valid |= RTEMS_CAPTURE_CONTROL_FROM_MASK (i);
+ control->by[i].name = from_name;
+ control->by[i].id = from_id;
+ control->by[i].trigger = flags;
+ done = 1;
+ break;
+ }
+ }
+ }
+
+ if (!done)
+ return RTEMS_TOO_MANY;
+ }
+ }
+ return RTEMS_SUCCESSFUL;
+}
- if (trigger == rtems_capture_from_any)
- control->flags |= RTEMS_CAPTURE_FROM_ANY;
+/*
+ * rtems_capture_clear_trigger
+ *
+ * DESCRIPTION:
+ *
+ * This function clear a trigger.
+ */
+rtems_status_code
+rtems_capture_clear_trigger (rtems_name from_name,
+ rtems_id from_id,
+ rtems_name to_name,
+ rtems_id to_id,
+ rtems_capture_trigger_mode_t mode,
+ rtems_capture_trigger_t trigger)
+{
+ rtems_capture_control_t* control;
+ uint32_t flags;
+
+ flags = rtems_capture_map_trigger (trigger);
+
+ if (mode == rtems_capture_to_any)
+ {
+ control = rtems_capture_find_control (from_name, from_id);
+ if (control == NULL)
+ {
+ if (from_id)
+ return RTEMS_INVALID_ID;
+ return RTEMS_INVALID_NAME;
+ }
+ control->from_triggers &= ~flags;
+ }
+ else
+ {
+ control = rtems_capture_find_control (to_name, to_id);
+ if (control == NULL)
+ {
+ if (to_id)
+ return RTEMS_INVALID_ID;
+ return RTEMS_INVALID_NAME;
+ }
+ if (mode == rtems_capture_from_any)
+ control->to_triggers &= ~flags;
else
{
- control->flags |= RTEMS_CAPTURE_FROM_TO;
+ rtems_boolean done = 0;
+ int i;
+
+ control->by_triggers &= ~flags;
+
for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)
{
- if (control->from[i] == 0)
+ if (rtems_capture_control_by_valid (control, i) &&
+ ((control->by[i].name == from_name) ||
+ (control->by[i].id == from_id)))
{
- control->from[i] = from;
- control->from_id[i] = from_id;
+ control->by[i].trigger &= ~trigger;
+ if (control->by[i].trigger == 0)
+ control->by_valid &= ~RTEMS_CAPTURE_CONTROL_FROM_MASK (i);
+ done = 1;
break;
}
}
+
+ if (!done)
+ {
+ if (from_id)
+ return RTEMS_INVALID_ID;
+ return RTEMS_INVALID_NAME;
+ }
}
}
return RTEMS_SUCCESSFUL;
@@ -1366,14 +1708,14 @@ rtems_capture_set_trigger (rtems_name from,
*
*/
rtems_status_code
-rtems_capture_read (uint32_t threshold,
- uint32_t timeout,
- uint32_t * read,
+rtems_capture_read (uint32_t threshold,
+ uint32_t timeout,
+ uint32_t* read,
rtems_capture_record_t** recs)
{
rtems_interrupt_level level;
rtems_status_code sc = RTEMS_SUCCESSFUL;
- uint32_t count;
+ uint32_t count;
*read = 0;
*recs = NULL;
@@ -1455,12 +1797,6 @@ rtems_capture_read (uint32_t threshold,
break;
}
- rtems_interrupt_disable (level);
-
- capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
-
- rtems_interrupt_enable (level);
-
return sc;
}
@@ -1473,8 +1809,11 @@ rtems_capture_read (uint32_t threshold,
* to the capture engine. The count must match the number read.
*/
rtems_status_code
-rtems_capture_release (uint32_t count)
+rtems_capture_release (uint32_t count)
{
+ rtems_capture_record_t* rec;
+ uint32_t counted;
+
rtems_interrupt_level level;
rtems_interrupt_disable (level);
@@ -1482,9 +1821,26 @@ rtems_capture_release (uint32_t count)
if (count > capture_count)
count = capture_count;
+ rtems_interrupt_enable (level);
+
+ counted = count;
+
+ rec = &capture_records[capture_out];
+
+ while (counted--)
+ {
+ rtems_capture_refcount_down (rec->task);
+ rtems_capture_destroy_capture_task (rec->task);
+ rec++;
+ }
+
+ rtems_interrupt_disable (level);
+
capture_count -= count;
- capture_out = (capture_count + count) % capture_size;
+ capture_out = (capture_out + count) % capture_size;
+
+ capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
rtems_interrupt_enable (level);
@@ -1548,8 +1904,8 @@ rtems_capture_task_stack_usage (rtems_capture_task_t* task)
{
if (task->tcb)
{
- uint32_t * st;
- uint32_t * s;
+ uint32_t* st;
+ uint32_t* s;
/*
* @todo: Assumes all stacks move the same way.
@@ -1565,7 +1921,7 @@ rtems_capture_task_stack_usage (rtems_capture_task_t* task)
}
task->stack_clean =
- s - (uint32_t *) task->tcb->Start.Initial_stack.area;
+ s - (uint32_t*) task->tcb->Start.Initial_stack.area;
}
return task->stack_clean;
diff --git a/cpukit/libmisc/capture/capture.h b/cpukit/libmisc/capture/capture.h
index 6db1ee89f3..11b9835e93 100644
--- a/cpukit/libmisc/capture/capture.h
+++ b/cpukit/libmisc/capture/capture.h
@@ -22,7 +22,6 @@
------------------------------------------------------------------------
RTEMS Performance Monitoring and Measurement Framework.
-
This is the Capture Engine component.
*/
@@ -42,44 +41,100 @@ extern "C" {
#define RTEMS_CAPTURE_TRIGGER_TASKS (32)
/**
+ * rtems_capture_from_t
+ *
+ * DESCRIPTION:
+ *
+ * A from capture is a task id and a mask for the type of
+ * from trigger we are interested in. The mask uses the same
+ * bit maps as the flags field in the control structure. There
+ * will only be a from type trigger if the flags in the control
+ * structure has the specific *_BY bit set.
+ */
+typedef struct rtems_capture_from_s
+{
+ rtems_name name;
+ rtems_id id;
+ uint32_t trigger;
+} rtems_capture_from_t;
+
+/**
* rtems_capture_control_t
*
* DESCRIPTION:
*
* RTEMS control holds the trigger and watch configuration for a group of
- * tasks with the same name.
+ * tasks with the same name. The flags hold global control flags.
+ *
+ * The to_triggers fields holds triggers TO this task. The from_triggers holds
+ * triggers from this task. The by_triggers is an OR or triggers which are
+ * caused BY the task listed TO this task. The by_valid flag which entries
+ * in by are valid.
*/
typedef struct rtems_capture_control_s
{
rtems_name name;
rtems_id id;
- uint32_t flags;
- rtems_name from[RTEMS_CAPTURE_TRIGGER_TASKS];
- rtems_id from_id[RTEMS_CAPTURE_TRIGGER_TASKS];
+ uint32_t flags;
+ uint32_t to_triggers;
+ uint32_t from_triggers;
+ uint32_t by_triggers;
+ uint32_t by_valid;
+ rtems_capture_from_t by[RTEMS_CAPTURE_TRIGGER_TASKS];
struct rtems_capture_control_s* next;
} rtems_capture_control_t;
/**
+ * The from_valid mask.
+ */
+#define RTEMS_CAPTURE_CONTROL_FROM_MASK(_s) \
+ (1 << (RTEMS_CAPTURE_TRIGGER_TASKS - ((_s) + 1)))
+
+/**
* Control flags.
*/
#define RTEMS_CAPTURE_WATCH (1 << 0)
-#define RTEMS_CAPTURE_FROM_ANY (1 << 1)
-#define RTEMS_CAPTURE_TO_ANY (1 << 2)
-#define RTEMS_CAPTURE_FROM_TO (1 << 3)
/**
+ * Control triggers.
+ */
+#define RTEMS_CAPTURE_SWITCH (1 << 0)
+#define RTEMS_CAPTURE_CREATE (1 << 1)
+#define RTEMS_CAPTURE_START (1 << 2)
+#define RTEMS_CAPTURE_RESTART (1 << 3)
+#define RTEMS_CAPTURE_DELETE (1 << 4)
+#define RTEMS_CAPTURE_BEGIN (1 << 5)
+#define RTEMS_CAPTURE_EXITTED (1 << 6)
+
+#define RTEMS_CAPTURE_FROM_TRIGS (RTEMS_CAPTURE_SWITCH | \
+ RTEMS_CAPTURE_CREATE | \
+ RTEMS_CAPTURE_START | \
+ RTEMS_CAPTURE_RESTART | \
+ RTEMS_CAPTURE_DELETE)
+
+#define RTEMS_CAPTURE_TO_TRIGS (RTEMS_CAPTURE_SWITCH | \
+ RTEMS_CAPTURE_CREATE | \
+ RTEMS_CAPTURE_START | \
+ RTEMS_CAPTURE_RESTART | \
+ RTEMS_CAPTURE_DELETE | \
+ RTEMS_CAPTURE_BEGIN | \
+ RTEMS_CAPTURE_EXITTED)
+
+/**
* rtems_capture_control_t
*
* DESCRIPTION:
*
* RTEMS capture control provdes the information about a task, along
* with its trigger state. The control is referenced by each
- * capture record. This is* information neeed by the decoder. The
+ * capture record. This is information neeed by the decoder. The
* capture record cannot assume the task will exist when the record is
* dumped via the target interface so task info needed for tracing is
- * copied and held here.
+ * copied and held here. Once the references in the trace buffer
+ * have been removed and the task is deleted this structure is
+ * released back to the heap.
*
- * The inline heper functions provide more details about the info
+ * The inline helper functions provide more details about the info
* contained in this structure.
*
* Note, the tracer code exploits the fact an rtems_name is a
@@ -89,19 +144,20 @@ typedef struct rtems_capture_task_s
{
rtems_name name;
rtems_id id;
- uint32_t flags;
+ uint32_t flags;
+ uint32_t refcount;
rtems_tcb* tcb;
- uint32_t in;
- uint32_t out;
+ uint32_t in;
+ uint32_t out;
rtems_task_priority start_priority;
- uint32_t stack_size;
- uint32_t stack_clean;
- uint32_t ticks;
- uint32_t tick_offset;
- uint32_t ticks_in;
- uint32_t tick_offset_in;
- uint32_t last_ticks;
- uint32_t last_tick_offset;
+ uint32_t stack_size;
+ uint32_t stack_clean;
+ uint32_t ticks;
+ uint32_t tick_offset;
+ uint32_t ticks_in;
+ uint32_t tick_offset_in;
+ uint32_t last_ticks;
+ uint32_t last_tick_offset;
rtems_capture_control_t* control;
struct rtems_capture_task_s* forw;
struct rtems_capture_task_s* back;
@@ -124,46 +180,64 @@ typedef struct rtems_capture_task_s
typedef struct rtems_capture_record_s
{
rtems_capture_task_t* task;
- uint32_t events;
- uint32_t ticks;
- uint32_t tick_offset;
+ uint32_t events;
+ uint32_t ticks;
+ uint32_t tick_offset;
} rtems_capture_record_t;
/**
* The capture record event flags.
*/
-#define RTEMS_CAPTURE_REAL_PRI_EVENT_MASK UINT32_C(0x000000ff)
-#define RTEMS_CAPTURE_CURR_PRI_EVENT_MASK UINT32_C(0x0000ff00)
+#define RTEMS_CAPTURE_REAL_PRI_EVENT_MASK UINT32_C (0x000000ff)
+#define RTEMS_CAPTURE_CURR_PRI_EVENT_MASK UINT32_C (0x0000ff00)
#define RTEMS_CAPTURE_REAL_PRIORITY_EVENT (0)
#define RTEMS_CAPTURE_CURR_PRIORITY_EVENT (8)
#define RTEMS_CAPTURE_EVENT_START (16)
-#define RTEMS_CAPTURE_CREATED_BY_EVENT UINT32_C(0x00010000)
-#define RTEMS_CAPTURE_CREATED_EVENT UINT32_C(0x00020000)
-#define RTEMS_CAPTURE_STARTED_BY_EVENT UINT32_C(0x00040000)
-#define RTEMS_CAPTURE_STARTED_EVENT UINT32_C(0x00080000)
-#define RTEMS_CAPTURE_RESTARTED_BY_EVENT UINT32_C(0x00100000)
-#define RTEMS_CAPTURE_RESTARTED_EVENT UINT32_C(0x00200000)
-#define RTEMS_CAPTURE_DELETED_BY_EVENT UINT32_C(0x00400000)
-#define RTEMS_CAPTURE_DELETED_EVENT UINT32_C(0x00800000)
-#define RTEMS_CAPTURE_BEGIN_EVENT UINT32_C(0x01000000)
-#define RTEMS_CAPTURE_EXITTED_EVENT UINT32_C(0x02000000)
-#define RTEMS_CAPTURE_SWITCHED_OUT_EVENT UINT32_C(0x04000000)
-#define RTEMS_CAPTURE_SWITCHED_IN_EVENT UINT32_C(0x08000000)
-#define RTEMS_CAPTURE_TIMESTAMP UINT32_C(0x10000000)
+#define RTEMS_CAPTURE_CREATED_BY_EVENT UINT32_C (0x00010000)
+#define RTEMS_CAPTURE_CREATED_EVENT UINT32_C (0x00020000)
+#define RTEMS_CAPTURE_STARTED_BY_EVENT UINT32_C (0x00040000)
+#define RTEMS_CAPTURE_STARTED_EVENT UINT32_C (0x00080000)
+#define RTEMS_CAPTURE_RESTARTED_BY_EVENT UINT32_C (0x00100000)
+#define RTEMS_CAPTURE_RESTARTED_EVENT UINT32_C (0x00200000)
+#define RTEMS_CAPTURE_DELETED_BY_EVENT UINT32_C (0x00400000)
+#define RTEMS_CAPTURE_DELETED_EVENT UINT32_C (0x00800000)
+#define RTEMS_CAPTURE_BEGIN_EVENT UINT32_C (0x01000000)
+#define RTEMS_CAPTURE_EXITTED_EVENT UINT32_C (0x02000000)
+#define RTEMS_CAPTURE_SWITCHED_OUT_EVENT UINT32_C (0x04000000)
+#define RTEMS_CAPTURE_SWITCHED_IN_EVENT UINT32_C (0x08000000)
+#define RTEMS_CAPTURE_TIMESTAMP UINT32_C (0x10000000)
#define RTEMS_CAPTURE_EVENT_END (28)
/**
- * rtems_capture_trigger_t
+ * rtems_capture_trigger_mode_t
*
* DESCRIPTION:
*
- * The types of triggers that exist. FIXME: add more here.
+ * The types of trigger modes that exist.
*/
-typedef enum rtems_capture_trigger_t
+typedef enum rtems_capture_trigger_mode_e
{
rtems_capture_to_any,
rtems_capture_from_any,
rtems_capture_from_to
+} rtems_capture_trigger_mode_t;
+
+/**
+ * rtems_capture_trigger_t
+ *
+ * DESCRIPTION:
+ *
+ * The types of triggers that exist.
+ */
+typedef enum rtems_capture_trigger_e
+{
+ rtems_capture_switch,
+ rtems_capture_create,
+ rtems_capture_start,
+ rtems_capture_restart,
+ rtems_capture_delete,
+ rtems_capture_begin,
+ rtems_capture_exitted
} rtems_capture_trigger_t;
/**
@@ -177,32 +251,23 @@ typedef enum rtems_capture_trigger_t
*/
typedef void (*rtems_capture_timestamp)
- (uint32_t * ticks, uint32_t * micro);
+ (uint32_t* ticks, uint32_t* micro);
/**
* rtems_capture_open
*
* DESCRIPTION:
*
- * This function initialises the realtime trace manager allocating the capture
- * buffer. It is assumed we have a working heap at stage of initialisation.
+ * This function initialises the realtime trace manager allocating the
+ * capture buffer. It is assumed we have a working heap at stage of
+ * initialisation.
*
*/
rtems_status_code
-rtems_capture_open (uint32_t size,
+rtems_capture_open (uint32_t size,
rtems_capture_timestamp timestamp);
/**
- * rtems_capture_free_info_on_task_delete
- *
- * DESCRIPTION:
- *
- * If non-zero task informaion if freed when a task is deleted.
- *
- */
-extern int rtems_capture_free_info_on_task_delete;
-
-/**
* rtems_capture_close
*
* DESCRIPTION:
@@ -223,6 +288,18 @@ rtems_capture_close ();
rtems_status_code
rtems_capture_control (rtems_boolean enable);
+/**
+ * rtems_capture_monitor
+ *
+ * DESCRIPTION:
+ *
+ * This function enable the monitor mode. When in the monitor mode
+ * the tasks are monitored but no data is saved. This can be used
+ * to profile the load on a system.
+ */
+rtems_status_code
+rtems_capture_monitor (rtems_boolean enable);
+
/*
* rtems_capture_flush
*
@@ -268,16 +345,18 @@ rtems_capture_watch_del (rtems_name name, rtems_id id);
* disabled.
*/
rtems_status_code
-rtems_capture_watch_ctrl (rtems_name name, rtems_id id, rtems_boolean enable);
+rtems_capture_watch_ctrl (rtems_name name,
+ rtems_id id,
+ rtems_boolean enable);
/**
* rtems_capture_watch_global
*
* DESCRIPTION:
*
- * This function allows control of a global watch. The watch can be enabled or
- * disabled. A global watch configures all tasks below the ceiling and above
- * the floor to be traced.
+ * This function allows control of a global watch. The watch can
+ * be enabled or disabled. A global watch configures all tasks below
+ * the ceiling and above the floor to be traced.
*/
rtems_status_code
rtems_capture_watch_global (rtems_boolean enable);
@@ -343,14 +422,7 @@ rtems_capture_watch_get_floor ();
*
* DESCRIPTION:
*
- * This function sets an edge trigger. Left is the left side of
- * the edge and right is right side of the edge. The trigger type
- * can be -
- *
- * FROM_ANY : a switch from any task to the right side of the edge.
- * TO_ANY : a switch from the left side of the edge to any task.
- * FROM_TO : a switch from the left side of the edge to the right
- * side of the edge.
+ * This function sets a trigger.
*
* This set trigger routine will create a trace control for the
* target task. The task list is searched and any existing tasks
@@ -361,11 +433,29 @@ rtems_capture_watch_get_floor ();
* linked to single control.
*/
rtems_status_code
-rtems_capture_set_trigger (rtems_name from,
- rtems_id from_id,
- rtems_name to,
- rtems_id to_id,
- rtems_capture_trigger_t trigger);
+rtems_capture_set_trigger (rtems_name from_name,
+ rtems_id from_id,
+ rtems_name to_name,
+ rtems_id to_id,
+ rtems_capture_trigger_mode_t mode,
+ rtems_capture_trigger_t trigger);
+
+/**
+ * rtems_capture_clear_trigger
+ *
+ * DESCRIPTION:
+ *
+ * This function clears a trigger.
+ *
+ * This clear trigger routine will not clear a watch.
+ */
+rtems_status_code
+rtems_capture_clear_trigger (rtems_name from_name,
+ rtems_id from_id,
+ rtems_name to_name,
+ rtems_id to_id,
+ rtems_capture_trigger_mode_t mode,
+ rtems_capture_trigger_t trigger);
/**
* rtems_capture_read
@@ -394,14 +484,14 @@ rtems_capture_set_trigger (rtems_name from,
* thrashing occuring for a small number of records, yet allows
* a user configured latiency to be applied for single events.
*
- * The 'timeout' parameter is in micro-seconds. A value of 0 will disable
- * the timeout.
+ * The 'timeout' parameter is in micro-seconds. A value of 0 will
+ * disable the timeout.
*
*/
rtems_status_code
-rtems_capture_read (uint32_t threshold,
- uint32_t timeout,
- uint32_t * read,
+rtems_capture_read (uint32_t threshold,
+ uint32_t timeout,
+ uint32_t* read,
rtems_capture_record_t** recs);
/**
@@ -413,7 +503,7 @@ rtems_capture_read (uint32_t threshold,
* to the capture engine. The count must match the number read.
*/
rtems_status_code
-rtems_capture_release (uint32_t count);
+rtems_capture_release (uint32_t count);
/**
* rtems_capture_tick_time
@@ -825,33 +915,101 @@ rtems_capture_control_flags (rtems_capture_control_t* control)
}
/**
- * rtems_capture_control_from_name
+ * rtems_capture_control_to_triggers
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task control to triggers.
+ */
+static inline uint32_t
+rtems_capture_control_to_triggers (rtems_capture_control_t* control)
+{
+ return control->to_triggers;
+}
+
+/**
+ * rtems_capture_control_from_triggers
*
* DESCRIPTION:
*
- * This function returns the control from task name.
+ * This function returns the task control from triggers.
+ */
+static inline uint32_t
+rtems_capture_control_from_triggers (rtems_capture_control_t* control)
+{
+ return control->from_triggers;
+}
+
+/**
+ * rtems_capture_control_all_by_triggers
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the task control by triggers.
+ */
+static inline uint32_t
+rtems_capture_control_all_by_triggers (rtems_capture_control_t* control)
+{
+ return control->by_triggers;
+}
+
+/**
+ * rtems_capture_control_by_valid
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the control valid BY flags.
+ */
+static inline int
+rtems_capture_control_by_valid (rtems_capture_control_t* control, int slot)
+{
+ return control->by_valid & RTEMS_CAPTURE_CONTROL_FROM_MASK (slot);
+}
+
+/**
+ * rtems_capture_control_by_name
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the control BY task name.
*/
static inline rtems_name
-rtems_capture_control_from_name (rtems_capture_control_t* control, int from)
+rtems_capture_control_by_name (rtems_capture_control_t* control, int by)
{
- if (from < RTEMS_CAPTURE_TRIGGER_TASKS)
- return control->from[from];
- return control->from[0];
+ if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
+ return control->by[by].name;
+ return control->by[0].name;
}
/**
- * rtems_capture_control_from_id
+ * rtems_capture_control_by_id
*
* DESCRIPTION:
*
- * This function returns the control from task id.
+ * This function returns the control BY task id.
*/
static inline rtems_id
-rtems_capture_control_from_id (rtems_capture_control_t* control, int from)
+rtems_capture_control_by_id (rtems_capture_control_t* control, int by)
+{
+ if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
+ return control->by[by].id;
+ return control->by[0].id;
+}
+
+/**
+ * rtems_capture_control_by_triggers
+ *
+ * DESCRIPTION:
+ *
+ * This function returns the control BY task triggers.
+ */
+static inline uint32_t
+rtems_capture_control_by_triggers (rtems_capture_control_t* control,
+ int by)
{
- if (from < RTEMS_CAPTURE_TRIGGER_TASKS)
- return control->from_id[from];
- return control->from_id[0];
+ if (by < RTEMS_CAPTURE_TRIGGER_TASKS)
+ return control->by[by].trigger;
+ return control->by[0].trigger;
}
/**
@@ -866,7 +1024,7 @@ static inline uint32_t
rtems_capture_control_count ()
{
rtems_capture_control_t* control = rtems_capture_get_control_list ();
- uint32_t count = 0;
+ uint32_t count = 0;
while (control)
{