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

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

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