source: rtems/cpukit/libblock/src/show_bdbuf.c @ 6d612944

4.104.115
Last change on this file since 6d612944 was 4f971343, checked in by Ralf Corsepius <ralf.corsepius@…>, on 09/01/08 at 07:44:48

Convert to using "bool".

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