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

Last change on this file was 54f35888, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 25, 2018 at 8:54:12 AM

posix: Provide threads by default

Update #2514.

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