source: rtems/cpukit/libblock/src/show_bdbuf.c @ f381e9b

Last change on this file since f381e9b was f381e9b, checked in by Joel Sherrill <joel@…>, on 02/17/22 at 15:47:33

cpukit/libblock: Change license to BSD-2

Updates #3053.

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