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

5
Last change on this file since df91dd9 was df91dd9, checked in by Sebastian Huber <sebastian.huber@…>, on 03/14/16 at 11:31:12

monitor: Use object allocator lock

Use object allocator lock instead of disabled thread dispatching.

Update #2555.

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