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

5
Last change on this file since d7665823 was d7665823, checked in by Sebastian Huber <sebastian.huber@…>, on 06/24/15 at 13:43:19

score: Introduce Thread_queue_Heads

Move the storage for the thread queue heads to the threads. Each thread
provides a set of thread queue heads allocated from a dedicated memory
pool. In case a thread blocks on a queue, then it lends its heads to
the queue. In case the thread unblocks, then it takes a free set of
threads from the queue. Since a thread can block on at most one queue
this works. This mechanism is used in FreeBSD. The motivation for this
change is to reduce the memory demands of the synchronization objects.
On a 32-bit uni-processor configuration the Thread_queue_Control size is
now 8 bytes, compared to 64 bytes in RTEMS 4.10 (other changes reduced
the size as well).

  • 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       _Thread_Enable_dispatch();
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.