From 133962bf2fccd2d281972142983bd73ba732cbf7 Mon Sep 17 00:00:00 2001 From: Jennifer Averett Date: Tue, 22 Jul 2014 09:40:54 -0500 Subject: capture: Split user extension methods out. --- cpukit/libmisc/capture/capture.c | 428 +++-------------------- cpukit/libmisc/capture/capture_user_extension.c | 435 ++++++++++++++++++++++++ cpukit/libmisc/capture/captureimpl.h | 195 +++++++++++ 3 files changed, 671 insertions(+), 387 deletions(-) create mode 100644 cpukit/libmisc/capture/capture_user_extension.c create mode 100644 cpukit/libmisc/capture/captureimpl.h (limited to 'cpukit/libmisc/capture') diff --git a/cpukit/libmisc/capture/capture.c b/cpukit/libmisc/capture/capture.c index 9ec07b8051..54b289439b 100644 --- a/cpukit/libmisc/capture/capture.c +++ b/cpukit/libmisc/capture/capture.c @@ -29,7 +29,7 @@ #include #include -#include "capture.h" +#include "captureimpl.h" #include #include @@ -57,46 +57,6 @@ #define RTEMS_CAPTURE_RECORD_EVENTS (0) #endif -static bool -rtems_capture_create_task (rtems_tcb* current_task, - rtems_tcb* new_task); - -static void -rtems_capture_start_task (rtems_tcb* current_task, - rtems_tcb* started_task); - -static void -rtems_capture_restart_task (rtems_tcb* current_task, - rtems_tcb* restarted_task); - -static void -rtems_capture_delete_task (rtems_tcb* current_task, - rtems_tcb* deleted_task); - -static void -rtems_capture_switch_task (rtems_tcb* current_task, - rtems_tcb* heir_task); - -static void -rtems_capture_begin_task (rtems_tcb* begin_task); - -static void -rtems_capture_exitted_task (rtems_tcb* exitted_task); - -static void -rtems_capture_terminated_task (rtems_tcb* terminated_task); - -/* - * 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_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) /* * RTEMS Capture Data. @@ -110,7 +70,6 @@ static uint32_t capture_flags; static rtems_capture_task_t* capture_tasks; static rtems_capture_control_t* capture_controls; static int capture_extension_index; -static rtems_id capture_id; static rtems_capture_timestamp capture_timestamp; static rtems_task_priority capture_ceiling; static rtems_task_priority capture_floor; @@ -118,18 +77,6 @@ static rtems_id capture_reader; static rtems_interrupt_lock capture_lock = RTEMS_INTERRUPT_LOCK_INITIALIZER("capture"); -static const rtems_extensions_table capture_extensions = { - .thread_create = rtems_capture_create_task, - .thread_start = rtems_capture_start_task, - .thread_restart = rtems_capture_restart_task, - .thread_delete = rtems_capture_delete_task, - .thread_switch = rtems_capture_switch_task, - .thread_begin = rtems_capture_begin_task, - .thread_exitted = rtems_capture_exitted_task, - .fatal = NULL, - .thread_terminate = rtems_capture_terminated_task -}; - /* * RTEMS Event text. */ @@ -151,11 +98,43 @@ static const char* capture_event_text[] = "TIMESTAMP" }; +void rtems_capture_set_extension_index(int index) +{ + capture_extension_index = index; +} + +int rtems_capture_get_extension_index(void) +{ + return capture_extension_index; +} + +uint32_t rtems_capture_get_flags(void) +{ + return capture_flags; +} + +void rtems_capture_set_flags(uint32_t mask) +{ + capture_flags |= mask; +} + + +rtems_capture_task_t* rtems_capture_find_capture_task( rtems_id ct_id ) +{ + rtems_capture_task_t* ct; + + for (ct = capture_tasks; ct; ct = ct->forw) { + if (ct->id == ct_id) + break; + } + return ct; +} + /* * This function returns the current time. If a handler is provided * by the user get the time from that. */ -static inline void +void rtems_capture_get_time (rtems_capture_time_t* time) { if (capture_timestamp) @@ -290,7 +269,7 @@ rtems_capture_refcount_down (rtems_capture_task_t* task) /* * This function setups a stack so its usage can be monitored. */ -static inline void +void rtems_capture_init_stack_usage (rtems_capture_task_t* task) { if (task->tcb) @@ -378,7 +357,7 @@ rtems_capture_create_control (rtems_name name, rtems_id id) /* * This function create the task control. */ -static inline rtems_capture_task_t* +rtems_capture_task_t* rtems_capture_create_capture_task (rtems_tcb* new_task) { rtems_interrupt_lock_context lock_context; @@ -456,7 +435,7 @@ rtems_capture_create_capture_task (rtems_tcb* new_task) * is 0 and the tcb has been cleared signalling the task has been * deleted. */ -static inline void +void rtems_capture_destroy_capture_task (rtems_capture_task_t* task) { if (task) @@ -487,7 +466,7 @@ rtems_capture_destroy_capture_task (rtems_capture_task_t* task) /* * This function records a capture record into the capture buffer. */ -static inline void +void rtems_capture_record (rtems_capture_task_t* task, uint32_t events) { @@ -550,7 +529,7 @@ rtems_capture_record (rtems_capture_task_t* task, * See if we have triggered and if not see if this event is a * cause of a trigger. */ -static bool +bool rtems_capture_trigger (rtems_capture_task_t* ft, rtems_capture_task_t* tt, uint32_t events) @@ -615,321 +594,6 @@ rtems_capture_trigger (rtems_capture_task_t* ft, return 1; } -/* - * This function is called when a task is created. - */ -static bool -rtems_capture_create_task (rtems_tcb* current_task, - rtems_tcb* new_task) -{ - rtems_capture_task_t* ct; - rtems_capture_task_t* nt; - - ct = current_task->extensions[capture_extension_index]; - - /* - * The task pointers may not be known as the task may have - * been created before the capture engine was open. Add them. - */ - - if (ct == NULL) - ct = rtems_capture_create_capture_task (current_task); - - /* - * Create the new task's capture control block. - */ - nt = rtems_capture_create_capture_task (new_task); - - 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; -} - -/* - * This function is called when a task is started. - */ -static void -rtems_capture_start_task (rtems_tcb* current_task, - rtems_tcb* started_task) -{ - /* - * Get the capture task control block so we can trace this - * event. - */ - rtems_capture_task_t* ct; - rtems_capture_task_t* st; - - ct = current_task->extensions[capture_extension_index]; - st = started_task->extensions[capture_extension_index]; - - /* - * The task pointers may not be known as the task may have - * been created before the capture engine was open. Add them. - */ - - if (ct == NULL) - ct = rtems_capture_create_capture_task (current_task); - - if (st == NULL) - st = rtems_capture_create_capture_task (started_task); - - 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); -} - -/* - * This function is called when a task is restarted. - */ -static void -rtems_capture_restart_task (rtems_tcb* current_task, - rtems_tcb* restarted_task) -{ - /* - * Get the capture task control block so we can trace this - * event. - */ - rtems_capture_task_t* ct; - rtems_capture_task_t* rt; - - ct = current_task->extensions[capture_extension_index]; - rt = restarted_task->extensions[capture_extension_index]; - - /* - * The task pointers may not be known as the task may have - * been created before the capture engine was open. Add them. - */ - - if (ct == NULL) - ct = rtems_capture_create_capture_task (current_task); - - if (rt == NULL) - rt = rtems_capture_create_capture_task (restarted_task); - - 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); -} - -/* - * This function is called when a task is deleted. - */ -static void -rtems_capture_delete_task (rtems_tcb* current_task, - rtems_tcb* deleted_task) -{ - /* - * Get the capture task control block so we can trace this - * event. - */ - rtems_capture_task_t* ct; - rtems_capture_task_t* dt; - - /* - * The task pointers may not be known as the task may have - * been created before the capture engine was open. Add them. - */ - - ct = current_task->extensions[capture_extension_index]; - dt = deleted_task->extensions[capture_extension_index]; - - if (ct == NULL) - ct = rtems_capture_create_capture_task (current_task); - - if (dt == NULL) - dt = rtems_capture_create_capture_task (deleted_task); - - 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 signals the - * task has been deleted. - */ - dt->tcb = 0; - - rtems_capture_destroy_capture_task (dt); -} - -/* - * This function is called when a task is begun. - */ -static void -rtems_capture_begin_task (rtems_tcb* begin_task) -{ - /* - * Get the capture task control block so we can trace this - * event. - */ - rtems_capture_task_t* bt; - - bt = begin_task->extensions[capture_extension_index]; - - /* - * 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); - - if (rtems_capture_trigger (NULL, bt, RTEMS_CAPTURE_BEGIN)) - rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT); -} - -/* - * This function is called when a task is exitted. That is - * returned rather than was deleted. - */ -static void -rtems_capture_exitted_task (rtems_tcb* exitted_task) -{ - /* - * Get the capture task control block so we can trace this - * event. - */ - rtems_capture_task_t* et; - - et = exitted_task->extensions[capture_extension_index]; - - /* - * 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); - - if (rtems_capture_trigger (NULL, et, RTEMS_CAPTURE_EXITTED)) - rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT); - - rtems_capture_task_stack_usage (et); -} - -/* - * This function is called when a termination request is identified. - */ -static void -rtems_capture_terminated_task (rtems_tcb* terminated_task) -{ - /* - * Get the capture task control block so we can trace this - * event. - */ - rtems_capture_task_t* tt; - - tt = terminated_task->extensions[capture_extension_index]; - - /* - * The task pointers may not be known as the task may have - * been created before the capture engine was open. Add them. - */ - - if (tt == NULL) - tt = rtems_capture_create_capture_task (terminated_task); - - if (rtems_capture_trigger (NULL, tt, RTEMS_CAPTURE_TERMINATED)) - rtems_capture_record (tt, RTEMS_CAPTURE_TERMINATED_EVENT); - - rtems_capture_task_stack_usage (tt); -} - -/* - * This function is called when a context is switched. - */ -static void -rtems_capture_switch_task (rtems_tcb* current_task, - rtems_tcb* heir_task) -{ - /* - * Only perform context switch trace processing if tracing is - * enabled. - */ - if (capture_flags & RTEMS_CAPTURE_ON) - { - rtems_capture_time_t time; - - /* - * Get the cpature task control block so we can update the - * 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; - rtems_capture_task_t* ht; - - - if (_States_Is_dormant (current_task->current_state)) - { - rtems_id ct_id = current_task->Object.id; - - for (ct = capture_tasks; ct; ct = ct->forw) - if (ct->id == ct_id) - break; - } - else - { - ct = current_task->extensions[capture_extension_index]; - - if (ct == NULL) - ct = rtems_capture_create_capture_task (current_task); - } - - ht = heir_task->extensions[capture_extension_index]; - - if (ht == NULL) - ht = rtems_capture_create_capture_task (heir_task); - - /* - * Update the execution time. Assume the time will not overflow - * for now. This may need to change. - */ - rtems_capture_get_time (&time); - - /* - * We could end up with null pointers for both the current task - * and the heir task. - */ - - if (ht) - { - ht->in++; - ht->time_in = time; - } - - if (ct) - { - ct->out++; - if (ct->time_in) - ct->time += time - ct->time_in; - } - - if (rtems_capture_trigger (ct, ht, RTEMS_CAPTURE_SWITCH)) - { - rtems_capture_record (ct, RTEMS_CAPTURE_SWITCHED_OUT_EVENT); - rtems_capture_record (ht, RTEMS_CAPTURE_SWITCHED_IN_EVENT); - } - } -} - /* * This function initialises the realtime capture engine allocating the trace * buffer. It is assumed we have a working heap at stage of initialisation. @@ -937,7 +601,6 @@ rtems_capture_switch_task (rtems_tcb* current_task, rtems_status_code rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribute__((unused))) { - rtems_name name; rtems_status_code sc; /* @@ -961,22 +624,13 @@ rtems_capture_open (uint32_t size, rtems_capture_timestamp timestamp __attribu capture_ceiling = 0; capture_floor = 255; - /* - * Register the user extension handlers for the CAPture Engine. - */ - name = rtems_build_name ('C', 'A', 'P', 'E'); - sc = rtems_extension_create (name, &capture_extensions, &capture_id); + sc = rtems_capture_user_extension_open(); if (sc != RTEMS_SUCCESSFUL) { - capture_id = 0; free (capture_records); capture_records = NULL; } - else - { - capture_extension_index = rtems_object_id_get_index (capture_id); - } /* * Iterate over the list of existing tasks. @@ -1016,7 +670,7 @@ rtems_capture_close (void) * release the resources we have without them being used. */ - sc = rtems_extension_delete (capture_id); + sc = rtems_capture_user_extension_close(); if (sc != RTEMS_SUCCESSFUL) return sc; diff --git a/cpukit/libmisc/capture/capture_user_extension.c b/cpukit/libmisc/capture/capture_user_extension.c new file mode 100644 index 0000000000..f3bebc829a --- /dev/null +++ b/cpukit/libmisc/capture/capture_user_extension.c @@ -0,0 +1,435 @@ +/* + ------------------------------------------------------------------------ + + Copyright Objective Design Systems Pty Ltd, 2002 + All rights reserved Objective Design Systems Pty Ltd, 2002 + Chris Johns (ccj@acm.org) + + COPYRIGHT (c) 1989-2009. + On-Line Applications Research Corporation (OAR). + + The license and distribution terms for this file may be + found in the file LICENSE in this distribution. + + This software with is provided ``as is'' and with NO WARRANTY. + + ------------------------------------------------------------------------ + + RTEMS Performance Monitoring and Measurement Framework. + + This is the Capture Engine component. +rtems_status_code rtems_capture_user_extension_open(void); +rtems_status_code rtems_capture_user_extension_close(void); + + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "captureimpl.h" + +#include +#include + + +/* + * RTEMS Capture User Extension Data. + */ +static rtems_id capture_id; + +static bool +rtems_capture_create_task (rtems_tcb* current_task, + rtems_tcb* new_task); + +static void +rtems_capture_start_task (rtems_tcb* current_task, + rtems_tcb* started_task); + +static void +rtems_capture_restart_task (rtems_tcb* current_task, + rtems_tcb* restarted_task); + +static void +rtems_capture_delete_task (rtems_tcb* current_task, + rtems_tcb* deleted_task); + +static void +rtems_capture_switch_task (rtems_tcb* current_task, + rtems_tcb* heir_task); + +static void +rtems_capture_begin_task (rtems_tcb* begin_task); + +static void +rtems_capture_exitted_task (rtems_tcb* exitted_task); + +static void +rtems_capture_terminated_task (rtems_tcb* terminated_task); + +static const rtems_extensions_table capture_extensions = { + .thread_create = rtems_capture_create_task, + .thread_start = rtems_capture_start_task, + .thread_restart = rtems_capture_restart_task, + .thread_delete = rtems_capture_delete_task, + .thread_switch = rtems_capture_switch_task, + .thread_begin = rtems_capture_begin_task, + .thread_exitted = rtems_capture_exitted_task, + .fatal = NULL, + .thread_terminate = rtems_capture_terminated_task +}; + +rtems_status_code rtems_capture_user_extension_open(void) +{ + rtems_status_code sc; + rtems_name name; + int index; + + /* + * Register the user extension handlers for the CAPture Engine. + */ + name = rtems_build_name ('C', 'A', 'P', 'E'); + sc = rtems_extension_create (name, &capture_extensions, &capture_id); + if (sc != RTEMS_SUCCESSFUL) + capture_id = 0; + else { + index = rtems_object_id_get_index (capture_id); + rtems_capture_set_extension_index( index ); + } + + return sc; +} + +rtems_status_code rtems_capture_user_extension_close(void) +{ + rtems_status_code sc; + sc = rtems_extension_delete (capture_id); + return sc; +} + +/* + * This function is called when a task is created. + */ +static bool +rtems_capture_create_task (rtems_tcb* current_task, + rtems_tcb* new_task) +{ + rtems_capture_task_t* ct; + rtems_capture_task_t* nt; + int index = rtems_capture_get_extension_index(); + + ct = current_task->extensions[index]; + + /* + * The task pointers may not be known as the task may have + * been created before the capture engine was open. Add them. + */ + + if (ct == NULL) + ct = rtems_capture_create_capture_task (current_task); + + /* + * Create the new task's capture control block. + */ + nt = rtems_capture_create_capture_task (new_task); + + 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; +} + +/* + * This function is called when a task is started. + */ +static void +rtems_capture_start_task (rtems_tcb* current_task, + rtems_tcb* started_task) +{ + /* + * Get the capture task control block so we can trace this + * event. + */ + rtems_capture_task_t* ct; + rtems_capture_task_t* st; + int index = rtems_capture_get_extension_index(); + + ct = current_task->extensions[index]; + st = started_task->extensions[index]; + + /* + * The task pointers may not be known as the task may have + * been created before the capture engine was open. Add them. + */ + + if (ct == NULL) + ct = rtems_capture_create_capture_task (current_task); + + if (st == NULL) + st = rtems_capture_create_capture_task (started_task); + + 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); +} + +/* + * This function is called when a task is restarted. + */ +static void +rtems_capture_restart_task (rtems_tcb* current_task, + rtems_tcb* restarted_task) +{ + /* + * Get the capture task control block so we can trace this + * event. + */ + rtems_capture_task_t* ct; + rtems_capture_task_t* rt; + int index = rtems_capture_get_extension_index(); + + ct = current_task->extensions[index]; + rt = restarted_task->extensions[index]; + + /* + * The task pointers may not be known as the task may have + * been created before the capture engine was open. Add them. + */ + + if (ct == NULL) + ct = rtems_capture_create_capture_task (current_task); + + if (rt == NULL) + rt = rtems_capture_create_capture_task (restarted_task); + + 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); +} + +/* + * This function is called when a task is deleted. + */ +static void +rtems_capture_delete_task (rtems_tcb* current_task, + rtems_tcb* deleted_task) +{ + /* + * Get the capture task control block so we can trace this + * event. + */ + rtems_capture_task_t* ct; + rtems_capture_task_t* dt; + int index = rtems_capture_get_extension_index(); + + /* + * The task pointers may not be known as the task may have + * been created before the capture engine was open. Add them. + */ + + ct = current_task->extensions[index]; + dt = deleted_task->extensions[index]; + + if (ct == NULL) + ct = rtems_capture_create_capture_task (current_task); + + if (dt == NULL) + dt = rtems_capture_create_capture_task (deleted_task); + + 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 signals the + * task has been deleted. + */ + dt->tcb = 0; + + rtems_capture_destroy_capture_task (dt); +} + +/* + * This function is called when a task is begun. + */ +static void +rtems_capture_begin_task (rtems_tcb* begin_task) +{ + /* + * Get the capture task control block so we can trace this + * event. + */ + rtems_capture_task_t* bt; + int index = rtems_capture_get_extension_index(); + + bt = begin_task->extensions[index]; + + /* + * 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); + + if (rtems_capture_trigger (NULL, bt, RTEMS_CAPTURE_BEGIN)) + rtems_capture_record (bt, RTEMS_CAPTURE_BEGIN_EVENT); +} + +/* + * This function is called when a task is exitted. That is + * returned rather than was deleted. + */ +static void +rtems_capture_exitted_task (rtems_tcb* exitted_task) +{ + /* + * Get the capture task control block so we can trace this + * event. + */ + rtems_capture_task_t* et; + int index = rtems_capture_get_extension_index(); + + et = exitted_task->extensions[index]; + + /* + * 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); + + if (rtems_capture_trigger (NULL, et, RTEMS_CAPTURE_EXITTED)) + rtems_capture_record (et, RTEMS_CAPTURE_EXITTED_EVENT); + + rtems_capture_task_stack_usage (et); +} + +/* + * This function is called when a termination request is identified. + */ +static void +rtems_capture_terminated_task (rtems_tcb* terminated_task) +{ + /* + * Get the capture task control block so we can trace this + * event. + */ + rtems_capture_task_t* tt; + int index = rtems_capture_get_extension_index(); + + tt = terminated_task->extensions[index]; + + /* + * The task pointers may not be known as the task may have + * been created before the capture engine was open. Add them. + */ + + if (tt == NULL) + tt = rtems_capture_create_capture_task (terminated_task); + + if (rtems_capture_trigger (NULL, tt, RTEMS_CAPTURE_TERMINATED)) + rtems_capture_record (tt, RTEMS_CAPTURE_TERMINATED_EVENT); + + rtems_capture_task_stack_usage (tt); +} + +/* + * This function is called when a context is switched. + */ +static void +rtems_capture_switch_task (rtems_tcb* current_task, + rtems_tcb* heir_task) +{ + uint32_t flags = rtems_capture_get_flags(); + int index = rtems_capture_get_extension_index(); + + /* + * Only perform context switch trace processing if tracing is + * enabled. + */ + if (flags & RTEMS_CAPTURE_ON) + { + rtems_capture_time_t time; + + /* + * Get the cpature task control block so we can update the + * 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; + rtems_capture_task_t* ht; + + + if (_States_Is_dormant (current_task->current_state)) + { + rtems_id ct_id = current_task->Object.id; + ct = rtems_capture_find_capture_task( ct_id ); + } + else + { + ct = current_task->extensions[index]; + + if (ct == NULL) + ct = rtems_capture_create_capture_task (current_task); + } + + ht = heir_task->extensions[index]; + + if (ht == NULL) + ht = rtems_capture_create_capture_task (heir_task); + + /* + * Update the execution time. Assume the time will not overflow + * for now. This may need to change. + */ + rtems_capture_get_time (&time); + + /* + * We could end up with null pointers for both the current task + * and the heir task. + */ + + if (ht) + { + ht->in++; + ht->time_in = time; + } + + if (ct) + { + ct->out++; + if (ct->time_in) + ct->time += time - ct->time_in; + } + + if (rtems_capture_trigger (ct, ht, RTEMS_CAPTURE_SWITCH)) + { + rtems_capture_record (ct, RTEMS_CAPTURE_SWITCHED_OUT_EVENT); + rtems_capture_record (ht, RTEMS_CAPTURE_SWITCHED_IN_EVENT); + } + } +} diff --git a/cpukit/libmisc/capture/captureimpl.h b/cpukit/libmisc/capture/captureimpl.h new file mode 100644 index 0000000000..ee18d827ad --- /dev/null +++ b/cpukit/libmisc/capture/captureimpl.h @@ -0,0 +1,195 @@ +/** + * @file rtems/captureimpl.h + * + * @brief Capture Implementation file + * + * This file contains an interface between the capture engine and + * capture user extension methods. + */ + +/* + ------------------------------------------------------------------------ + + Copyright Objective Design Systems Pty Ltd, 2002 + All rights reserved Objective Design Systems Pty Ltd, 2002 + Chris Johns (ccj@acm.org) + + COPYRIGHT (c) 1989-2014. + On-Line Applications Research Corporation (OAR). + + The license and distribution terms for this file may be + found in the file LICENSE in this distribution. + + This software with is provided ``as is'' and with NO WARRANTY. + + ------------------------------------------------------------------------ + + RTEMS Performance Monitoring and Measurement Framework. + This is the Capture Engine component. + +*/ + +#ifndef __CAPTUREIMPL_H_ +#define __CAPTUREIMPL_H_ + + +/**@{*/ +#ifdef __cplusplus +extern "C" { +#endif + +#include "capture.h" + +/* + * 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_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) + +/** + * @brief Capture set extension index. + * + * This function is used to set the extension index + * for the capture engine. + * + * @param[in] index specifies the extension index to be + * used for capture engine data. + */ +void rtems_capture_set_extension_index(int index); + +/** + * @brief Capture get extension index. + * + * This function rturns the extension index for the + * capture engine. + * + * @retval This method returns the extension index. + */ +int rtems_capture_get_extension_index(void); + +/** + * @brief Capture get flags. + * + * This function gets the current flag settings + * for the capture engine. + * + * @retval This method returns the global capture + * flags. + * + */ +uint32_t rtems_capture_get_flags(void); + +/** + * @brief Capture set flags. + * + * This function sets a flag in the capture engine + * + * @param[in] mask specifies the flag to set + */ +void rtems_capture_set_flags(uint32_t mask); + +/** + * @brief Capture user extension open. + * + * This function creates the capture user extensions. + * + * + * @retval This method returns RTEMS_SUCCESSFUL upon successful + * creation of the user extensions. + */ +rtems_status_code rtems_capture_user_extension_open(void); + +/** + * @brief Capture user extension close. + * + * This function closes the capture user extensions. + * + * @retval This method returns RTEMS_SUCCESSFUL upon a successful + * delete of the user extensions. + */ +rtems_status_code rtems_capture_user_extension_close(void); + +/** + * @brief Capture find capture task. + * + * This function finds the capture task control block + * + * @param[in] ct_id specifies the task_id + * + * @retval This method returns the capture task control block associated + * with the given task id. + */ +rtems_capture_task_t* rtems_capture_find_capture_task( rtems_id ct_id ); + +/** + * @brief Capture create capture task control block. + * + * This function create the capture task control block + * + * @param[in] new_task specifies the rtems thread control block + * + * @retval This method returns a capture task control block. + */ +rtems_capture_task_t* rtems_capture_create_capture_task (rtems_tcb* new_task); + +/** + * @brief Capture trigger. + * + * This function checks if we have triggered or if this event is a + * cause of a trigger. + * + * @param[in] ft specifies specifices the capture from task + * @param[in] tt specifies specifices the capture to task + * @param[in] events specifies the events + * + * @retval This method returns true if we have triggered or + * if the event is a cause of a trigger. + */ +bool rtems_capture_trigger (rtems_capture_task_t* ft, + rtems_capture_task_t* tt, + uint32_t events); +/** + * @brief Capture initialize stack usage + * + * This function setups a stack so its usage can be monitored. + * + * @param[in] task specifies the capture task block + */ +void rtems_capture_init_stack_usage (rtems_capture_task_t* task); + +/** + * @brief Capture destroy task. + * + * This function destroy the task structure if the reference count + * is 0 and the tcb has been cleared signalling the task has been + * deleted. + * + * @param[in] task specifies the capture task block + */ +void rtems_capture_destroy_capture_task (rtems_capture_task_t* task); + +/** + * @brief . + * + * This function returns the current time. If a handler is provided + * by the user the time is gotten from that. + * + * @param[in] time specifies the capture time + * + * @retval This method returns a nano-second time if no user handler + * is provided. Otherwise, it returns a resolution defined by the handler. + */ +void rtems_capture_get_time (rtems_capture_time_t* time); + + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3