source: rtems/c/src/lib/libmisc/monitor/mon-server.c @ 0836603

4.104.114.84.95
Last change on this file since 0836603 was be95da0, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 18, 1996 at 8:55:13 PM

casts added to numerous arguments, prototypes corrected, and
proper include files added.

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