source: rtems/cpukit/libmisc/monitor/mon-server.c @ f004b2b8

5
Last change on this file since f004b2b8 was f004b2b8, checked in by Sebastian Huber <sebastian.huber@…>, on 10/02/18 at 08:22:15

Use rtems_task_exit()

Update #3530.
Update #3533.

  • Property mode set to 100644
File size: 8.9 KB
Line 
1/*
2 * RTEMS monitor server (handles requests for info from RTEMS monitors
3 *             running on other nodes)
4 */
5
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif
9
10#include <rtems.h>
11
12#include <stdio.h>
13#include <string.h>
14#include <stdlib.h>
15#include <unistd.h>
16
17#include <rtems/monitor.h>
18#include <rtems/score/sysstate.h>
19
20/*
21 * Various id's for the server
22 */
23
24rtems_id  rtems_monitor_server_task_id;
25rtems_id  rtems_monitor_server_request_queue_id;        /* our server */
26rtems_id *rtems_monitor_server_request_queue_ids;       /* all servers */
27rtems_id  rtems_monitor_server_response_queue_id;       /* our server */
28
29
30/*
31 * Send a request to a server task
32 */
33
34rtems_status_code
35rtems_monitor_server_request(
36    uint32_t                         server_node,
37    rtems_monitor_server_request_t  *request,
38    rtems_monitor_server_response_t *response
39)
40{
41    rtems_id          server_id;
42    rtems_status_code status;
43    size_t            size;
44
45    /*
46     * What is id of monitor on target node?
47     * Look it up if we don't know it yet.
48     */
49
50    server_id = rtems_monitor_server_request_queue_ids[server_node];
51    if (server_id == 0)
52    {
53        status = rtems_message_queue_ident(RTEMS_MONITOR_QUEUE_NAME,
54                                           server_node,
55                                           &server_id);
56        if (status != RTEMS_SUCCESSFUL)
57        {
58            rtems_error(status, "ident of remote server failed");
59            goto done;
60        }
61
62        rtems_monitor_server_request_queue_ids[server_node] = server_id;
63    }
64
65    request->return_id = rtems_monitor_server_response_queue_id;
66
67    status = rtems_message_queue_send(server_id, request, sizeof(*request));
68    if (status != RTEMS_SUCCESSFUL)
69    {
70        rtems_error(status, "monitor server request send failed");
71        goto done;
72    }
73
74    /*
75     * Await response, if requested
76     */
77
78    if (response)
79    {
80        status = rtems_message_queue_receive(rtems_monitor_server_response_queue_id,
81                                             response,
82                                             &size,
83                                             RTEMS_WAIT,
84                                             100);
85        if (status != RTEMS_SUCCESSFUL)
86        {
87            rtems_error(status, "server did not respond");
88
89            /* maybe server task was restarted; look it up again next time */
90            rtems_monitor_server_request_queue_ids[server_node] = 0;
91
92            goto done;
93        }
94
95        if (response->command != RTEMS_MONITOR_SERVER_RESPONSE)
96        {
97            status = RTEMS_INCORRECT_STATE;
98            goto done;
99        }
100    }
101
102done:
103    return status;
104}
105
106
107
108/*
109 * monitor server task
110 */
111
112void
113rtems_monitor_server_task(
114    rtems_task_argument monitor_flags RTEMS_UNUSED
115)
116{
117    rtems_monitor_server_request_t  request;
118    rtems_monitor_server_response_t response;
119    rtems_status_code               status;
120    size_t                          size;
121
122    for (;;)
123    {
124        status = rtems_message_queue_receive(
125                        rtems_monitor_server_request_queue_id,
126                        &request,
127                        &size,
128                        RTEMS_WAIT,
129                        (rtems_interval) 0);
130
131        if (status != RTEMS_SUCCESSFUL)
132        {
133            rtems_error(status, "monitor server msg queue receive error");
134            goto failed;
135        }
136
137        if (size != sizeof(request))
138        {
139            rtems_error(0, "monitor server bad size on receive");
140            goto failed;
141        }
142
143        switch (request.command)
144        {
145            case RTEMS_MONITOR_SERVER_CANONICAL:
146            {
147                rtems_monitor_object_type_t object_type;
148                rtems_id            id;
149                rtems_id            next_id;
150
151                object_type = (rtems_monitor_object_type_t) request.argument0;
152                id          = (rtems_id)            request.argument1;
153                next_id = rtems_monitor_object_canonical_get(object_type,
154                                                             id,
155                                                             &response.payload,
156                                                             &size);
157
158                response.command = RTEMS_MONITOR_SERVER_RESPONSE;
159                response.result0 = next_id;
160                response.result1 = size;
161
162#define SERVER_OVERHEAD  (offsetof(rtems_monitor_server_response_t, \
163                                         payload))
164
165                status = rtems_message_queue_send(request.return_id,
166                                                  &response,
167                                                  size + SERVER_OVERHEAD);
168                if (status != RTEMS_SUCCESSFUL)
169                {
170                    rtems_error(status, "response send failed");
171                    goto failed;
172                }
173                break;
174            }
175
176            default:
177            {
178                rtems_error(0, "invalid command to monitor server: %d", request.command);
179                goto failed;
180            }
181        }
182    }
183
184failed:
185    rtems_task_exit();
186}
187
188
189/*
190 * Kill off any old server
191 * Not sure if this is useful, but it doesn't help
192 */
193
194void
195rtems_monitor_server_kill(void)
196{
197    if (rtems_monitor_server_task_id)
198        rtems_task_delete(rtems_monitor_server_task_id);
199    rtems_monitor_server_task_id = 0;
200
201    if (rtems_monitor_server_request_queue_id)
202        rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
203    rtems_monitor_server_request_queue_ids = 0;
204
205    if (rtems_monitor_server_response_queue_id)
206        rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
207    rtems_monitor_server_response_queue_id = 0;
208
209    if (rtems_monitor_server_request_queue_ids)
210        free(rtems_monitor_server_request_queue_ids);
211    rtems_monitor_server_request_queue_ids = 0;
212}
213
214
215void
216rtems_monitor_server_init(
217    uint32_t   monitor_flags RTEMS_UNUSED
218)
219{
220    #if defined(RTEMS_MULTIPROCESSING)
221    rtems_status_code status;
222
223    if (_System_state_Is_multiprocessing    &&
224        (_Configuration_MP_table->maximum_nodes > 1))
225    {
226        uint32_t   maximum_nodes = _Configuration_MP_table->maximum_nodes;
227
228        /*
229         * create the msg que our server will listen
230         * Since we only get msgs from other RTEMS monitors, we just
231         * need reserve space for 1 msg from each node.
232         */
233
234        status = rtems_message_queue_create(
235                       RTEMS_MONITOR_QUEUE_NAME,
236                       maximum_nodes,
237                       sizeof(rtems_monitor_server_request_t),
238                       RTEMS_GLOBAL,
239                       &rtems_monitor_server_request_queue_id);
240
241        if (status != RTEMS_SUCCESSFUL)
242        {
243            rtems_error(status, "could not create monitor server message queue");
244            goto done;
245        }
246
247        /*
248         * create the msg que our responses will come on
249         * Since monitor just does one thing at a time, we only need 1 item
250         * message queue.
251         */
252
253        status = rtems_message_queue_create(
254                       RTEMS_MONITOR_RESPONSE_QUEUE_NAME,
255                       1, /* depth */
256                       sizeof(rtems_monitor_server_response_t),
257                       RTEMS_GLOBAL,
258                       &rtems_monitor_server_response_queue_id);
259
260        if (status != RTEMS_SUCCESSFUL)
261        {
262            rtems_error(status, "could not create monitor response message queue");
263            goto done;
264        }
265
266        /* need an id for queue of each other server we might talk to */
267        /* indexed by node, so add 1 to maximum_nodes */
268        rtems_monitor_server_request_queue_ids =
269                   (rtems_id *) malloc((maximum_nodes + 1) * sizeof(rtems_id));
270        (void) memset(rtems_monitor_server_request_queue_ids,
271                      0,
272                      (maximum_nodes + 1) * sizeof(rtems_id));
273
274        rtems_monitor_server_request_queue_ids[rtems_monitor_node] =
275                   rtems_monitor_server_request_queue_id;
276
277        /*
278         * create the server task
279         */
280        status = rtems_task_create(RTEMS_MONITOR_SERVER_NAME,
281                                   1,
282                                   0 /* default stack */,
283                                   RTEMS_INTERRUPT_LEVEL(0),
284                                   RTEMS_DEFAULT_ATTRIBUTES,
285                                   &rtems_monitor_server_task_id);
286        if (status != RTEMS_SUCCESSFUL)
287        {
288            rtems_error(status, "could not create monitor server task");
289            goto done;
290        }
291
292        /*
293         * Start the server task
294         */
295        status = rtems_task_start(rtems_monitor_server_task_id,
296                                  rtems_monitor_server_task,
297                                  monitor_flags);
298        if (status != RTEMS_SUCCESSFUL)
299        {
300            rtems_error(status, "could not start monitor server");
301            goto done;
302        }
303    }
304
305done:
306    #endif
307    return;
308}
Note: See TracBrowser for help on using the repository browser.