?? tm1if_pc.c
字號:
/*
* COPYRIGHT (c) 1995 by Philips Semiconductors
*
* +-----------------------------------------------------------------+
* | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED |
* | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH |
* | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. |
* | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE |
* | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE |
* | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED. |
* +-----------------------------------------------------------------+
*
* Module name : TM1IF_pc.c 1.7
*
* Last update : 11:04:54 - 99/03/29
*
* Title : PC version of HostCall server, PC part
*
* Reviewed :
*
* Revision history :
*
* Description :
*
* This module is part of an implementation of the server part
* for a HostCall interface. HostCall is the software component
* which is required by the TCS toolset to adapt the programs
* generated by this toolset to a specific host (see file
* HostCall.h in the TCS include dir).
*
* HostIF is the part of the implementation which runs on the
* host, serving all IO requests of the TM-1 application.
* HostIF is one of two modules of this host-resident part, and
* defines all host specific issues which are communication
* with the target and the ability to start a number of server
* tasks. The other part, RPCClient, defines *how* messages
* should be served; RPCClient it still is host independent.
*
* RPCServ is the counterpart of RPCClient on the target, and
* TM1IF is the counterpart of HostIF on the target. However,
* contrary to the target situation, where RPCClient is built
* on top of HostIF, on the host side TM1IF is built on top of
* RPCServ. Hence TM1IF forms the external interface of the
* server pair.
*
* The interface to this module is as follows: First, it should
* be initialised. Second, a number of nodes should be defined,
* specifying node specific information.
* After this, the nodes can be started and a communication
* session with these nodes can be started by means of function
* TM1IF_start_serving; depending on the implementation, a call
* to this function either immediately returns, with a number
* of serving tasks created for handling target's IO requests,
* or it blocks until function TM1IF_term is called (typically
* by the exit handler, when the last node has reported termination).
*
* Having a pool of servers reduces the possibility that serving
* is halted due to serving requests which take a longer
* time to complete. For instance, when running pSOS on the
* target with one task requesting keyboard input from the host,
* the current implementation of RPCClient will stop serving
* requests when only one server task is selected: while blocked
* on the keyboard, it will not be able to serve requests from
* other pSOS tasks.
* The current host (with the OS used) might or might not be
* able to dispatch multiple tasks, so start_serving returns
* one of the following results:
* - TM1IF_Serving_Failed
* Initialisation (e.g. setup of target
* communication, or server task creation)
* failed.
* - TM1IF_Serving_Started
* The servers have been created, and
* are now busy serving.
* Serving should be stopped using the
* TM1IF_term function.
* - TM1IF_Serving_Completed
* TM1IF was not capable of creating independent
* serving tasks, so the TM-1 application
* has been entirely served during the call
* to start_serving.
*
* NB: This interface does not provide for loading and
* starting the TM1 appication.
*
* This module forms a Windows 95 implementation of
* the TM1IF interface. It is capable of creating multiple
* server tasks. The communication is implemented on top of
* the Trimedia Manager interface, of which it reserves
* Channel #1.
*/
/*---------------------------- Includes --------------------------------------*/
#include <windows.h>
#include <winioctl.h>
#include <time.h>
#include <sys/timeb.h>
#include <signal.h>
#include <stdarg.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <setjmp.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include "tmtypes.h"
#include "tmmanerr.h"
#include "tmmanapi.h"
#include "HostCall.h"
#include "RPC_Common.h"
#include "TM1IF.h"
#include "io.h"
#include "Lib_Local.h"
/*---------------------------- Module State ----------------------------------*/
#define NROF_SERVERS 4
/*
* Various global state:
*/
static Int32 nrof_created_servers;
static HANDLE *created_servers;
static Bool same_endian;
static HANDLE MessageSynchHandle;
typedef struct {
DWORD dsp_number;
DWORD dsp_handle;
DWORD hostcall_channel;
Bool valid;
} NodeData;
static NodeData *nodedata;
static Int nrof_dsps;
/*--------------------------- Exported Functions -----------------------------*/
static Bool serving_stopped;
static void
serve()
{
int i;
while (!serving_stopped) {
tmmanPacket Packet;
WaitForSingleObject(MessageSynchHandle, INFINITE);
for (i = 0; i < nrof_dsps; i++) {
if (serving_stopped) {
/*
* Pass termination event:
*/
SetEvent(MessageSynchHandle);
return;
}
else if (nodedata[i].valid
&& tmmanMessageReceive(nodedata[i].hostcall_channel, &Packet) == statusSuccess
) {
Pointer raw_command;
HostCall_command *command;
/*
* Let next task check for next message:
*/
SetEvent(MessageSynchHandle);
raw_command = Packet.Argument[0];
command = RPCServ_raw_to_host(raw_command);
command->notification_status = HostCall_BUSY;
if (RPCServ_serve(raw_command)) {
tmmanMessageSend(nodedata[i].hostcall_channel, &Packet);
}
}
}
}
}
/*
* Function : Start serving the (independently started)
* TM-1 application. Serving should use the specified
* IO functions, and use the specified file descriptors
* for stdin, stdout and stderr. It should try to
* start the requested number of serving tasks and return,
* but when there are no capabilities for starting
* tasks this function itself can act as server before
* it returns.
* Function Result : see module header
* Precondition : -
* Postcondition : -
* Sideeffects : -
*/
TM1IF_Served_Status
TM1IF_start_serving( )
{
Int32 i;
nrof_created_servers = 0;
created_servers = malloc( NROF_SERVERS * sizeof(HANDLE) );
if (created_servers == NULL) {
return TM1IF_Serving_Failed;
}
for (i=1; i <= NROF_SERVERS; i++) {
HANDLE dummy;
HANDLE new_thread;
new_thread= CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE)serve, 0, 0, (LPDWORD)&dummy );
if (new_thread != NULL) {
created_servers[nrof_created_servers++]= new_thread;
}
}
if (nrof_created_servers > 0) {
return TM1IF_Serving_Started;
} else {
return TM1IF_Serving_Failed;
}
}
/*
* Function : Initialise this module, and make the
* I/O callback functions known to it.
* Parameters : open .. exit (I) IO functions.
* endian (I) node's endianness
* Function Result : True iff initialisation succeeded
*/
Bool TM1IF_init(
RPCServ_OpenFunc open,
RPCServ_OpenDllFunc open_dll,
RPCServ_CloseFunc close,
RPCServ_ReadFunc read,
RPCServ_WriteFunc write,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -