source: rtems/cpukit/libmisc/monitor/mon-object.c

Last change on this file was e4cc56a7, checked in by Joel Sherrill <joel@…>, on 03/24/22 at 17:37:47

cpukit/libmisc/monitor/: Manually change to BSD-2 license

This code did not have any copyrights or licenses and a bit
of archeology was needed to determine authorship.

This code was in the initial import into the RTEMS CVS repository when
it was established in May 1995. There was very little, if any, code not
written by OAR Corporation in that initial import. After discussion
with Chris Johns, it was determined that this code was from OAR
Corporation and that he had added a few features later. Both
Chris Johns and OAR Corporation have given permission to relicense.

Updates #3053.

  • Property mode set to 100644
File size: 14.0 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @brief RTEMS Monitor "object" support.
7 *
8 * Used to traverse object lists and print them out.
9 * An object can be an RTEMS object (chain based stuff) or
10 * a "misc" object such as a device driver.
11 *
12 * Each object has its own file in this directory (eg: extension.c)
13 * That file provides routines to convert a "native" structure
14 * to its canonical form, print a canonical structure, etc.
15 *
16 * TODO:
17 *     should allow for non-numeric id's???
18 */
19
20/*
21 * COPYRIGHT (c) 1989-2022. On-Line Applications Research Corporation (OAR).
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the above copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
36 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGE.
43 */
44
45#ifdef HAVE_CONFIG_H
46#include "config.h"
47#endif
48
49#include <rtems.h>
50#include <rtems/monitor.h>
51#include <rtems/extensionimpl.h>
52#include <rtems/rtems/messageimpl.h>
53#include <rtems/rtems/partimpl.h>
54#include <rtems/rtems/regionimpl.h>
55#include <rtems/rtems/semimpl.h>
56#include <rtems/rtems/tasksimpl.h>
57#include <rtems/posix/pthreadimpl.h>
58
59#include <stdio.h>
60#include <stdlib.h>             /* strtoul() */
61#include <string.h>             /* memcpy() */
62
63#define NUMELEMS(arr)   (sizeof(arr) / sizeof(arr[0]))
64
65/*
66 * add:
67 *     next
68 */
69
70static const rtems_monitor_object_info_t rtems_monitor_object_info[] =
71{
72    { RTEMS_MONITOR_OBJECT_CONFIG,
73      (void *) 0,
74      sizeof(rtems_monitor_config_t),
75      (rtems_monitor_object_next_fn)        rtems_monitor_config_next,
76      (rtems_monitor_object_canonical_fn)   rtems_monitor_config_canonical,
77      (rtems_monitor_object_dump_header_fn) rtems_monitor_config_dump_header,
78      (rtems_monitor_object_dump_fn)        rtems_monitor_config_dump,
79    },
80    { RTEMS_MONITOR_OBJECT_MPCI,
81      (void *) 0,
82#if defined(RTEMS_MULTIPROCESSING)
83      sizeof(rtems_monitor_mpci_t),
84      (rtems_monitor_object_next_fn)        rtems_monitor_mpci_next,
85      (rtems_monitor_object_canonical_fn)   rtems_monitor_mpci_canonical,
86      (rtems_monitor_object_dump_header_fn) rtems_monitor_mpci_dump_header,
87      (rtems_monitor_object_dump_fn)        rtems_monitor_mpci_dump,
88#else
89      0,
90      (rtems_monitor_object_next_fn)        0,
91      (rtems_monitor_object_canonical_fn)   0,
92      (rtems_monitor_object_dump_header_fn) 0,
93      (rtems_monitor_object_dump_fn)        0,
94#endif
95    },
96    { RTEMS_MONITOR_OBJECT_INIT_TASK,
97      (void *) 0,
98      sizeof(rtems_monitor_init_task_t),
99      (rtems_monitor_object_next_fn)        rtems_monitor_init_task_next,
100      (rtems_monitor_object_canonical_fn)   rtems_monitor_init_task_canonical,
101      (rtems_monitor_object_dump_header_fn) rtems_monitor_init_task_dump_header,
102      (rtems_monitor_object_dump_fn)        rtems_monitor_init_task_dump,
103    },
104    { RTEMS_MONITOR_OBJECT_TASK,
105      (void *) &_RTEMS_tasks_Information.Objects,
106      sizeof(rtems_monitor_task_t),
107      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
108      (rtems_monitor_object_canonical_fn)   rtems_monitor_task_canonical,
109      (rtems_monitor_object_dump_header_fn) rtems_monitor_task_dump_header,
110      (rtems_monitor_object_dump_fn)        rtems_monitor_task_dump,
111    },
112    { RTEMS_MONITOR_OBJECT_QUEUE,
113      (void *) &_Message_queue_Information,
114      sizeof(rtems_monitor_queue_t),
115      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
116      (rtems_monitor_object_canonical_fn)   rtems_monitor_queue_canonical,
117      (rtems_monitor_object_dump_header_fn) rtems_monitor_queue_dump_header,
118      (rtems_monitor_object_dump_fn)        rtems_monitor_queue_dump,
119    },
120    { RTEMS_MONITOR_OBJECT_SEMAPHORE,
121      (void *) &_Semaphore_Information,
122      sizeof(rtems_monitor_sema_t),
123      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
124      (rtems_monitor_object_canonical_fn)   rtems_monitor_sema_canonical,
125      (rtems_monitor_object_dump_header_fn) rtems_monitor_sema_dump_header,
126      (rtems_monitor_object_dump_fn)        rtems_monitor_sema_dump,
127    },
128    { RTEMS_MONITOR_OBJECT_REGION,
129      (void *) &_Region_Information,
130      sizeof(rtems_monitor_region_t),
131      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
132      (rtems_monitor_object_canonical_fn)   rtems_monitor_region_canonical,
133      (rtems_monitor_object_dump_header_fn) rtems_monitor_region_dump_header,
134      (rtems_monitor_object_dump_fn)        rtems_monitor_region_dump,
135    },
136    { RTEMS_MONITOR_OBJECT_PARTITION,
137      (void *) &_Partition_Information,
138      sizeof(rtems_monitor_part_t),
139      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
140      (rtems_monitor_object_canonical_fn)   rtems_monitor_part_canonical,
141      (rtems_monitor_object_dump_header_fn) rtems_monitor_part_dump_header,
142      (rtems_monitor_object_dump_fn)        rtems_monitor_part_dump,
143    },
144    { RTEMS_MONITOR_OBJECT_EXTENSION,
145      (void *) &_Extension_Information,
146      sizeof(rtems_monitor_extension_t),
147      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
148      (rtems_monitor_object_canonical_fn)   rtems_monitor_extension_canonical,
149      (rtems_monitor_object_dump_header_fn) rtems_monitor_extension_dump_header,
150      (rtems_monitor_object_dump_fn)        rtems_monitor_extension_dump,
151    },
152    { RTEMS_MONITOR_OBJECT_DRIVER,
153      (void *) 0,
154      sizeof(rtems_monitor_driver_t),
155      (rtems_monitor_object_next_fn)        rtems_monitor_driver_next,
156      (rtems_monitor_object_canonical_fn)   rtems_monitor_driver_canonical,
157      (rtems_monitor_object_dump_header_fn) rtems_monitor_driver_dump_header,
158      (rtems_monitor_object_dump_fn)        rtems_monitor_driver_dump,
159    },
160    { RTEMS_MONITOR_OBJECT_PTHREAD,
161      (void *) &_POSIX_Threads_Information.Objects,
162      sizeof(rtems_monitor_task_t),
163      (rtems_monitor_object_next_fn)        rtems_monitor_manager_next,
164      (rtems_monitor_object_canonical_fn)   rtems_monitor_task_canonical,
165      (rtems_monitor_object_dump_header_fn) rtems_monitor_task_dump_header,
166      (rtems_monitor_object_dump_fn)        rtems_monitor_task_dump,
167    }
168};
169
170/*
171 * Allow id's to be specified without the node number or
172 * type for convenience.
173 */
174
175rtems_id
176rtems_monitor_id_fixup(
177    rtems_id            id,
178    uint32_t            default_node,
179    rtems_monitor_object_type_t type
180)
181{
182    uint32_t    node;
183
184    node = rtems_object_id_get_node(id);
185    if (node == 0)
186    {
187        if (rtems_object_id_get_class(id) != OBJECTS_CLASSIC_NO_CLASS)
188            type = rtems_object_id_get_class(id);
189
190        id = rtems_build_id(
191          OBJECTS_CLASSIC_API,
192          type,
193          default_node,
194          rtems_object_id_get_index(id)
195        );
196    }
197    return id;
198}
199
200
201const rtems_monitor_object_info_t *
202rtems_monitor_object_lookup(
203    rtems_monitor_object_type_t type
204)
205{
206    const rtems_monitor_object_info_t *p;
207    for (p = &rtems_monitor_object_info[0];
208         p < &rtems_monitor_object_info[NUMELEMS(rtems_monitor_object_info)];
209         p++)
210    {
211        if (p->type == type)
212            return p;
213    }
214    return 0;
215}
216
217#if defined(RTEMS_MULTIPROCESSING)
218static rtems_id
219rtems_monitor_object_canonical_next_remote(
220    rtems_monitor_object_type_t type,
221    rtems_id            id,
222    void               *canonical
223)
224{
225    rtems_id                        next_id;
226    rtems_status_code               status;
227    rtems_monitor_server_request_t  request;
228    rtems_monitor_server_response_t response;
229
230    /*
231     * Send request
232     */
233
234    request.command = RTEMS_MONITOR_SERVER_CANONICAL;
235    request.argument0 = (uint32_t) type;
236    request.argument1 = (uint32_t) id;
237
238    status = rtems_monitor_server_request(
239      rtems_object_id_get_node(id), &request, &response);
240    if (status != RTEMS_SUCCESSFUL)
241        goto failed;
242
243    /*
244     * process response
245     */
246
247    next_id = (rtems_id) response.result0;
248    if (next_id != RTEMS_OBJECT_ID_FINAL)
249        (void) memcpy(canonical, &response.payload, response.result1);
250
251    return next_id;
252
253failed:
254    return RTEMS_OBJECT_ID_FINAL;
255
256}
257#endif
258
259
260rtems_id
261rtems_monitor_object_canonical_next(
262    const rtems_monitor_object_info_t *info,
263    rtems_id                     id,
264    void                        *canonical
265)
266{
267  rtems_id    next_id;
268  const void *raw_item;
269
270#if defined(RTEMS_MULTIPROCESSING)
271    if ( ! _Objects_Is_local_id(id) ) {
272       next_id = rtems_monitor_object_canonical_next_remote(
273         info->type,
274         id,
275         canonical
276      );
277    } else
278#endif
279    {
280      next_id = id;
281
282      raw_item = info->next(
283        info->object_information,
284        canonical,
285        &next_id
286      );
287
288     if (raw_item) {
289       info->canonical(canonical, raw_item);
290       _Objects_Allocator_unlock();
291     }
292  }
293  return next_id;
294}
295
296
297/*
298 * this is routine server invokes locally to get the type
299 */
300
301rtems_id
302rtems_monitor_object_canonical_get(
303    rtems_monitor_object_type_t  type,
304    rtems_id             id,
305    void                *canonical,
306    size_t              *size_p
307)
308{
309    const rtems_monitor_object_info_t *info;
310    rtems_id                     next_id;
311
312    *size_p = 0;
313
314    info = rtems_monitor_object_lookup(type);
315
316    if (info == 0)
317        return RTEMS_OBJECT_ID_FINAL;
318
319    next_id = rtems_monitor_object_canonical_next(info, id, canonical);
320    *size_p = info->size;
321
322    return next_id;
323}
324
325
326static void
327rtems_monitor_object_dump_1(
328    const rtems_monitor_object_info_t *info,
329    rtems_id                     id,
330    bool                         verbose
331)
332{
333    rtems_id next_id;
334    rtems_monitor_union_t canonical;
335
336    if ((next_id = rtems_monitor_object_canonical_next(
337                                     info,
338                                     id,
339                                     &canonical)) != RTEMS_OBJECT_ID_FINAL)
340    {
341        /*
342         * If the one we actually got is the one we wanted, then
343         * print it out.
344         * For ones that have an id field, this works fine,
345         * for all others, always dump it out.
346         *
347         * HACK: the way we determine whether there is an id is a hack.
348         *
349         * by the way: the reason we try to not have an id, is that some
350         *   of the canonical structures are almost too big for shared
351         *   memory driver (eg: mpci)
352         */
353
354        if ((info->next != rtems_monitor_manager_next) ||
355            (id == canonical.generic.id))
356            info->dump(&canonical, verbose);
357    }
358}
359
360static void
361rtems_monitor_object_dump_all(
362    const rtems_monitor_object_info_t *info,
363    bool                         verbose
364)
365{
366    rtems_id next_id;
367    rtems_monitor_union_t canonical;
368
369    next_id = RTEMS_OBJECT_ID_INITIAL(OBJECTS_CLASSIC_API, info->type, rtems_monitor_default_node);
370
371    while ((next_id = rtems_monitor_object_canonical_next(
372                                         info,
373                                         next_id,
374                                         &canonical)) != RTEMS_OBJECT_ID_FINAL)
375    {
376        info->dump(&canonical, verbose);
377    }
378}
379
380void
381rtems_monitor_object_cmd(
382    int                                argc,
383    char                             **argv,
384    const rtems_monitor_command_arg_t *command_arg,
385    bool                               verbose
386)
387{
388    int arg;
389    const rtems_monitor_object_info_t *info = 0;
390    rtems_monitor_object_type_t  type;
391
392    /* what is the default type? */
393    type = command_arg->monitor_object;
394
395    if (argc == 1)
396    {
397        if (type == RTEMS_MONITOR_OBJECT_INVALID)
398        {
399            fprintf(stdout,"A type must be specified to \"dump all\"\n");
400            goto done;
401        }
402
403        info = rtems_monitor_object_lookup(type);
404        if (info == 0)
405            goto not_found;
406
407        if (info->dump_header)
408            info->dump_header(verbose);
409        rtems_monitor_object_dump_all(info, verbose);
410    }
411    else
412    {
413        uint32_t            default_node = rtems_monitor_default_node;
414        rtems_monitor_object_type_t last_type = RTEMS_MONITOR_OBJECT_INVALID;
415        rtems_id            id;
416
417        for (arg=1; argv[arg]; arg++)
418        {
419            id = (rtems_id) strtoul(argv[arg], 0, 16);
420            id = rtems_monitor_id_fixup(id, default_node, type);
421            type = (rtems_monitor_object_type_t) rtems_object_id_get_class(id);
422
423            /*
424             * Allow the item type to change in the middle
425             * of the command.  If the type changes, then
426             * just dump out a new header and keep on going.
427             */
428            if (type != last_type)
429            {
430                info = rtems_monitor_object_lookup(type);
431                if (info == 0)
432                    goto not_found;
433
434                if (info->dump_header)
435                    info->dump_header(verbose);
436            }
437
438            if (info == 0)
439            {
440not_found:      fprintf(stdout,"Invalid or unsupported type %d\n", type);
441                goto done;
442            }
443
444            rtems_monitor_object_dump_1(info, id, verbose);
445
446            default_node = rtems_object_id_get_node(id);
447
448            last_type = type;
449        }
450    }
451done:
452    return;
453}
Note: See TracBrowser for help on using the repository browser.