Changeset 2a86615 in rtems


Ignore:
Timestamp:
Aug 5, 2014, 8:48:01 PM (5 years ago)
Author:
Jennifer Averett <jennifer.averett@…>
Branches:
4.11, master
Children:
a72f16e
Parents:
133962b
git-author:
Jennifer Averett <jennifer.averett@…> (08/05/14 20:48:01)
git-committer:
Jennifer Averett <jennifer.averett@…> (09/05/14 11:50:29)
Message:

capture: Add support for variable length records.

Location:
cpukit
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • cpukit/Makefile.am

    r133962b r2a86615  
    150150include_rtems_HEADERS += libmisc/capture/capture.h
    151151include_rtems_HEADERS += libmisc/capture/capture-cli.h
     152include_rtems_HEADERS += libmisc/capture/captureimpl.h
    152153
    153154## cpuuse
  • cpukit/libmisc/Makefile.am

    r133962b r2a86615  
    1919noinst_LIBRARIES += libcapture.a
    2020libcapture_a_SOURCES = capture/capture.c capture/capture-cli.c \
    21     capture/capture_user_extension.c \
    22     capture/capture.h capture/captureimpl.h capture/capture-cli.h
     21    capture/capture_user_extension.c capture/capture_buffer.c \
     22    capture/capture.h capture/captureimpl.h capture/capture-cli.h \
     23    capture/capture_buffer.h
    2324
    2425## cpuuse
  • cpukit/libmisc/capture/capture-cli.c

    r133962b r2a86615  
    13541354  uint32_t                read;
    13551355  rtems_capture_record_t* rec;
     1356  uint8_t*                ptr;
    13561357  int                     arg;
    13571358  rtems_capture_time_t    last_t = 0;
     
    14091410
    14101411    count = total < read ? total : read;
    1411 
     1412    ptr = (uint8_t *) rec;
    14121413    while (count--)
    14131414    {
     1415      rec = (rtems_capture_record_t*) ptr;
     1416
    14141417      if (csv)
    14151418        fprintf (stdout, "%08" PRIxPTR ",%03" PRIu32
     
    14511454        }
    14521455      }
    1453       rec++;
     1456      ptr += rec->size;
    14541457    }
    14551458
  • cpukit/libmisc/capture/capture.c

    r133962b r2a86615  
    3131
    3232#include "captureimpl.h"
     33#include "capture_buffer.h"
    3334
    3435#include <rtems/score/statesimpl.h>
     
    5354                                      RTEMS_CAPTURE_BEGIN_EVENT | \
    5455                                      RTEMS_CAPTURE_EXITTED_EVENT | \
    55                                       RTEMS_CAPTURE_TERMINATED_EVENT)
     56                                      RTEMS_CAPTURE_TERMINATED_EVENT | \
     57                                      RTEMS_CAPTURE_AUTOGEN_ENTRY_EVENT | \
     58                                      RTEMS_CAPTURE_AUTOGEN_EXIT_EVENT)
    5659#else
    5760#define RTEMS_CAPTURE_RECORD_EVENTS  (0)
     
    6265 * RTEMS Capture Data.
    6366 */
    64 static rtems_capture_record_t*  capture_records;
    65 static uint32_t                 capture_size;
     67static rtems_capture_buffer_t         capture_records = {NULL, 0, 0, 0, 0, 0};
    6668static uint32_t                 capture_count;
    67 static rtems_capture_record_t*  capture_in;
    68 static uint32_t                 capture_out;
    6969static uint32_t                 capture_flags;
    7070static rtems_capture_task_t*    capture_tasks;
     
    465465
    466466/*
    467  * This function records a capture record into the capture buffer.
    468  */
    469 void
    470 rtems_capture_record (rtems_capture_task_t* task,
    471                       uint32_t              events)
    472 {
    473   /*
    474    * Check the watch state if we have a task control, and
    475    * the task's real priority is lower or equal to the ceiling.
    476    */
     467 * This function indicates if data should be filtered from the
     468 * log.
     469 */
     470bool rtems_capture_filter( rtems_capture_task_t* task,
     471                           uint32_t              events)
     472{
    477473  if (task &&
    478474      ((capture_flags &
     
    495491          (control && (control->flags & RTEMS_CAPTURE_WATCH)))))
    496492    {
    497       rtems_interrupt_lock_context lock_context;
    498 
    499       rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
    500 
    501       if (capture_count < capture_size)
    502       {
    503         capture_count++;
    504         capture_in->task   = task;
    505         capture_in->events = (events |
    506                               (task->tcb->real_priority) |
    507                               (task->tcb->current_priority << 8));
    508 
    509         if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)
    510           task->flags |= RTEMS_CAPTURE_TRACED;
    511 
    512         rtems_capture_get_time (&capture_in->time);
    513 
    514         if (capture_in == &capture_records[capture_size - 1])
    515           capture_in = capture_records;
    516         else
    517           capture_in++;
    518 
    519         rtems_capture_refcount_up (task);
    520       }
    521       else
    522         capture_flags |= RTEMS_CAPTURE_OVERFLOW;
    523       rtems_interrupt_lock_release (&capture_lock, &lock_context);
    524     }
    525   }
     493      return false;
     494    }
     495  }
     496
     497  return true;
     498}
     499
     500/*
     501 * This function records a capture record into the capture buffer.
     502 */
     503void *
     504rtems_capture_record_open (rtems_capture_task_t*         task,
     505                           uint32_t                      events,
     506                           size_t                        size,
     507                           rtems_interrupt_lock_context* lock_context)
     508{
     509  uint8_t*                     ptr;
     510  rtems_capture_record_t*      capture_in;
     511
     512  rtems_interrupt_lock_acquire (&capture_lock, lock_context);
     513
     514  ptr = rtems_capture_buffer_allocate(&capture_records, size);
     515  capture_in = (rtems_capture_record_t *) ptr;
     516  if ( capture_in )
     517  {
     518    capture_count++;
     519    capture_in->size   = size;
     520    capture_in->task   = task;
     521    capture_in->events = (events |
     522                          (task->tcb->real_priority) |
     523                          (task->tcb->current_priority << 8));
     524
     525    if ((events & RTEMS_CAPTURE_RECORD_EVENTS) == 0)
     526      task->flags |= RTEMS_CAPTURE_TRACED;
     527
     528    rtems_capture_get_time (&capture_in->time);
     529
     530    rtems_capture_refcount_up (task);
     531    ptr = ptr + sizeof(*capture_in);
     532  }
     533  else
     534    capture_flags |= RTEMS_CAPTURE_OVERFLOW;
     535
     536  return ptr;
     537}
     538
     539void rtems_capture_record_close( void *rec, rtems_interrupt_lock_context* lock_context)
     540{
     541  rtems_interrupt_lock_release (&capture_lock, lock_context);
    526542}
    527543
     
    608624   */
    609625
    610   if (capture_records)
     626  if (capture_records.buffer)
    611627    return RTEMS_RESOURCE_IN_USE;
    612628
    613   capture_records = malloc (size * sizeof (rtems_capture_record_t));
    614 
    615   if (capture_records == NULL)
     629  rtems_capture_buffer_create( &capture_records, size );
     630
     631  if (capture_records.buffer == NULL)
    616632    return RTEMS_NO_MEMORY;
    617633
    618   capture_size    = size;
    619634  capture_count   = 0;
    620   capture_in      = capture_records;
    621   capture_out     = 0;
    622635  capture_flags   = 0;
    623636  capture_tasks   = NULL;
     
    629642  if (sc != RTEMS_SUCCESSFUL)
    630643  {
    631     free (capture_records);
    632     capture_records = NULL;
     644    rtems_capture_buffer_destroy( &capture_records);
    633645  }
    634646
     
    654666  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
    655667
    656   if (!capture_records)
     668  if (!capture_records.buffer)
    657669  {
    658670    rtems_interrupt_lock_release (&capture_lock, &lock_context);
     
    661673
    662674  capture_flags &= ~(RTEMS_CAPTURE_ON | RTEMS_CAPTURE_ONLY_MONITOR);
    663 
    664   capture_records = NULL;
    665675
    666676  rtems_interrupt_lock_release (&capture_lock, &lock_context);
     
    698708  capture_controls = NULL;
    699709
    700   if (capture_records)
    701   {
    702     free (capture_records);
    703     capture_records = NULL;
     710  if (capture_records.buffer)
     711  {
     712    rtems_capture_buffer_destroy( &capture_records);
    704713  }
    705714
     
    723732  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
    724733
    725   if (!capture_records)
     734  if (!capture_records.buffer)
    726735  {
    727736    rtems_interrupt_lock_release (&capture_lock, &lock_context);
     
    753762  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
    754763
    755   if (!capture_records)
     764  if (!capture_records.buffer)
    756765  {
    757766    rtems_interrupt_lock_release (&capture_lock, &lock_context);
     
    792801    capture_flags &= ~RTEMS_CAPTURE_OVERFLOW;
    793802
     803  rtems_capture_buffer_flush( &capture_records );
    794804  capture_count = 0;
    795   capture_in    = capture_records;
    796   capture_out   = 0;
    797805
    798806  rtems_interrupt_lock_release (&capture_lock, &lock_context);
     
    11941202  }
    11951203  return RTEMS_SUCCESSFUL;
     1204}
     1205
     1206static inline uint32_t rtems_capture_count_records( void* recs, size_t size )
     1207{
     1208  rtems_capture_record_t* rec;
     1209  uint8_t*                ptr = recs;
     1210  uint32_t                rec_count = 0;
     1211  size_t                  byte_count = 0;
     1212 
     1213 
     1214 while (byte_count < size) {
     1215    rec = (rtems_capture_record_t*) ptr;
     1216    rec_count++;
     1217    _Assert( rec->size >= sizeof(*rec) );
     1218    ptr += rec->size;
     1219    byte_count += rec->size;
     1220    _Assert( rec_count <= capture_count );
     1221 };
     1222   
     1223 return rec_count;
    11961224}
    11971225
     
    12301258  rtems_interrupt_lock_context lock_context;
    12311259  rtems_status_code            sc = RTEMS_SUCCESSFUL;
    1232   uint32_t                     count;
     1260  size_t                       recs_size = 0;
     1261  bool                         wrapped;
    12331262
    12341263  *read = 0;
     
    12481277
    12491278  capture_flags |= RTEMS_CAPTURE_READER_ACTIVE;
    1250   *read = count = capture_count;
     1279
     1280  *recs = rtems_capture_buffer_peek( &capture_records, &recs_size );
     1281  *read = rtems_capture_count_records( *recs, recs_size );
    12511282
    12521283  rtems_interrupt_lock_release (&capture_lock, &lock_context);
    12531284
    1254   *recs = &capture_records[capture_out];
    1255 
    12561285  for (;;)
    12571286  {
    12581287    /*
    1259      * See if the count wraps the end of the record buffer.
     1288     * See if the data wraps the end of the record buffer.
    12601289     */
    1261     if (count && ((capture_out + count) >= capture_size))
    1262       *read = capture_size - capture_out;
     1290    wrapped = rtems_capture_buffer_has_wrapped( &capture_records);
    12631291
    12641292    /*
    1265      * Do we have a threshold and the current count has not wrapped
     1293     * Do we have a threshold and have not wrapped
    12661294     * around the end of the capture record buffer ?
    12671295     */
    1268     if ((*read == count) && threshold)
     1296    if ((!wrapped) && threshold)
    12691297    {
    12701298      /*
     
    12981326        rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
    12991327
    1300         *read = count = capture_count;
     1328        *recs = rtems_capture_buffer_peek( &capture_records, &recs_size );
     1329        *read = rtems_capture_count_records( *recs, recs_size );
    13011330
    13021331        rtems_interrupt_lock_release (&capture_lock, &lock_context);
     
    13231352{
    13241353  rtems_interrupt_lock_context lock_context;
     1354  uint8_t*                     ptr;
    13251355  rtems_capture_record_t*      rec;
    13261356  uint32_t                     counted;
     1357  size_t                       ptr_size = 0;
    13271358
    13281359  rtems_interrupt_lock_acquire (&capture_lock, &lock_context);
     
    13341365
    13351366  counted = count;
    1336 
    1337   rec = &capture_records[capture_out];
    1338 
     1367 
     1368  ptr = rtems_capture_buffer_peek( &capture_records, &ptr_size );
     1369  _Assert(ptr_size >= (count * sizeof(*rec) ));
     1370
     1371  ptr_size = 0;
    13391372  while (counted--)
    1340   {
     1373  {
     1374    rec = (rtems_capture_record_t*) ptr;
     1375    ptr_size += rec->size;
    13411376    rtems_capture_refcount_down (rec->task);
    13421377    rtems_capture_destroy_capture_task (rec->task);
    1343     rec++;
     1378    ptr += rec->size;
    13441379  }
    13451380
     
    13481383  capture_count -= count;
    13491384
    1350   capture_out = (capture_out + count) % capture_size;
     1385  if (count)
     1386    rtems_capture_buffer_free( &capture_records, ptr_size );
    13511387
    13521388  capture_flags &= ~RTEMS_CAPTURE_READER_ACTIVE;
     
    14311467  return capture_controls;
    14321468}
     1469
     1470
  • cpukit/libmisc/capture/capture.h

    r133962b r2a86615  
    192192  uint32_t              events;
    193193  rtems_capture_time_t  time;
     194  size_t                size;
    194195} rtems_capture_record_t;
    195196
  • cpukit/libmisc/capture/capture_user_extension.c

    r133962b r2a86615  
    8585};
    8686
     87
     88static inline void rtems_capture_record (
     89  rtems_capture_task_t* task,
     90  uint32_t              events
     91)
     92{
     93  rtems_capture_record_t*  rec;
     94
     95  if (rtems_capture_filter( task, events) )
     96    return;
     97 
     98  rtems_capture_begin_add_record (task, events, sizeof(*rec), &rec);
     99
     100  rtems_capture_end_add_record ( rec );
     101}
     102
     103
    87104rtems_status_code rtems_capture_user_extension_open(void)
    88105{
  • cpukit/libmisc/capture/captureimpl.h

    r133962b r2a86615  
    155155                       rtems_capture_task_t* tt,
    156156                       uint32_t              events);
     157
     158/**
     159 * @brief Capture append to record
     160 *
     161 * This function Capture appends data to a capture record.  It should
     162 * be called between rtems_capture_begin_add_record and
     163 * rtems_capture_end_add_record.
     164 *
     165 * @param[in] rec specifies the next location to write in the record
     166 * @param[in] data specifies the data to write
     167 * @param[in] size specifies specifies the size of the data
     168 *
     169 * @retval This method returns a pointer which is used as a marker
     170 * for the next location in the capture record. it should only be
     171 * used as input into rtems_capture_append_to_record or
     172 * rtems_capture_end_add_record.
     173 */
     174static void *rtems_capture_append_to_record(void*  rec,
     175                                     void*  data,
     176                                     size_t size );
     177
     178/**
     179 * @brief Capture filter
     180 *
     181 * This function this function specifies if the given task
     182 * and events should be logged.
     183 *
     184 * @param[in] task specifies the capture task control block
     185 * @param[in] events specifies the events
     186 *
     187 * @retval This method returns true if this data should be
     188 * filtered from the log.  It returns false if this data
     189 * should be logged.
     190 */
     191bool rtems_capture_filter( rtems_capture_task_t* task,
     192                           uint32_t              events);
     193/**
     194 * @brief Capture begin add record.
     195 *
     196 * This function opens a record for writing and inserts
     197 * the header information
     198 *
     199 * @param[in] _task specifies the capture task block
     200 * @param[in] _events specifies the events
     201 * @param[in] _size specifies the expected size of the capture record
     202 * @param[out] _rec specifies the next write point in the capture record
     203 */
     204#define rtems_capture_begin_add_record( _task, _events, _size, _rec) \
     205  do { \
     206    rtems_interrupt_lock_context _lock_context; \
     207    *_rec = rtems_capture_record_open( _task, _events, _size, &_lock_context );
     208
     209/**
     210 * @brief Capture append to record.
     211 *
     212 * This function appends data of a specifed size into a capture record.
     213 *
     214 * @param[in] rec specifies the next write point in the capture record
     215 * @param[in] data specifies the data to write
     216 * @param[in] size specifies the size of the data
     217 *
     218 * @retval This method returns the next write point in the capture record.
     219 */
     220static inline void *rtems_capture_append_to_record(void*  rec,
     221                                                   void*  data,
     222                                                   size_t size )
     223{
     224  uint8_t *ptr = rec;
     225  memcpy( ptr, data, size );
     226  return (ptr + size);
     227}
     228
     229/**
     230 * @brief Capture end add record.
     231 *
     232 * This function completes the add capture record process
     233 *
     234 * @param[in] _rec specifies the end of the capture record
     235 */
     236#define rtems_capture_end_add_record( _rec ) \
     237    rtems_capture_record_close( _rec, &_lock_context ); \
     238  } while (0)
     239
    157240/**
    158241 * @brief Capture initialize stack usage
     
    188271void rtems_capture_get_time (rtems_capture_time_t* time);
    189272
     273/**
     274 * @brief Capture record open.
     275 *
     276 * This function allocates a record and fills in the
     277 * header information.  It does a lock acquire
     278 * which will remain in effect until
     279 * rtems_capture_record_close is called.  This method
     280 * should only be used by rtems_capture_begin_add_record.
     281 *
     282 * @param[in] task specifies the caputre task block
     283 * @param[in] events specifies the events
     284 * @param[in] size specifies capture record size
     285 * @param[out] lock_context specifies the lock context
     286 *
     287 * @retval This method returns a pointer to the next location in
     288 * the capture record to store data.
     289 */
     290void* rtems_capture_record_open (rtems_capture_task_t*         task,
     291                                 uint32_t                      events,
     292                                 size_t                        size,
     293                                 rtems_interrupt_lock_context* lock_context);
     294/**
     295 * @brief Capture record close.
     296 *
     297 * This function closes writing to capure record and
     298 * releases the lock that was held on the record. This
     299 * method should only be used by rtems_capture_end_add_record.
     300 *
     301 * @param[in] rec specifies the record
     302 * @param[out] lock_context specifies the lock context
     303 */
     304void rtems_capture_record_close( void *rec, rtems_interrupt_lock_context* lock_context);
     305
    190306
    191307#ifdef __cplusplus
  • cpukit/preinstall.am

    r133962b r2a86615  
    331331PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/capture-cli.h
    332332
     333$(PROJECT_INCLUDE)/rtems/captureimpl.h: libmisc/capture/captureimpl.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
     334        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/captureimpl.h
     335PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/captureimpl.h
     336
    333337$(PROJECT_INCLUDE)/rtems/cpuuse.h: libmisc/cpuuse/cpuuse.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
    334338        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/cpuuse.h
Note: See TracChangeset for help on using the changeset viewer.