source: rtems/cpukit/libblock/src/show_bdbuf.c @ 9de9b7d2

4.115
Last change on this file since 9de9b7d2 was f6c7bcfe, checked in by Mathew Kallada <matkallada@…>, on 12/21/12 at 17:42:39

libblock: Doxygen Enhancement Task #1

  • Property mode set to 100644
File size: 29.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief Enable the Monitor to Show bdbuf Information
5 * @ingroup rtems_bdpart
6 *
7 * This module inspects the bdbuf data structures,
8 * assuming they are static, but in fact they are used very
9 * dynamically. Therefore the results show MAY BE INCORRECT in
10 * some cases. And, to cure this a bit, this module may block
11 * preemption for a rather long time and therefore it may
12 * BREAK THE REALTIME BEHAVIOUR OF YOUR SYSTEM (when in use)
13 */
14
15/*
16 * Copyright (c) 2005
17 * Embedded Brains GmbH
18 * Obere Lagerstr. 30
19 * D-82178 Puchheim
20 * Germany
21 * rtems@embedded-brains.de
22 * The license and distribution terms for this file may be
23 * found in the file LICENSE in this distribution or at
24 * http://www.rtems.com/license/LICENSE.
25 */
26
27#if HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <rtems.h>
32#include <rtems/monitor.h>
33#include <rtems/bdbuf.h>
34#include <string.h>
35#include <ctype.h>
36#include <stdio.h>
37#include <rtems/libio.h>
38#include <inttypes.h>
39
40typedef struct {
41  bool bdbuf_modified;
42  bool bdbuf_in_progress;
43  bool bdbuf_actual;
44  bool bdbuf_used;
45  bool bdbuf_all;
46  rtems_bdpool_id pool_id;
47} show_bdbuf_filter_t;
48
49typedef struct {
50  bool show_all;
51  bool show_node_chain;
52  bool show_dev;
53  bool show_blocknum;
54  bool show_error;
55  bool show_state;
56  bool show_use_count;
57  bool show_pool_id;
58  bool show_sema;
59} show_bdbuf_selector_t;
60
61typedef enum {bdbuf_chain_ident_none,
62              bdbuf_chain_ident_free,
63              bdbuf_chain_ident_lru,
64              bdbuf_chain_ident_mod} bdbuf_chain_identifier_t;
65
66typedef struct {
67  rtems_bdpool_id pool_id;
68  int index;
69  bdbuf_chain_identifier_t in_chain;
70  dev_t dev;
71  blkdev_bnum blknum;
72  rtems_status_code status;
73  int error;
74  bool modified;
75  bool in_progress;
76  bool actual;
77  int use_count;
78  const CORE_mutex_Control *sema;
79} show_bdbuf_bdbuf_info_t;
80
81typedef rtems_mode preemption_key_t;
82#define DISABLE_PREEMPTION(key) \
83    do {                                                               \
84        rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &(key)); \
85    } while (0)
86
87#define ENABLE_PREEMPTION(key) \
88    do {                                                        \
89        rtems_mode temp;                                        \
90        rtems_task_mode((key), RTEMS_PREEMPT_MASK, &temp);      \
91    } while (0)
92
93/*=========================================================================*\
94| Function:                                                                 |
95\*-------------------------------------------------------------------------*/
96rtems_status_code rtems_bdbuf_show_follow_chain_node_to_head
97(
98/*-------------------------------------------------------------------------*\
99| Purpose:                                                                  |
100|   follow a given chain to its head                                        |
101|   XXX: this is executed with preemption disabled                          |
102+---------------------------------------------------------------------------+
103| Input Parameters:                                                         |
104\*-------------------------------------------------------------------------*/
105 const Chain_Node *the_node, /* input: node to track to its head  */
106 Chain_Control **the_head    /* storage for pointer to chain head */
107)
108/*-------------------------------------------------------------------------*\
109| Return Value:                                                             |
110|    rtems_status_code                                                      |
111\*=========================================================================*/
112{
113  rtems_status_code rc = RTEMS_SUCCESSFUL;
114  preemption_key_t preempt_key;
115  bool preempt_disabled = false;
116  /*
117   * disable preemption
118   */
119  if (rc == RTEMS_SUCCESSFUL) {
120    DISABLE_PREEMPTION(preempt_key);
121  }
122  /*
123   * follow node to its head
124   * XXX: this is highly dependent on the chain implementation
125   * in score/src/chain.c and friends
126   */
127  while (the_node->previous != NULL) {
128    the_node = the_node->previous;
129  }
130  /*
131   * reenable preemption, if disabled
132   */
133  if (preempt_disabled) {
134    ENABLE_PREEMPTION(preempt_key);
135  }
136  /*
137   * XXX: this depends n the chain implementation in
138   * score/include/rtems/score/chain.h:
139   * Chain_Control is overlayed by two Cohain_Nodes
140   */
141  *the_head = (Chain_Control *)the_node;
142
143  return rc;
144}
145
146/*=========================================================================*\
147| Function:                                                                 |
148\*-------------------------------------------------------------------------*/
149rtems_status_code rtems_bdbuf_show_determine_chain_of_bdbuf
150(
151/*-------------------------------------------------------------------------*\
152| Purpose:                                                                  |
153|   find out, which chain this bdbuf is linked in                           |
154+---------------------------------------------------------------------------+
155| Input Parameters:                                                         |
156\*-------------------------------------------------------------------------*/
157 const bdbuf_buffer *the_bdbuf,         /* this is the bdbuf structure     */
158 const bdbuf_pool   *curr_pool,         /* the pool this buffer belongs to */
159 bdbuf_chain_identifier_t *chn_ident    /* result: identifier for chain    */
160)
161/*-------------------------------------------------------------------------*\
162| Return Value:                                                             |
163|    rtems_status_code                                                      |
164\*=========================================================================*/
165{
166  rtems_status_code rc = RTEMS_SUCCESSFUL;
167  Chain_Control *the_chain_control;
168
169
170  *chn_ident = bdbuf_chain_ident_none;
171  if (rc == RTEMS_SUCCESSFUL) {
172    rc = rtems_bdbuf_show_follow_chain_node_to_head(&(the_bdbuf->link),
173                                                    &(the_chain_control));
174  }
175  if (rc == RTEMS_SUCCESSFUL) {
176    if (the_chain_control == &(curr_pool->free)) {
177      *chn_ident = bdbuf_chain_ident_free;
178    }
179    else if (the_chain_control == &(curr_pool->lru)) {
180      *chn_ident = bdbuf_chain_ident_lru;
181    }
182    else if (the_chain_control == &(rtems_bdbuf_ctx.mod)) {
183      *chn_ident = bdbuf_chain_ident_mod;
184    }
185  }
186  return rc;
187}
188
189/*=========================================================================*\
190| Function:                                                                 |
191\*-------------------------------------------------------------------------*/
192rtems_status_code rtems_bdbuf_show_getargs
193(
194/*-------------------------------------------------------------------------*\
195| Purpose:                                                                  |
196|   analyze cmd arguments                                                   |
197+---------------------------------------------------------------------------+
198| Input Parameters:                                                         |
199\*-------------------------------------------------------------------------*/
200    int     argc,
201    char  **argv,
202    show_bdbuf_filter_t *filter,
203    show_bdbuf_selector_t *selector
204)
205/*-------------------------------------------------------------------------*\
206| Return Value:                                                             |
207|    rtems_status_code                                                      |
208\*=========================================================================*/
209{
210  rtems_status_code sc = RTEMS_SUCCESSFUL;
211  int arg_error = 0;
212  int i;
213  char *tmp_ptr;
214  int nm_argc = 0;
215  /*
216   * set filter and selector to default
217   */
218  memset(filter,0,sizeof(*filter));
219  filter->bdbuf_all  = true;
220  memset(selector,0,sizeof(*selector));
221  selector->show_all = true;
222
223  /*
224   * scan arguments
225   */
226  for (i = 1;
227       (i < argc) && (arg_error == 0);
228       i++) {
229    if (argv[i][0] == '-') {
230      /*
231       * modifier arguments
232       */
233      switch(tolower(argv[i][1])) {
234        /*
235         * selection, which bdbufs to show
236         */
237      case 'm': /* only show bdbufs modified */
238        filter->bdbuf_modified = true ;
239        filter->bdbuf_all      = false;
240        break;
241      case 'i': /* only show bdbufs in progress*/
242        filter->bdbuf_in_progress = true ;
243        filter->bdbuf_all         = false;
244        break;
245      case 'v': /* only show bdbufs, which have valid data*/
246        filter->bdbuf_actual   = true ;
247        filter->bdbuf_all      = false;
248        break;
249      case 'u': /* only show bdbufs, which are in use */
250        filter->bdbuf_used     = true ;
251        filter->bdbuf_all      = false;
252        break;
253      case 'p': /* only show bdbufs, which belong to pool <n> */
254        filter->pool_id = strtol(argv[i]+2,&tmp_ptr,0);
255        if (tmp_ptr == argv[i]+2) { /* no conversion performed... */
256          arg_error = i;
257        }
258        filter->bdbuf_all      = false;
259        break;
260        /*
261         * selection, what fields to show
262         */
263      case 'n': /* show bdbuf node_chain */
264        selector->show_node_chain = true ;
265        selector->show_all        = false;
266        break;
267      case 'd': /* show device           */
268        selector->show_dev        = true ;
269        selector->show_all        = false;
270        break;
271      case 'b': /* show blocknum         */
272        selector->show_blocknum   = true ;
273        selector->show_all        = false;
274        break;
275      case 'e': /* show bdbuf error status */
276        selector->show_error      = true ;
277        selector->show_all        = false;
278        break;
279      case 's': /* show bdbuf state */
280        selector->show_state      = true ;
281        selector->show_all        = false;
282        break;
283      case 'c': /* show bdbuf use count */
284        selector->show_use_count  = true ;
285        selector->show_all        = false;
286        break;
287      case 'l': /* show bdbuf pool id   */
288        selector->show_pool_id    = true ;
289        selector->show_all        = false;
290        break;
291      case 't': /* show bdbuf transfer sema */
292        selector->show_sema       = true ;
293        break;
294      default:
295        arg_error = i;
296        break;
297      }
298    }
299    else {
300      /*
301       * non-modifier arguments
302       */
303      switch(++nm_argc) {
304      default: /* no further arguments defined */
305        arg_error = i;
306        break;
307      }
308    }
309  }
310  if (arg_error) {
311    printf("%s: unknown argument %s\n",argv[0],argv[arg_error]);
312    sc = RTEMS_NOT_DEFINED;
313  }
314  return sc;
315}
316
317/*=========================================================================*\
318| Function:                                                                 |
319\*-------------------------------------------------------------------------*/
320rtems_status_code rtems_bdbuf_show_get_bufpool
321(
322/*-------------------------------------------------------------------------*\
323| Purpose:                                                                  |
324|   get buffer pool information                                             |
325|   XXX: this should be coupled closer to the bdbuf.c module               |
326+---------------------------------------------------------------------------+
327| Input Parameters:                                                         |
328\*-------------------------------------------------------------------------*/
329 struct bdbuf_pool **pool_base_pptr,
330 int *pool_cnt_ptr
331)
332/*-------------------------------------------------------------------------*\
333| Return Value:                                                             |
334|    rtems_status_code                                                      |
335\*=========================================================================*/
336{
337  rtems_status_code rc = RTEMS_SUCCESSFUL;
338#if 0
339  rtems_status_code pool_rc = RTEMS_SUCCESSFUL;
340  struct bdbuf_pool *curr_pool,*pool_base, *pool_top;
341  int pool_cnt;
342  int pool_probe_size;
343  /*
344   * get first buffer pool
345   * XXX: this is highly dependent on how pools are defined
346   * and maintained in bdbuf.c
347   */
348  if (rc == RTEMS_SUCCESSFUL) {
349    /*
350     * try all possible pool sizes, get highest/lowest pool address
351     */
352    pool_base = NULL;
353    pool_top  = NULL;
354    curr_pool = NULL;
355    for (pool_probe_size = 1;
356         pool_probe_size < (INT_MAX>>1) && (pool_rc == RTEMS_SUCCESSFUL);
357         pool_probe_size <<= 1) {
358      pool_rc = rtems_bdbuf_find_pool(pool_probe_size,&curr_pool);
359      if (pool_rc == RTEMS_SUCCESSFUL) {
360        if (pool_base > curr_pool) {
361          pool_base = curr_pool;
362        }
363        if (pool_top < curr_pool) {
364          pool_top = curr_pool;
365        }
366      }
367    }
368    if (pool_base == NULL) {
369      rc = RTEMS_UNSATISFIED;
370    }
371    else {
372      pool_cnt = (pool_top - pool_base) + 1;
373    }
374  }
375  if (rc == RTEMS_SUCCESSFUL) {
376    *pool_base_pptr = pool_base;
377    *pool_cnt_ptr   = pool_cnt;
378  }
379#else
380  if (rc == RTEMS_SUCCESSFUL) {
381    *pool_base_pptr = rtems_bdbuf_ctx.pool;
382    *pool_cnt_ptr   = rtems_bdbuf_ctx.npools;
383  }
384#endif
385  return rc;
386}
387
388/*=========================================================================*\
389| Function:                                                                 |
390\*-------------------------------------------------------------------------*/
391rtems_status_code rtems_bdbuf_show_pool_header
392(
393/*-------------------------------------------------------------------------*\
394| Purpose:                                                                  |
395|   print buffer pool information                                           |
396+---------------------------------------------------------------------------+
397| Input Parameters:                                                         |
398\*-------------------------------------------------------------------------*/
399 int        pool_idx,
400 bdbuf_pool *pool_ptr
401)
402/*-------------------------------------------------------------------------*\
403| Return Value:                                                             |
404|    rtems_status_code                                                      |
405\*=========================================================================*/
406{
407
408  rtems_status_code rc = RTEMS_SUCCESSFUL;
409
410  if (rc == RTEMS_SUCCESSFUL) {
411    printf("------------------------------------------------------------------------------\n");
412    printf(" pool #%03d: blksize=%5u nblks=%5u buf_mem=0x%08" PRIxPTR " bdbuf_mem=0x%08" PRIxPTR "\n",
413           pool_idx,
414           pool_ptr->blksize,
415           pool_ptr->nblks,
416           (intptr_t) pool_ptr->mallocd_bufs,
417           (intptr_t) pool_ptr->bdbufs);
418    printf("------------------------------------------------------------------------------\n");
419  }
420  return rc;
421}
422
423/*=========================================================================*\
424| Function:                                                                 |
425\*-------------------------------------------------------------------------*/
426rtems_status_code rtems_show_bdbuf_get_bdbuf_info
427(
428/*-------------------------------------------------------------------------*\
429| Purpose:                                                                  |
430|   get buffer pool information                                             |
431|   XXX: this should be coupled closer to the bdbuf.c module                |
432+---------------------------------------------------------------------------+
433| Input Parameters:                                                         |
434\*-------------------------------------------------------------------------*/
435 const bdbuf_buffer *the_bdbuf,         /* this is the bdbuf structure     */
436 int           bdbuf_idx,               /* index of bdbuf                  */
437 const bdbuf_pool   *curr_pool,         /* the pool this buffer belongs to */
438 show_bdbuf_bdbuf_info_t *bdbuf_info    /* struct to  store info of bdbuf */
439)
440/*-------------------------------------------------------------------------*\
441| Return Value:                                                             |
442|    rtems_status_code                                                      |
443\*=========================================================================*/
444{
445
446  rtems_status_code rc = RTEMS_SUCCESSFUL;
447
448  /*
449   * determine the chain we are in
450   */
451  if (rc == RTEMS_SUCCESSFUL) {
452    rc = rtems_bdbuf_show_determine_chain_of_bdbuf(the_bdbuf,curr_pool,
453        &(bdbuf_info->in_chain));
454    if (rc != RTEMS_SUCCESSFUL) {
455      bdbuf_info->in_chain = bdbuf_chain_ident_none;
456      rc = RTEMS_SUCCESSFUL;
457    }
458  }
459
460  if (rc == RTEMS_SUCCESSFUL) {
461    bdbuf_info->index       = bdbuf_idx;
462    bdbuf_info->dev         = the_bdbuf->dev;
463    bdbuf_info->blknum      = the_bdbuf->block;
464    bdbuf_info->status      = the_bdbuf->status;
465    bdbuf_info->error       = the_bdbuf->error;
466    bdbuf_info->modified    = the_bdbuf->modified;
467    bdbuf_info->in_progress = the_bdbuf->in_progress;
468    bdbuf_info->actual      = the_bdbuf->actual;
469    bdbuf_info->use_count   = the_bdbuf->use_count;
470    bdbuf_info->sema        = &(the_bdbuf->transfer_sema);
471    bdbuf_info->pool_id     = the_bdbuf->pool;
472  }
473  return rc;
474}
475
476/*=========================================================================*\
477| Function:                                                                 |
478\*-------------------------------------------------------------------------*/
479rtems_status_code rtems_show_bdbuf_match_filter
480(
481/*-------------------------------------------------------------------------*\
482| Purpose:                                                                  |
483|   match bdbuf info with given filter                                      |
484+---------------------------------------------------------------------------+
485| Input Parameters:                                                         |
486\*-------------------------------------------------------------------------*/
487 const show_bdbuf_bdbuf_info_t *bdbuf_info, /* struct to  store info of bdbuf */
488 const show_bdbuf_filter_t *filter,
489 bool *is_match
490)
491/*-------------------------------------------------------------------------*\
492| Return Value:                                                             |
493|    rtems_status_code                                                      |
494\*=========================================================================*/
495{
496
497  rtems_status_code rc = RTEMS_SUCCESSFUL;
498  bool unmatch = false;
499
500  if (rc == RTEMS_SUCCESSFUL) {
501    if (filter->bdbuf_all) {
502      unmatch = false;
503    }
504    else {
505      unmatch = ((filter->bdbuf_modified    && !bdbuf_info->modified) ||
506                 (filter->bdbuf_in_progress && !bdbuf_info->in_progress) ||
507                 (filter->bdbuf_actual      && !bdbuf_info->actual) ||
508                 (filter->bdbuf_used        && !(bdbuf_info->use_count > 0)));
509
510    }
511    *is_match = !unmatch;
512  }
513  return rc;
514}
515
516/*=========================================================================*\
517| Function:                                                                 |
518\*-------------------------------------------------------------------------*/
519rtems_status_code rtems_show_bdbuf_print_wait_chain
520(
521/*-------------------------------------------------------------------------*\
522| Purpose:                                                                  |
523|   list tasks waiting in "transfer_sema" chain                             |
524+---------------------------------------------------------------------------+
525| Input Parameters:                                                         |
526\*-------------------------------------------------------------------------*/
527 bdbuf_buffer *the_bdbuf                /* this is the bdbuf structure     */
528)
529/*-------------------------------------------------------------------------*\
530| Return Value:                                                             |
531|    rtems_status_code                                                      |
532\*=========================================================================*/
533{
534  rtems_status_code rc = RTEMS_SUCCESSFUL;
535  Chain_Control *the_chain_head;
536  const Chain_Node    *the_chain_node;
537  int   thread_cnt = 0;
538  const Thread_Control *the_thread;
539  Objects_Id      thread_id;
540  Objects_Name    thread_name;
541  uint32_t        thread_name_nonstring;
542  /*
543   * get head of (fifo) wait chain
544   */
545  if (rc == RTEMS_SUCCESSFUL) {
546    the_chain_head = &(the_bdbuf->transfer_sema.Wait_queue.Queues.Fifo);
547    the_chain_node = _Chain_First(the_chain_head);
548  }
549  /*
550   * walk through thread chain
551   */
552  while ((rc == RTEMS_SUCCESSFUL) &&
553         (the_chain_node != _Chain_Tail( the_chain_head ))) {
554    thread_cnt++;
555    the_thread = (const Thread_Control *)the_chain_node;
556
557    thread_id   = the_thread->Object.id;
558    thread_name = the_thread->Object.name;
559    thread_name_nonstring = (uint32_t)thread_name.name_u32;
560    printf("%20s %3d (0x%08" PRIx32 ") %c%c%c%c\n",
561           ((thread_cnt == 1) ? "Threads waiting:" : ""),
562           thread_cnt,thread_id,
563           (char)((thread_name_nonstring >> 24) & 0xff),
564           (char)((thread_name_nonstring >> 16) & 0xff),
565           (char)((thread_name_nonstring >>  8) & 0xff),
566           (char)((thread_name_nonstring >>  0) & 0xff));
567
568    the_chain_node = the_chain_node->next;
569  }
570
571  return rc;
572}
573
574/*=========================================================================*\
575| Function:                                                                 |
576\*-------------------------------------------------------------------------*/
577rtems_status_code rtems_show_bdbuf_print
578(
579/*-------------------------------------------------------------------------*\
580| Purpose:                                                                  |
581|   print requested bdbuffer information                                    |
582+---------------------------------------------------------------------------+
583| Input Parameters:                                                         |
584\*-------------------------------------------------------------------------*/
585 const show_bdbuf_bdbuf_info_t *bdbuf_info, /* info of bdbuf               */
586 show_bdbuf_selector_t * selector,          /* selector, what to show      */
587 bool       print_header             /* true: print header, not info    */
588)
589/*-------------------------------------------------------------------------*\
590| Return Value:                                                             |
591|    rtems_status_code                                                      |
592\*=========================================================================*/
593{
594
595  rtems_status_code rc = RTEMS_SUCCESSFUL;
596
597  /*
598   * 6 chars: print index of buffer
599   */
600  if (rc == RTEMS_SUCCESSFUL) {
601    if (print_header) {
602      printf("INDEX ");
603    }
604    else {
605      printf("%5u ",bdbuf_info->index);
606    }
607  }
608  /*
609   * 3 chars: print info about the pool id of this buffer
610   */
611  if ((rc == RTEMS_SUCCESSFUL) &&
612      ((selector->show_all) ||
613       (selector->show_use_count))) {
614    if (print_header) {
615      printf("PL ");
616    }
617    else {
618      printf("%2u ",bdbuf_info->pool_id);
619    }
620  }
621
622  /*
623   * 4 chars: print info about chain (lru/free/mod) of this buffer
624   */
625  if ((rc == RTEMS_SUCCESSFUL) &&
626      ((selector->show_all) ||
627       (selector->show_node_chain))) {
628    if (print_header) {
629      printf("CHN ");
630    }
631    else {
632      printf("%3s ",
633             ((bdbuf_info->in_chain == bdbuf_chain_ident_free)  ? "FRE"
634              : (bdbuf_info->in_chain == bdbuf_chain_ident_lru) ? "LRU"
635              : (bdbuf_info->in_chain == bdbuf_chain_ident_mod) ? "MOD"
636              : "???"));
637    }
638  }
639
640  /*
641   * 7 chars: print info about device of this buffer
642   */
643  if ((rc == RTEMS_SUCCESSFUL) &&
644      ((selector->show_all) ||
645       (selector->show_dev))) {
646    if (print_header) {
647      printf("DEVICE ");
648    }
649    else {
650      printf("%3" PRIu32 "%2" PRIu32,
651             ((bdbuf_info->dev == -1)
652              ? 0 : rtems_filesystem_dev_major_t(bdbuf_info->dev)),
653             ((bdbuf_info->dev == -1)
654              ? 0 : rtems_filesystem_dev_minor_t(bdbuf_info->dev)));
655    }
656  }
657
658  /*
659   * 7 chars: print info about block number of this buffer
660   */
661  if ((rc == RTEMS_SUCCESSFUL) &&
662      ((selector->show_all) ||
663       (selector->show_blocknum))) {
664    if (print_header) {
665      printf("BLOCK  ");
666    }
667    else {
668      printf("%6" PRIu32,bdbuf_info->blknum);
669    }
670  }
671
672  /*
673   * 4 chars: print info about use count of this buffer
674   */
675  if ((rc == RTEMS_SUCCESSFUL) &&
676      ((selector->show_all) ||
677       (selector->show_use_count))) {
678    if (print_header) {
679      printf("USE ");
680    }
681    else {
682      printf("%3u ",bdbuf_info->use_count);
683    }
684  }
685
686  /*
687   * 4 chars: print info about state of this buffer
688   */
689  if ((rc == RTEMS_SUCCESSFUL) &&
690      ((selector->show_all) ||
691       (selector->show_state))) {
692    if (print_header) {
693      printf("STA ");
694    }
695    else {
696      printf("%c%c%c ",
697             (bdbuf_info->modified    ? 'M' : '.'),
698             (bdbuf_info->in_progress ? 'P' : '.'),
699             (bdbuf_info->actual      ? 'A' : '.'));
700    }
701  }
702
703  /*
704   * 42 chars: print info about error of this buffer
705   */
706  if ((rc == RTEMS_SUCCESSFUL) &&
707      ((selector->show_all) ||
708       (selector->show_error))) {
709    if (print_header) {
710      printf("%20s:%-10s ","RTEMS STATUS","ERRNO");
711    }
712    else {
713      printf("%20s:%-10s ",
714             ((bdbuf_info->status == RTEMS_SUCCESSFUL)
715              ? "SUCCESSFUL" : rtems_status_text(bdbuf_info->status)),
716             ((bdbuf_info->status == RTEMS_SUCCESSFUL)
717              ? "" : strerror(bdbuf_info->error)));
718    }
719  }
720  /*
721   * FIXME: add info about waiting chain
722   */
723  printf("\n");
724  return rc;
725}
726
727/*=========================================================================*\
728| Function:                                                                 |
729\*-------------------------------------------------------------------------*/
730void rtems_bdbuf_show_fnc
731(
732/*-------------------------------------------------------------------------*\
733| Purpose:                                                                  |
734|   list all bdbufs with their content                                      |
735+---------------------------------------------------------------------------+
736| Input Parameters:                                                         |
737\*-------------------------------------------------------------------------*/
738    int     argc,
739    char  **argv,
740    rtems_monitor_command_arg_t* command_arg,
741    bool verbose
742)
743/*-------------------------------------------------------------------------*\
744| Return Value:                                                             |
745|    rtems_status_code                                                      |
746\*=========================================================================*/
747{
748  rtems_status_code rc = RTEMS_SUCCESSFUL;
749  show_bdbuf_filter_t   filter;
750  show_bdbuf_selector_t selector;
751  show_bdbuf_bdbuf_info_t bdbuf_info;
752
753  bdbuf_pool *curr_pool,*pool_base;
754  int pool_cnt,pool_idx;
755  int bdbuf_idx;
756  bool bdbuf_matches;
757  int matched_cnt,un_matched_cnt;
758
759  /*
760   * analyze command line options
761   */
762  if (rc == RTEMS_SUCCESSFUL) {
763    rc = rtems_bdbuf_show_getargs (argc,argv,
764                                   &filter,&selector);
765  }
766
767  /*
768   * get buffer pool information
769   */
770  if (rc == RTEMS_SUCCESSFUL) {
771    rc = rtems_bdbuf_show_get_bufpool(&pool_base,&pool_cnt);
772    if (rc != RTEMS_SUCCESSFUL) {
773      printf("%s: ERROR: no buffer pool found\n",argv[0]);
774    }
775  }
776  /*
777   * for all or selected buffer pool(s)
778   */
779  for (pool_idx = 0;
780       (rc == RTEMS_SUCCESSFUL) && (pool_idx < pool_cnt);
781       pool_idx++) {
782    if ((filter.pool_id < 0) ||
783        (filter.pool_id == pool_idx)) {
784      curr_pool = pool_base + pool_idx;
785      /*
786       * print pool header
787       */
788      if (rc == RTEMS_SUCCESSFUL) {
789        rc = rtems_bdbuf_show_pool_header(pool_idx,curr_pool);
790      }
791      if (rc == RTEMS_SUCCESSFUL) {
792        matched_cnt = 0;
793        un_matched_cnt = 0;
794        /*
795         * print header for bdbuf
796         */
797          if (rc == RTEMS_SUCCESSFUL) {
798            rc = rtems_show_bdbuf_print(NULL,&selector,
799                                        true);
800          }
801        /*
802         * for all bdbufs in this pool
803         */
804        for (bdbuf_idx = 0;
805             ((rc == RTEMS_SUCCESSFUL) &&
806              (bdbuf_idx < curr_pool->nblks));
807             bdbuf_idx++) {
808          /*
809           * get infos about bdbuf
810           */
811          if (rc == RTEMS_SUCCESSFUL) {
812            rc = rtems_show_bdbuf_get_bdbuf_info
813              (&(curr_pool->bdbufs[bdbuf_idx]),
814               bdbuf_idx,
815               curr_pool,
816               &bdbuf_info);
817          }
818          /*
819           * check, if bdbuf matches selection criteria
820           */
821          if (rc == RTEMS_SUCCESSFUL) {
822            rc = rtems_show_bdbuf_match_filter(&bdbuf_info,&filter,
823                                               &bdbuf_matches);
824          }
825          /*
826           * print info about bdbuf
827           */
828          if (rc == RTEMS_SUCCESSFUL) {
829            if (bdbuf_matches) {
830              rc = rtems_show_bdbuf_print(&bdbuf_info,&selector,
831                                          false);
832              if ((rc == RTEMS_SUCCESSFUL) &&
833                  selector.show_sema) {
834                rc = rtems_show_bdbuf_print_wait_chain(&(curr_pool->bdbufs[bdbuf_idx]));
835              }
836              matched_cnt++;
837            }
838            else {
839              un_matched_cnt++;
840            }
841          }
842        }
843        /*
844         * print match statistics and footer
845         */
846        if (rc == RTEMS_SUCCESSFUL) {
847          printf("%d bdbufs printed, %d bdbufs suppressed\n",
848                 matched_cnt,un_matched_cnt);
849        }
850      }
851    }
852  }
853}
854
855static rtems_monitor_command_entry_t rtems_show_bdbuf_cmds[] = {
856  {
857    "bdbuf_show",
858    "usage: bdbuf_show\n",
859    0,
860    rtems_bdbuf_show_fnc,
861    { 0 },
862    0
863  }
864};
865
866#ifndef ARRAY_CNT
867#define ARRAY_CNT(arr) (sizeof((arr))/sizeof((arr)[0]))
868#endif
869
870/*=========================================================================*\
871| Function:                                                                 |
872\*-------------------------------------------------------------------------*/
873rtems_status_code rtems_bdbuf_show_init
874(
875/*-------------------------------------------------------------------------*\
876| Purpose:                                                                  |
877|   add command(s) to monitor                                               |
878+---------------------------------------------------------------------------+
879| Input Parameters:                                                         |
880\*-------------------------------------------------------------------------*/
881 void /* none up to now */
882)
883/*-------------------------------------------------------------------------*\
884| Return Value:                                                             |
885|    rtems_status_code                                                      |
886\*=========================================================================*/
887{
888  rtems_status_code sc = RTEMS_SUCCESSFUL;
889  int item;
890
891  for (item = 0;
892       (sc == RTEMS_SUCCESSFUL) && (item < ARRAY_CNT(rtems_show_bdbuf_cmds));
893       item++) {
894    if (0 == rtems_monitor_insert_cmd (&rtems_show_bdbuf_cmds[item])) {
895      sc = RTEMS_INVALID_NAME;
896    }
897  }
898  return sc;
899}
Note: See TracBrowser for help on using the repository browser.