⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capture.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  ------------------------------------------------------------------------  $Id: capture.c,v 1.3.2.1 2003/07/08 08:36:36 ralf Exp $  ------------------------------------------------------------------------    Copyright Objective Design Systems Pty Ltd, 2002  All rights reserved Objective Design Systems Pty Ltd, 2002  Chris Johns (ccj@acm.org)  COPYRIGHT (c) 1989-1998.  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.*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <string.h>#include "capture.h"#include <rtems/score/states.inl>#include <rtems/score/wkspace.h>#include <rtems/score/wkspace.inl>/* * These events are always recorded and are not part of the * watch filters. */#define RTEMS_CAPTURE_RECORD_EVENTS  (RTEMS_CAPTURE_CREATED_BY_EVENT | \                                      RTEMS_CAPTURE_CREATED_EVENT | \                                      RTEMS_CAPTURE_STARTED_BY_EVENT | \                                      RTEMS_CAPTURE_STARTED_EVENT | \                                      RTEMS_CAPTURE_RESTARTED_BY_EVENT | \                                      RTEMS_CAPTURE_RESTARTED_EVENT | \                                      RTEMS_CAPTURE_DELETED_BY_EVENT | \                                      RTEMS_CAPTURE_DELETED_EVENT | \                                      RTEMS_CAPTURE_BEGIN_EVENT | \                                      RTEMS_CAPTURE_EXITTED_EVENT)/* * Global capture flags. */#define RTEMS_CAPTURE_ON             (1 << 0)#define RTEMS_CAPTURE_NO_MEMORY      (1 << 1)#define RTEMS_CAPTURE_OVERFLOW       (1 << 2)#define RTEMS_CAPTURE_TRIGGERED      (1 << 3)#define RTEMS_CAPTURE_READER_ACTIVE  (1 << 4)#define RTEMS_CAPTURE_READER_WAITING (1 << 5)#define RTEMS_CAPTURE_GLOBAL_WATCH   (1 << 6)/* * RTEMS Capture Data. */static rtems_capture_record_t*  capture_records;static rtems_unsigned32         capture_size;static rtems_unsigned32         capture_count;static rtems_capture_record_t*  capture_in;static rtems_unsigned32         capture_out;static rtems_unsigned32         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;static rtems_unsigned32         capture_tick_period;static rtems_id                 capture_reader;/* * RTEMS Event text. */static const char* capture_event_text[] ={  "CREATED_BY",  "CREATED",  "STARTED_BY",  "STARTED",  "RESTARTED_BY",  "RESTARTED",  "DELETED_BY",  "DELETED",  "BEGIN",  "EXITTED",  "SWITCHED_OUT",  "SWITCHED_IN",  "TIMESTAMP"};/* * rtems_capture_get_time * *  DESCRIPTION: * * 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 (rtems_unsigned32* ticks,                                           rtems_unsigned32* tick_offset){  if (capture_timestamp)    capture_timestamp (ticks, tick_offset);  else  {    *ticks       = _Watchdog_Ticks_since_boot;    *tick_offset = 0;  }}/* * rtems_capture_match_names * *  DESCRIPTION: * * This function compares rtems_names. It protects the * capture engine from a change to the way names are supported * in RTEMS. * */static inline rtems_booleanrtems_capture_match_names (rtems_name lhs, rtems_name rhs){  return lhs == rhs;}/* * rtems_capture_dup_name * *  DESCRIPTION: * * This function duplicates an rtems_names. It protects the * cpature engine from a change to the way names are supported * in RTEMS. * */static inline voidrtems_capture_dup_name (rtems_name* dst, rtems_name src){  *dst = src;}/* * rtems_capture_name_in_group * *  DESCRIPTION: * * This function sees if a name is in a group of names. * */static inline rtems_booleanrtems_capture_name_in_group (rtems_name task, rtems_name* tasks){  if (tasks)  {    int i;    for (i = 0; i < RTEMS_CAPTURE_TRIGGER_TASKS; i++)      if (rtems_capture_match_names (task, *tasks++))        return 1;  }  return 0;}/* * rtems_capture_match_name_id * *  DESCRIPTION: * * This function matches a name and/or id. */static inline rtems_booleanrtems_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_init_stack_usage * *  DESCRIPTION: * * This function setups a stack so its usage can be monitored. */static inline voidrtems_capture_init_stack_usage (rtems_capture_task_t* task){  if (task->tcb)  {    rtems_unsigned32* s;    rtems_unsigned32  i;    task->stack_size  = task->tcb->Start.Initial_stack.size;    task->stack_clean = task->stack_size;    s = task->tcb->Start.Initial_stack.area;    for (i = 0; i < (task->stack_size - 128); i += 4)      *(s++) = 0xdeaddead;  }}/* * rtems_capture_find_control * *  DESCRIPTION: * * This function searches for a trigger given a name. * */static inline rtems_capture_control_t*rtems_capture_find_control (rtems_name name, rtems_id id){  rtems_capture_control_t* control;    for (control = capture_controls; control != NULL; control = control->next)    if (rtems_capture_match_name_id (name, id, control->name, control->id))      break;  return control;}/* * rtems_capture_create_control * *  DESCRIPTION: * * This function creates a capture control for the capture engine. * */static inline rtems_capture_control_t*rtems_capture_create_control (rtems_name name, rtems_id id){  rtems_interrupt_level    level;  rtems_capture_control_t* control;  rtems_capture_task_t*    task;  if ((name == 0) && (id == 0))    return NULL;  control = rtems_capture_find_control (name, id);    if (control == NULL)  {    control = _Workspace_Allocate (sizeof (rtems_capture_control_t));    if (control == NULL)    {      capture_flags |= RTEMS_CAPTURE_NO_MEMORY;      return NULL;    }        control->name  = name;    control->id    = id;    control->flags = 0;    memset (control->from,    0, sizeof (control->from));    memset (control->from_id, 0, sizeof (control->from_id));        rtems_interrupt_disable (level);    control->next    = capture_controls;    capture_controls = control;    /*     * We need to scan the task list as set the control to the     * tasks.     */    for (task = capture_tasks; task != NULL; task = task->next)      if (rtems_capture_match_name_id (name, id, task->name, task->id))        task->control = control;    rtems_interrupt_enable (level);  }  return control;}/* * rtems_capture_create_capture_task * *  DESCRIPTION: * * This function create the task control. * */static inline rtems_capture_task_t*rtems_capture_create_capture_task (rtems_tcb* new_task){  rtems_interrupt_level    level;  rtems_capture_task_t*    task;  rtems_capture_control_t* control;  task = _Workspace_Allocate (sizeof (rtems_capture_task_t));  if (task == NULL)  {    capture_flags |= RTEMS_CAPTURE_NO_MEMORY;    return NULL;  }  rtems_capture_dup_name (&task->name, ((rtems_name) new_task->Object.name));    task->id               = new_task->Object.id;  task->flags            = 0;  task->in               = 0;  task->out              = 0;  task->tcb              = new_task;  task->ticks            = 0;  task->tick_offset      = 0;  task->ticks_in         = 0;  task->tick_offset_in   = 0;  task->control          = 0;  task->last_ticks       = 0;  task->last_tick_offset = 0;  task->tcb->extensions[capture_extension_index] = task;  task->start_priority = new_task->Start.initial_priority;  task->stack_size     = new_task->Start.Initial_stack.size;  task->stack_clean    = task->stack_size;  rtems_interrupt_disable (level);  task->next    = capture_tasks;  capture_tasks = task;  rtems_interrupt_enable (level);  /*   * We need to scan the default control list to initialise   * this control.   */  for (control = capture_controls; control != NULL; control = control->next)    if (rtems_capture_match_name_id (control->name, control->id,                                     task->name, task->id))      task->control = control;    return task;}/* * rtems_capture_record * *  DESCRIPTION: * * This function records a capture record into the capture buffer. * */static inline voidrtems_capture_record (rtems_capture_task_t* task,                      rtems_unsigned32      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)  {    rtems_capture_control_t* control;    control = task->control;    /*     * Capure the record if we have an event that is always     * captured, or the task's real priority is greater than the     * watch ceiling, and the global watch or task watch is enabled.     */    if ((events & RTEMS_CAPTURE_RECORD_EVENTS) ||        ((task->tcb->real_priority >= capture_ceiling) &&         (task->tcb->real_priority <= capture_floor) &&         ((capture_flags & RTEMS_CAPTURE_GLOBAL_WATCH) ||          (control && (control->flags & RTEMS_CAPTURE_WATCH)))))    {      rtems_interrupt_level level;            rtems_interrupt_disable (level);          if (capture_count < capture_size)      {        capture_count++;        capture_in->task   = task;        capture_in->events = (events |                              (task->tcb->real_priority) |                              (task->tcb->current_priority << 8));        if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)          task->flags |= RTEMS_CAPTURE_TRACED;        rtems_capture_get_time (&capture_in->ticks, &capture_in->tick_offset);        if (capture_in == &capture_records[capture_size - 1])          capture_in = capture_records;        else          capture_in++;                }      else        capture_flags |= RTEMS_CAPTURE_OVERFLOW;      rtems_interrupt_enable (level);    }  }}/* * rtems_capture_create_task * *  DESCRIPTION: * * This function is called when a task is created. * */static rtems_booleanrtems_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 ponters 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 we are logging then record this fact.   */  rtems_capture_record (ct, RTEMS_CAPTURE_CREATED_BY_EVENT);  rtems_capture_record (nt, RTEMS_CAPTURE_CREATED_EVENT);  return 1 == 1;}/* * rtems_capture_start_task * *  DESCRIPTION: * * This function is called when a task is started. * */static rtems_extensionrtems_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 ponters 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);  rtems_capture_record (ct, RTEMS_CAPTURE_STARTED_BY_EVENT);  rtems_capture_record (st, RTEMS_CAPTURE_STARTED_EVENT);    rtems_capture_init_stack_usage (st);}/* * rtems_capture_restart_task * *  DESCRIPTION: * * This function is called when a task is restarted. * */static rtems_extensionrtems_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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -