source: rtems/cpukit/libmisc/capture/capture.h @ a923a82

4.104.114.84.95
Last change on this file since a923a82 was a923a82, checked in by Joel Sherrill <joel.sherrill@…>, on May 15, 2002 at 4:36:10 PM

2002-05-16 Chris Johns <ccj@…>

  • Per PR194, added the Capture engine.
  • capture/Makefile.am, capture/README, capture/capture-cli.c, capture/capture-cli.h, capture/capture.c, capture/capture.h, capture/.cvsignore: New files.
  • Makefile.am, configure.ac, wrapup/Makefile.am: Modified to reflect addition.
  • Property mode set to 100644
File size: 19.7 KB
Line 
1/*
2  ------------------------------------------------------------------------
3  $Id$
4  ------------------------------------------------------------------------
5 
6  Copyright Objective Design Systems Pty Ltd, 2002
7  All rights reserved Objective Design Systems Pty Ltd, 2002
8  Chris Johns (ccj@acm.org)
9
10  COPYRIGHT (c) 1989-1998.
11  On-Line Applications Research Corporation (OAR).
12
13  The license and distribution terms for this file may be
14  found in the file LICENSE in this distribution.
15
16  This software with is provided ``as is'' and with NO WARRANTY.
17 
18  ------------------------------------------------------------------------
19
20  RTEMS Performance Monitoring and Measurement Framework.
21
22  This is the Capture Engine component.
23
24*/
25
26#ifndef __CAPTURE_H_
27#define __CAPTURE_H_
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#include <rtems.h>
34
35/*
36 * The number of tasks in a trigger group.
37 */
38#define RTEMS_CAPTURE_TRIGGER_TASKS (32)
39
40/*
41 * rtems_capture_control_t
42 *
43 *  DESCRIPTION:
44 *
45 * RTEMS control holds the trigger and watch configuration for a group of
46 * tasks with the same name.
47 */
48typedef struct rtems_capture_control_s
49{
50  rtems_name                      name;
51  rtems_id                        id;
52  rtems_unsigned32                flags;
53  rtems_name                      from[RTEMS_CAPTURE_TRIGGER_TASKS];
54  rtems_id                        from_id[RTEMS_CAPTURE_TRIGGER_TASKS];
55  struct rtems_capture_control_s* next;
56} rtems_capture_control_t;
57
58/*
59 * Control flags.
60 */
61#define RTEMS_CAPTURE_WATCH         (1 << 0)
62#define RTEMS_CAPTURE_FROM_ANY      (1 << 1)
63#define RTEMS_CAPTURE_TO_ANY        (1 << 2)
64#define RTEMS_CAPTURE_FROM_TO       (1 << 3)
65 
66/*
67 * rtems_capture_control_t
68 *
69 *  DESCRIPTION:
70 *
71 * RTEMS capture control provdes the information about a task, along
72 * with its trigger state. The control is referenced by each
73 * capture record. This is* information neeed by the decoder. The
74 * capture record cannot assume the task will exist when the record is
75 * dumped via the target interface so task info needed for tracing is
76 * copied and held here.
77 *
78 * The inline heper functions provide more details about the info
79 * contained in this structure.
80 *
81 * Note, the tracer code exploits the fact an rtems_name is a
82 * 32bit value. 
83 */
84typedef struct rtems_capture_task_s
85{
86  rtems_name                   name;
87  rtems_id                     id;
88  rtems_unsigned32             flags;
89  rtems_tcb*                   tcb;
90  rtems_unsigned32             in;
91  rtems_unsigned32             out;
92  rtems_task_priority          start_priority;
93  rtems_unsigned32             stack_size;
94  rtems_unsigned32             stack_clean;
95  rtems_unsigned32             ticks;
96  rtems_unsigned32             tick_offset;
97  rtems_unsigned32             ticks_in;
98  rtems_unsigned32             tick_offset_in;
99  rtems_unsigned32             last_ticks;
100  rtems_unsigned32             last_tick_offset;
101  rtems_capture_control_t*     control;
102  struct rtems_capture_task_s* next;
103} rtems_capture_task_t;
104
105/*
106 * Task flags.
107 */
108#define RTEMS_CAPTURE_TRACED  (1 << 0)
109
110/*
111 * rtems_capture_record_t
112 *
113 *  DESCRIPTION:
114 *
115 * RTEMS capture record. This is a record that is written into
116 * the buffer. The events includes the priority of the task
117 * at the time of the context switch.
118 */
119typedef struct rtems_capture_record_s
120{
121  rtems_capture_task_t* task;
122  rtems_unsigned32      events;
123  rtems_unsigned32      ticks;
124  rtems_unsigned32      tick_offset;
125} rtems_capture_record_t;
126
127/*
128 * The capture record event flags.
129 */
130#define RTEMS_CAPTURE_REAL_PRI_EVENT_MASK (0x000000ff)
131#define RTEMS_CAPTURE_CURR_PRI_EVENT_MASK (0x0000ff00)
132#define RTEMS_CAPTURE_REAL_PRIORITY_EVENT (0)
133#define RTEMS_CAPTURE_CURR_PRIORITY_EVENT (8)
134#define RTEMS_CAPTURE_EVENT_START         (16)
135#define RTEMS_CAPTURE_CREATED_BY_EVENT    (1 << 16)
136#define RTEMS_CAPTURE_CREATED_EVENT       (1 << 17)
137#define RTEMS_CAPTURE_STARTED_BY_EVENT    (1 << 18)
138#define RTEMS_CAPTURE_STARTED_EVENT       (1 << 19)
139#define RTEMS_CAPTURE_RESTARTED_BY_EVENT  (1 << 20)
140#define RTEMS_CAPTURE_RESTARTED_EVENT     (1 << 21)
141#define RTEMS_CAPTURE_DELETED_BY_EVENT    (1 << 22)
142#define RTEMS_CAPTURE_DELETED_EVENT       (1 << 23)
143#define RTEMS_CAPTURE_BEGIN_EVENT         (1 << 24)
144#define RTEMS_CAPTURE_EXITTED_EVENT       (1 << 25)
145#define RTEMS_CAPTURE_SWITCHED_OUT_EVENT  (1 << 26)
146#define RTEMS_CAPTURE_SWITCHED_IN_EVENT   (1 << 27)
147#define RTEMS_CAPTURE_TIMESTAMP           (1 << 28)
148#define RTEMS_CAPTURE_EVENT_END           (28)
149
150/*
151 * rtems_capture_trigger_t
152 *
153 *  DESCRIPTION:
154 *
155 * The types of triggers that exist. FIXME: add more here.
156 */
157typedef enum rtems_capture_trigger_t
158{
159  rtems_capture_to_any,
160  rtems_capture_from_any,
161  rtems_capture_from_to
162} rtems_capture_trigger_t;
163
164/*
165 * rtems_capture_timestamp
166 *
167 *  DESCRIPTION:
168 *
169 * This defines the callout handler to obtain a time stamp. The
170 * value returned is time count since the last read.
171 *
172 */
173
174typedef void (*rtems_capture_timestamp)
175                (rtems_unsigned32* ticks, rtems_unsigned32* micro);
176
177/*
178 * rtems_capture_open
179 *
180 *  DESCRIPTION:
181 *
182 * This function initialises the realtime trace manager allocating the capture
183 * buffer. It is assumed we have a working heap at stage of initialisation.
184 *
185 */
186rtems_status_code
187rtems_capture_open (rtems_unsigned32        size,
188                    rtems_capture_timestamp timestamp);
189
190/*
191 * rtems_capture_close
192 *
193 *  DESCRIPTION:
194 *
195 * This function shutdowns the tracer and release any claimed
196 * resources.
197 */
198rtems_status_code
199rtems_capture_close ();
200
201/*
202 * rtems_capture_control
203 *
204 *  DESCRIPTION:
205 *
206 * This function allows control of tracing at a global level.
207 */
208rtems_status_code
209rtems_capture_control (rtems_boolean enable);
210
211/*
212 * rtems_capture_flush
213 *
214 *  DESCRIPTION:
215 *
216 * This function flushes the trace buffer. The prime parameter allows the
217 * capture engine to also be primed again.
218 */
219rtems_status_code
220rtems_capture_flush (rtems_boolean prime);
221
222/*
223 * rtems_capture_watch_add
224 *
225 *  DESCRIPTION:
226 *
227 * This function defines a watch for a specific task given a name. A watch
228 * causes it to be traced either in or out of context. The watch can be
229 * optionally enabled or disabled with the set routine. It is disabled by
230 * default.
231 */
232rtems_status_code
233rtems_capture_watch_add (rtems_name name, rtems_id id);
234
235/*
236 * rtems_capture_watch_del
237 *
238 *  DESCRIPTION:
239 *
240 * This function removes a watch for a specific task given a name. The task
241 * description will still exist if referenced by a trace record in the trace
242 * buffer or a global watch is defined.
243 */
244rtems_status_code
245rtems_capture_watch_del (rtems_name name, rtems_id id);
246
247/*
248 * rtems_capture_watch_set
249 *
250 *  DESCRIPTION:
251 *
252 * This function allows control of a watch. The watch can be enabled or
253 * disabled.
254 */
255rtems_status_code
256rtems_capture_watch_ctrl (rtems_name name, rtems_id id, rtems_boolean enable);
257
258/*
259 * rtems_capture_watch_global
260 *
261 *  DESCRIPTION:
262 *
263 * This function allows control of a global watch. The watch can be enabled or
264 * disabled. A global watch configures all tasks below the ceiling and above
265 * the floor to be traced.
266 */
267rtems_status_code
268rtems_capture_watch_global (rtems_boolean enable);
269
270/*
271 * rtems_capture_watch_global_on
272 *
273 *  DESCRIPTION:
274 *
275 * This function returns the global watch state.
276 */
277rtems_boolean
278rtems_capture_watch_global_on ();
279
280/*
281 * rtems_capture_watch_ceiling
282 *
283 *  DESCRIPTION:
284 *
285 * This function sets a watch ceiling. Tasks at or greating that the
286 * ceiling priority are not watched. This is a simple way to monitor
287 * an application and exclude system tasks running at a higher
288 * priority level.
289 */
290rtems_status_code
291rtems_capture_watch_ceiling (rtems_task_priority ceiling);
292
293/*
294 * rtems_capture_watch_get_ceiling
295 *
296 *  DESCRIPTION:
297 *
298 * This function gets the watch ceiling.
299 */
300rtems_task_priority
301rtems_capture_watch_get_ceiling ();
302
303/*
304 * rtems_capture_watch_floor
305 *
306 *  DESCRIPTION:
307 *
308 * This function sets a watch floor. Tasks at or less that the
309 * floor priority are not watched. This is a simple way to monitor
310 * an application and exclude system tasks running at a lower
311 * priority level.
312 */
313rtems_status_code
314rtems_capture_watch_floor (rtems_task_priority floor);
315
316/*
317 * rtems_capture_watch_get_floor
318 *
319 *  DESCRIPTION:
320 *
321 * This function gets the watch floor.
322 */
323rtems_task_priority
324rtems_capture_watch_get_floor ();
325
326/*
327 * rtems_capture_set_trigger
328 *
329 *  DESCRIPTION:
330 *
331 * This function sets an edge trigger. Left is the left side of
332 * the edge and right is right side of the edge. The trigger type
333 * can be -
334 *
335 *  FROM_ANY : a switch from any task to the right side of the edge.
336 *  TO_ANY   : a switch from the left side of the edge to any task.
337 *  FROM_TO  : a switch from the left side of the edge to the right
338 *             side of the edge.
339 *
340 * This set trigger routine will create a trace control for the
341 * target task. The task list is searched and any existing tasks
342 * are linked to the new control.
343 *
344 * We can have a number of tasks that have the same name so we
345 * search using names. This means a number of tasks can be
346 * linked to single control.
347 */
348rtems_status_code
349rtems_capture_set_trigger (rtems_name              from,
350                           rtems_id                from_id,
351                           rtems_name              to,
352                           rtems_id                to_id,
353                           rtems_capture_trigger_t trigger);
354
355/*
356 * rtems_capture_read
357 *
358 *  DESCRIPTION:
359 *
360 * This function reads a number of records from the capture buffer.
361 * The user can optionally block and wait until the buffer as a
362 * specific number of records available or a specific time has
363 * elasped.
364 *
365 * The function returns the number of record that is has that are
366 * in a continous block of memory. If the number of available records
367 * wrap then only those records are provided. This removes the need for
368 * caller to be concerned about buffer wrappings. If the number of
369 * requested records cannot be met due to the wrapping of the records
370 * less than the specified number will be returned.
371 *
372 * The user must release the records. This is achieved with a call to
373 * rtems_capture_release. Calls this function without a release will
374 * result in at least the same number of records being released.
375 *
376 * The 'threshold' parameter is the number of records that must be
377 * captured before returning. If a timeout period is specified (non-0)
378 * any captured records will be returned. These parameters stop
379 * thrashing occuring for a small number of records, yet allows
380 * a user configured latiency to be applied for single events.
381 *
382 * The 'timeout' parameter is in micro-seconds. A value of 0 will disable
383 * the timeout.
384 *
385 */
386rtems_status_code
387rtems_capture_read (rtems_unsigned32         threshold,
388                    rtems_unsigned32         timeout,
389                    rtems_unsigned32*        read,
390                    rtems_capture_record_t** recs);
391
392/*
393 * rtems_capture_release
394 *
395 *  DESCRIPTION:
396 *
397 * This function releases the requested number of record slots back
398 * to the capture engine. The count must match the number read.
399 */
400rtems_status_code
401rtems_capture_release (rtems_unsigned32 count);
402
403/*
404 * rtems_capture_tick_time
405 *
406 *  DESCRIPTION:
407 *
408 * This function returns the tick period in micro-seconds.
409 */
410rtems_unsigned32
411rtems_capture_tick_time ();
412
413/*
414 * rtems_capture_tick_time
415 *
416 *  DESCRIPTION:
417 *
418 * This function returns the tick period in micro-seconds.
419 */
420rtems_unsigned32
421rtems_capture_tick_time ();
422
423/*
424 * rtems_capture_event_text
425 *
426 *  DESCRIPTION:
427 *
428 * This function returns a string for an event based on the bit in the
429 * event. The functions takes the bit offset as a number not the bit
430 * set in a bit map.
431 */
432const char*
433rtems_capture_event_text (int event);
434
435/*
436 * rtems_capture_get_task_list
437 *
438 *  DESCRIPTION:
439 *
440 * This function returns the head of the list of tasks that the
441 * capture engine has detected.
442 */
443rtems_capture_task_t*
444rtems_capture_get_task_list ();
445
446/*
447 * rtems_capture_next_task
448 *
449 *  DESCRIPTION:
450 *
451 * This function returns the pointer to the next task in the list. The
452 * pointer NULL terminates the list.
453 */
454static inline rtems_capture_task_t*
455rtems_capture_next_task (rtems_capture_task_t* task)
456{
457  return task->next;
458}
459
460/*
461 * rtems_capture_task_valid
462 *
463 *  DESCRIPTION:
464 *
465 * This function returns true if the task control block points to
466 * a valid task.
467 */
468static inline rtems_boolean
469rtems_capture_task_valid (rtems_capture_task_t* task)
470{
471  return task->tcb != NULL;
472}
473
474/*
475 * rtems_capture_task_id
476 *
477 *  DESCRIPTION:
478 *
479 * This function returns the task id.
480 */
481static inline rtems_id
482rtems_capture_task_id (rtems_capture_task_t* task)
483{
484  return task->id;
485}
486
487/*
488 * rtems_capture_task_state
489 *
490 *  DESCRIPTION:
491 *
492 * This function returns the task state.
493 */
494static inline States_Control
495rtems_capture_task_state (rtems_capture_task_t* task)
496{
497  if (rtems_capture_task_valid (task))
498    return task->tcb->current_state;
499  return 0;
500}
501
502/*
503 * rtems_capture_task_name
504 *
505 *  DESCRIPTION:
506 *
507 * This function returns the task name.
508 */
509static inline rtems_name
510rtems_capture_task_name (rtems_capture_task_t* task)
511{
512  return task->name;
513}
514
515/*
516 * rtems_capture_task_flags
517 *
518 *  DESCRIPTION:
519 *
520 * This function returns the task flags.
521 */
522static inline rtems_unsigned32
523rtems_capture_task_flags (rtems_capture_task_t* task)
524{
525  return task->flags;
526}
527
528/*
529 * rtems_capture_task_control
530 *
531 *  DESCRIPTION:
532 *
533 * This function returns the task control if present.
534 */
535static inline rtems_capture_control_t*
536rtems_capture_task_control (rtems_capture_task_t* task)
537{
538  return task->control;
539}
540
541/*
542 * rtems_capture_task_control_flags
543 *
544 *  DESCRIPTION:
545 *
546 * This function returns the task control flags if a control is present.
547 */
548static inline rtems_unsigned32
549rtems_capture_task_control_flags (rtems_capture_task_t* task)
550{
551  if (!task->control)
552    return 0;
553  return task->control->flags;
554}
555
556/*
557 * rtems_capture_task_switched_in
558 *
559 *  DESCRIPTION:
560 *
561 * This function returns the number of times the task has
562 * been switched into context.
563 */
564static inline rtems_unsigned32
565rtems_capture_task_switched_in (rtems_capture_task_t* task)
566{
567  return task->in;
568}
569
570/*
571 * rtems_capture_task_switched_out
572 *
573 *  DESCRIPTION:
574 *
575 * This function returns the number of times the task has
576 * been switched out of context.
577 */
578static inline rtems_unsigned32
579rtems_capture_task_switched_out (rtems_capture_task_t* task)
580{
581  return task->out;
582}
583
584/*
585 * rtems_capture_task_curr_priority
586 *
587 *  DESCRIPTION:
588 *
589 * This function returns the tasks start priority. The tracer needs this
590 * to track where the task's priority goes.
591 */
592static inline rtems_task_priority
593rtems_capture_task_start_priority (rtems_capture_task_t* task)
594{
595  return task->start_priority;
596}
597
598/*
599 * rtems_capture_task_real_priority
600 *
601 *  DESCRIPTION:
602 *
603 * This function returns the tasks real priority.
604 */
605static inline rtems_task_priority
606rtems_capture_task_real_priority (rtems_capture_task_t* task)
607{
608  if (rtems_capture_task_valid (task))
609    return task->tcb->real_priority;
610  return 0;
611}
612
613/*
614 * rtems_capture_task_curr_priority
615 *
616 *  DESCRIPTION:
617 *
618 * This function returns the tasks current priority.
619 */
620static inline rtems_task_priority
621rtems_capture_task_curr_priority (rtems_capture_task_t* task)
622{
623  if (rtems_capture_task_valid (task))
624    return task->tcb->current_priority;
625  return 0;
626}
627
628/*
629 * rtems_capture_task_stack_usage
630 *
631 *  DESCRIPTION:
632 *
633 * This function updates the stack usage. The task control block
634 * is updated.
635 */
636rtems_unsigned32
637rtems_capture_task_stack_usage (rtems_capture_task_t* task);
638
639/*
640 * rtems_capture_task_stack_size
641 *
642 *  DESCRIPTION:
643 *
644 * This function returns the task's stack size.
645 */
646static inline rtems_unsigned32
647rtems_capture_task_stack_size (rtems_capture_task_t* task)
648{
649  return task->stack_size;
650}
651
652/*
653 * rtems_capture_task_stack_used
654 *
655 *  DESCRIPTION:
656 *
657 * This function returns the amount of stack used.
658 */
659static inline rtems_unsigned32
660rtems_capture_task_stack_used (rtems_capture_task_t* task)
661{
662  return task->stack_size - task->stack_clean;
663}
664
665/*
666 * rtems_capture_task_ticks
667 *
668 *  DESCRIPTION:
669 *
670 * This function returns the current execution time as ticks.
671 */
672static inline rtems_unsigned32
673rtems_capture_task_ticks (rtems_capture_task_t* task)
674{
675  return task->ticks;
676}
677
678/*
679 * rtems_capture_task_tick_offset
680 *
681 *  DESCRIPTION:
682 *
683 * This function returns the current execution time tick offset.
684 */
685static inline rtems_unsigned32
686rtems_capture_task_tick_offset (rtems_capture_task_t* task)
687{
688  return task->tick_offset;
689}
690
691/*
692 * rtems_capture_task_time
693 *
694 *  DESCRIPTION:
695 *
696 * This function returns the current execution time.
697 */
698static inline unsigned long long
699rtems_capture_task_time (rtems_capture_task_t* task)
700{
701  unsigned long long t = task->ticks;
702  return (t * rtems_capture_tick_time ()) + task->tick_offset;;
703}
704
705/*
706 * rtems_capture_task_delta_time
707 *
708 *  DESCRIPTION:
709 *
710 * This function returns the execution time as a different between the
711 * last time the detla time was and now.
712 */
713static inline unsigned long long
714rtems_capture_task_delta_time (rtems_capture_task_t* task)
715{
716  unsigned long long t = task->ticks - task->last_ticks;
717  rtems_unsigned32   o = task->tick_offset - task->last_tick_offset;
718
719  task->last_ticks       = task->ticks;
720  task->last_tick_offset = task->tick_offset;
721
722  return (t * rtems_capture_tick_time ()) + o;
723}
724
725/*
726 * rtems_capture_task_count
727 *
728 *  DESCRIPTION:
729 *
730 * This function returns the number of tasks the capture
731 * engine knows about.
732 */
733static inline rtems_unsigned32
734rtems_capture_task_count ()
735{
736  rtems_capture_task_t* task = rtems_capture_get_task_list ();
737  rtems_unsigned32      count = 0;
738 
739  while (task)
740  {
741    count++;
742    task = rtems_capture_next_task (task);
743  }
744
745  return count;
746}
747
748/*
749 * rtems_capture_get_control_list
750 *
751 *  DESCRIPTION:
752 *
753 * This function returns the head of the list of controls in the
754 * capture engine.
755 */
756rtems_capture_control_t*
757rtems_capture_get_control_list ();
758
759/*
760 * rtems_capture_next_control
761 *
762 *  DESCRIPTION:
763 *
764 * This function returns the pointer to the next control in the list. The
765 * pointer NULL terminates the list.
766 */
767static inline rtems_capture_control_t*
768rtems_capture_next_control (rtems_capture_control_t* control)
769{
770  return control->next;
771}
772
773/*
774 * rtems_capture_control_id
775 *
776 *  DESCRIPTION:
777 *
778 * This function returns the control id.
779 */
780static inline rtems_id
781rtems_capture_control_id (rtems_capture_control_t* control)
782{
783  return control->id;
784}
785
786/*
787 * rtems_capture_control_name
788 *
789 *  DESCRIPTION:
790 *
791 * This function returns the control name.
792 */
793static inline rtems_name
794rtems_capture_control_name (rtems_capture_control_t* control)
795{
796  return control->name;
797}
798
799/*
800 * rtems_capture_control_flags
801 *
802 *  DESCRIPTION:
803 *
804 * This function returns the control flags.
805 */
806static inline rtems_unsigned32
807rtems_capture_control_flags (rtems_capture_control_t* control)
808{
809  return control->flags;
810}
811
812/*
813 * rtems_capture_control_from_name
814 *
815 *  DESCRIPTION:
816 *
817 * This function returns the control from task name.
818 */
819static inline rtems_name
820rtems_capture_control_from_name (rtems_capture_control_t* control, int from)
821{
822  if (from < RTEMS_CAPTURE_TRIGGER_TASKS)
823    return control->from[from];
824  return control->from[0];
825}
826
827/*
828 * rtems_capture_control_from_id
829 *
830 *  DESCRIPTION:
831 *
832 * This function returns the control from task id.
833 */
834static inline rtems_id
835rtems_capture_control_from_id (rtems_capture_control_t* control, int from)
836{
837  if (from < RTEMS_CAPTURE_TRIGGER_TASKS)
838    return control->from_id[from];
839  return control->from_id[0];
840}
841
842/*
843 * rtems_capture_control_count
844 *
845 *  DESCRIPTION:
846 *
847 * This function returns the number of controls the capture
848 * engine has.
849 */
850static inline rtems_unsigned32
851rtems_capture_control_count ()
852{
853  rtems_capture_control_t* control = rtems_capture_get_control_list ();
854  rtems_unsigned32         count = 0;
855
856  while (control)
857  {
858    count++;
859    control = rtems_capture_next_control (control);
860  }
861
862  return count;
863}
864
865#ifdef __cplusplus
866}
867#endif
868
869#endif
Note: See TracBrowser for help on using the repository browser.