Files
rtems/cpukit/libmisc/monitor/mon-server.c
Joel Sherrill 3a4ae6c210 The word "RTEMS" almost completely removed from the core.
Configuration Table Template file added and all tests
modified to use this.  All gvar.h and conftbl.h files
removed from test directories.

Configuration parameter maximum_devices added.

Core semaphore and mutex handlers added and RTEMS API Semaphore
Manager updated to reflect this.

Initialization sequence changed to invoke API specific initialization
routines.  Initialization tasks table now owned by RTEMS Tasks Manager.

Added user extension for post-switch.

Utilized user extensions to implement API specific functionality
like signal dispatching.

Added extensions to the System Initialization Thread so that an
API can register a function to be invoked while the system
is being initialized.  These are largely equivalent to the
pre-driver and post-driver hooks.

Added the Modules file oar-go32_p5, modified oar-go32, and modified
the file make/custom/go32.cfg to look at an environment varable which
determines what CPU model is being used.

All BSPs updated to reflect named devices and clock driver's IOCTL
used by the Shared Memory Driver.  Also merged clock isr into
main file and removed ckisr.c where possible.

Updated spsize to reflect new and moved variables.

Makefiles for the executive source and include files updated to show
break down of files into Core, RTEMS API, and Neither.

Header and inline files installed into subdirectory based on whether
logically in the Core or a part of the RTEMS API.
1995-09-11 19:35:39 +00:00

306 lines
8.9 KiB
C

/*
* @(#)server.c 1.3 - 95/08/02
*
*
* RTEMS monitor server (handles requests for info from RTEMS monitors
* running on other nodes)
*
* $Id$
*/
#include <rtems.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "monitor.h"
/*
* Various id's for the server
*/
rtems_id rtems_monitor_server_task_id;
rtems_id rtems_monitor_server_request_queue_id; /* our server */
rtems_id *rtems_monitor_server_request_queue_ids; /* all servers */
rtems_id rtems_monitor_server_response_queue_id; /* our server */
/*
* Send a request to a server task
*/
rtems_status_code
rtems_monitor_server_request(
unsigned32 server_node,
rtems_monitor_server_request_t *request,
rtems_monitor_server_response_t *response
)
{
rtems_id server_id;
rtems_status_code status;
unsigned32 size;
/*
* What is id of monitor on target node?
* Look it up if we don't know it yet.
*/
server_id = rtems_monitor_server_request_queue_ids[server_node];
if (server_id == 0)
{
status = rtems_message_queue_ident(RTEMS_MONITOR_QUEUE_NAME,
server_node,
&server_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "ident of remote server failed");
goto done;
}
rtems_monitor_server_request_queue_ids[server_node] = server_id;
}
request->return_id = rtems_monitor_server_response_queue_id;
status = rtems_message_queue_send(server_id, request, sizeof(*request));
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "monitor server request send failed");
goto done;
}
/*
* Await response, if requested
*/
if (response)
{
status = rtems_message_queue_receive(rtems_monitor_server_response_queue_id,
response,
&size,
RTEMS_WAIT,
100);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "server did not respond");
/* maybe server task was restarted; look it up again next time */
rtems_monitor_server_request_queue_ids[server_node] = 0;
goto done;
}
if (response->command != RTEMS_MONITOR_SERVER_RESPONSE)
{
status = RTEMS_INCORRECT_STATE;
goto done;
}
}
done:
return status;
}
/*
* monitor server task
*/
void
rtems_monitor_server_task(
rtems_task_argument monitor_flags
)
{
rtems_monitor_server_request_t request;
rtems_monitor_server_response_t response;
rtems_status_code status;
unsigned32 size;
for (;;)
{
status = rtems_message_queue_receive(
rtems_monitor_server_request_queue_id,
&request,
&size,
RTEMS_WAIT,
(rtems_interval) 0);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "monitor server msg queue receive error");
goto failed;
}
if (size != sizeof(request))
{
rtems_error(0, "monitor server bad size on receive");
goto failed;
}
switch (request.command)
{
case RTEMS_MONITOR_SERVER_CANONICAL:
{
rtems_object_type_t object_type;
rtems_id id;
rtems_id next_id;
object_type = (rtems_object_type_t) request.argument0;
id = (rtems_id) request.argument1;
next_id = rtems_monitor_object_canonical_get(object_type,
id,
&response.payload,
&size);
response.command = RTEMS_MONITOR_SERVER_RESPONSE;
response.result0 = next_id;
response.result1 = size;
#define SERVER_OVERHEAD (RTEMS_offsetof(rtems_monitor_server_response_t, \
payload))
status = rtems_message_queue_send(request.return_id,
&response,
size + SERVER_OVERHEAD);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "response send failed");
goto failed;
}
break;
}
default:
{
rtems_error(0, "invalid command to monitor server: %d", request.command);
goto failed;
}
}
}
failed:
rtems_task_delete(RTEMS_SELF);
}
/*
* Kill off any old server
* Not sure if this is useful, but it doesn't help
*/
void
rtems_monitor_server_kill(void)
{
if (rtems_monitor_server_task_id)
rtems_task_delete(rtems_monitor_server_task_id);
rtems_monitor_task_id = 0;
if (rtems_monitor_server_request_queue_id)
rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
rtems_monitor_server_response_queue_id = 0;
if (rtems_monitor_server_response_queue_id)
rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
rtems_monitor_server_request_queue_ids = 0;
if (rtems_monitor_server_request_queue_ids)
free(rtems_monitor_server_request_queue_ids);
rtems_monitor_server_request_queue_ids = 0;
}
void
rtems_monitor_server_init(
unsigned32 monitor_flags
)
{
rtems_status_code status;
if (_System_state_Is_multiprocessing &&
(_Configuration_MP_table->maximum_nodes > 1))
{
unsigned32 maximum_nodes = _Configuration_MP_table->maximum_nodes;
/*
* create the msg que our server will listen
* Since we only get msgs from other RTEMS monitors, we just
* need reserve space for 1 msg from each node.
*/
status = rtems_message_queue_create(
RTEMS_MONITOR_QUEUE_NAME,
maximum_nodes,
sizeof(rtems_monitor_server_request_t),
RTEMS_GLOBAL,
&rtems_monitor_server_request_queue_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor server message queue");
goto done;
}
/*
* create the msg que our responses will come on
* Since monitor just does one thing at a time, we only need 1 item
* message queue.
*/
status = rtems_message_queue_create(
RTEMS_MONITOR_RESPONSE_QUEUE_NAME,
1, /* depth */
sizeof(rtems_monitor_server_response_t),
RTEMS_GLOBAL,
&rtems_monitor_server_response_queue_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor response message queue");
goto done;
}
/* need an id for queue of each other server we might talk to */
/* indexed by node, so add 1 to maximum_nodes */
rtems_monitor_server_request_queue_ids =
(rtems_id *) malloc((maximum_nodes + 1) * sizeof(rtems_id));
(void) memset(rtems_monitor_server_request_queue_ids,
0,
(maximum_nodes + 1) * sizeof(rtems_id));
rtems_monitor_server_request_queue_ids[rtems_monitor_node] =
rtems_monitor_server_request_queue_id;
/*
* create the server task
*/
status = rtems_task_create(RTEMS_MONITOR_SERVER_NAME,
1,
0 /* default stack */,
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_DEFAULT_ATTRIBUTES,
&rtems_monitor_server_task_id);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not create monitor server task");
goto done;
}
/*
* Start the server task
*/
status = rtems_task_start(rtems_monitor_server_task_id,
rtems_monitor_server_task,
monitor_flags);
if (status != RTEMS_SUCCESSFUL)
{
rtems_error(status, "could not start monitor server");
goto done;
}
}
done:
}