예제 #1
0
파일: user.c 프로젝트: kspaans/StrombolOS
void ipc1 () {
  bwprintf (COM2, "ipc1: I am %d\r\n", MyTid());
  bwprintf (COM2, "ipc1: Registering as LOL\r\n");
  RegisterAs ("LOL"); RegisterAs ("POO");
  bwprintf (COM2, "ipc1: Registration complete.\r\n");
  bwprintf (COM2, "ipc1: WhoIs(\"LOL\") = %d\r\n",WhoIs("LOL"));
  bwprintf (COM2, "ipc1: Exiting.\r\n");
  bwprintf (COM2, "ipc1: WhoIs(\"POO\") = %d\r\n",WhoIs("POO"));
  Exit();
}
예제 #2
0
파일: rps.c 프로젝트: RobertElder/CS452
void RPSServer_Start() {
	robprintfbusy((const unsigned char *)"RPSServer created tid=%d\n", MyTid());

	int result = RegisterAs((char*) RPS_SERVER_NAME);

	assert(result == 0, "RPSServer_Start failed to register name");

	ChannelDescription terminal_channel;
	terminal_channel.channel = COM2;
	terminal_channel.speed = 115200;
	robsetspeed( &terminal_channel);

	RPSServer server;
	RPSServer_Initialize(&server);

	while(1) {
		RPSServer_ProcessMessage(&server);

		if (!server.running) {
			break;
		}
	}

	robprintfbusy((const unsigned char *)"RPSServer exited\n");

	NameServerMessage * name_server_message = (NameServerMessage *) server.send_buffer;
	NameServerMessage * reply_message = (NameServerMessage *) server.reply_buffer;
	name_server_message->message_type = MESSAGE_TYPE_NAME_SERVER_SHUTDOWN;
	Send(NAMESERVER_TID, server.send_buffer, MESSAGE_SIZE, server.reply_buffer, MESSAGE_SIZE);
	assert(reply_message->message_type==MESSAGE_TYPE_ACK, "RPSServer didn't get ACK from name server");

	Exit();

	assert(0, "Shouldn't see me\n");
}
예제 #3
0
void sensor_server() {
    struct SensorService service;    
    sensorservice_initialize(&service);

    RegisterAs("SensorServer");

    // Create the thing sending us sensor messages.
    Create(HIGH, sensor_notifier);

    tid_t stream = CreateStream("SensorServerStream");

    int tid;
    SensorServerMessage msg, rply;
    for(;;) {
        Receive(&tid, (char *) &msg, sizeof(msg));

        switch(msg.type) {
            case SENSOR_EVENT_REQUEST:
                rply.type = SENSOR_EVENT_RESPONSE;
                Reply(tid, (char *) &rply, sizeof(rply));

                sensorservice_process_data(&service, msg.data);

                publish(&service, stream);
                break;
            default:
                ulog("Invalid SensorServer Request");
        }
    }

    Exit();
}
예제 #4
0
void routeFinder( ) {
	track_node track[TRACK_MAX];
	init_tracka(track);

	RegisterAs( "route" );

	// int printer = MyParentTid();
	ComReqStruct reply;
	int sender;

	FOREVER {
		Receive( &sender, (char *)&reply, sizeof(ComReqStruct) );

		int src  = reply.data1;	// No offset right now
		int dest = reply.data2;

		// Begin finding the shortest path from the src to the dest
		Path shortest;
		route( track, &shortest, src, dest );

		ComReqStruct fus, roh;
	fus.type = UPDATE_STAT;
	fus.data1 = (int *)&shortest;
	Send( MyParentTid(), (char *)&fus, sizeof(ComReqStruct), (char *)&roh, sizeof(ComReqStruct) );

		Reply( sender, (char *)&shortest, sizeof(Path) );
	}
}
예제 #5
0
void plAgeLoader::Init()
{
    RegisterAs( kAgeLoader_KEY );
    plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plClientMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plResPatcherMsg::Index(), GetKey());
}
예제 #6
0
void plAutoProfileImp::IInit()
{
    // TODO: Find a better way to grab a list of age names, since the old data server
    // no longer exists
    /*plIDataServer* dataServer = plNetClientMgr::GetInstance()->GetDataServer();
    if (!dataServer)
        return;

    dataServer->GetDatasetAges(fAges);*/

    // The first age we link into is AvatarCustomization, since we have a new avatar.
    // Coincidentally, the first age in our list is AvatarCustomization.  However,
    // sometimes linking from ACA to ACA causes a crash.  To get around that, we just
    // reverse the list, so it's last.
    std::reverse(fAges.begin(), fAges.end());

    fNextAge = 0;

    RegisterAs(kAutoProfile_KEY);

    plgDispatch::Dispatch()->RegisterForExactType(plAgeBeginLoadingMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
    plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());

    plConsoleMsg* consoleMsg = new plConsoleMsg(plConsoleMsg::kExecuteLine, "Camera.AlwaysCut true");
    consoleMsg->Send();
}
예제 #7
0
void    plInputInterfaceMgr::Init( void )
{
    RegisterAs( kInputInterfaceMgr_KEY );

    plgDispatch::Dispatch()->RegisterForType( plInputIfaceMgrMsg::Index(), GetKey() );
    plgDispatch::Dispatch()->RegisterForType( plInputEventMsg::Index(), GetKey() );

    plgDispatch::Dispatch()->RegisterForType( plEvalMsg::Index(), GetKey() );
    plgDispatch::Dispatch()->RegisterForExactType( plPlayerPageMsg::Index(), GetKey() );
    plgDispatch::Dispatch()->RegisterForExactType( plCmdIfaceModMsg::Index(), GetKey() );
    plgDispatch::Dispatch()->RegisterForExactType( plClientMsg::Index(), GetKey() );

    /// Hacks (?) for now
    plAvatarInputInterface *avatar = new plAvatarInputInterface();
    IAddInterface( avatar );
    hsRefCnt_SafeUnRef( avatar );

    plSceneInputInterface *scene = new plSceneInputInterface();
    IAddInterface( scene );
    hsRefCnt_SafeUnRef( scene );

    plDebugInputInterface *camDrive = new plDebugInputInterface();
    IAddInterface( camDrive );
    hsRefCnt_SafeUnRef( camDrive );

}
예제 #8
0
void rps_server() {
  int q[50];
  int start = 0;
  int end = 0;
  int p1=0, p2=0;
  char a1, a2;
  char m[2]; m[1] = 0;
  int tid;
  int nump = 0;
  bwprintf (COM2, "RPS server started.\r\n");
  RegisterAs ("RPS");
//  bwprintf (COM2, "I AM REGISTERED??? WhoIs (\"RPS\") = %d\r\n",WhoIs ("RPS"));
  while (1) {
   Receive (&tid, m, 1);
//   bwprintf (COM2, "dicks");
 
    switch (m[0]) {
      case 'J':
        bwprintf (COM2, "RPS_SERVER: %d joined.\r\n", tid);
	q[end]=tid;
        end++;
        break;
      case 'R':
      case 'P':
      case 'S':
        if (p1 == 0 || p2 == 0) { m[0] = 'Q'; Reply (tid, m, 1); }
        if (p1 == tid) { bwprintf (COM2, "RPS_SERVER: Player 1 says %c.\r\n", m[0]); a1 = m[0]; }
        else { bwprintf (COM2, "RPS_SERVER: Player 2 says %c.\r\n", m[0]); a2 = m[0]; }
        break;
      case 'Q':
        bwprintf (COM2, "RPS_SERVER: %d quit.", tid);
        if (tid == p1) p1 = 0;
        else  p2 = 0; p1=0;p2=0;
        break;
    }
    if (p1 == p2 && p1 == 0 && end-start >= 2) {
      p1 = q[start];
      p2 = q[start+1];
      start += 2;
      bwprintf (COM2, "\r\n RPS_SERVER: Start game: %d vs. %d.\r\n", p1, p2);
      nump -= 2;
      a1 = a2 = 0;
      Reply (p1, 0, 0);
      Reply (p2, 0, 0);
    } 
    if (a1 != 0 && a2 != 0) {
      if      (a1 == 'R' && a2 == 'R') { m[0] = 'T'; Reply (p1, m, 1); m[0] = 'T'; Reply (p2, m, 1); }
      else if (a1 == 'R' && a2 == 'P') { m[0] = 'L'; Reply (p1, m, 1); m[0] = 'W'; Reply (p2, m, 1); }
      else if (a1 == 'R' && a2 == 'S') { m[0] = 'W'; Reply (p1, m, 1); m[0] = 'L'; Reply (p2, m, 1); }
      else if (a1 == 'P' && a2 == 'R') { m[0] = 'W'; Reply (p1, m, 1); m[0] = 'L'; Reply (p2, m, 1); }
      else if (a1 == 'P' && a2 == 'P') { m[0] = 'T'; Reply (p1, m, 1); m[0] = 'T'; Reply (p2, m, 1); }
      else if (a1 == 'P' && a2 == 'S') { m[0] = 'L'; Reply (p1, m, 1); m[0] = 'W'; Reply (p2, m, 1); }
      else if (a1 == 'S' && a2 == 'R') { m[0] = 'L'; Reply (p1, m, 1); m[0] = 'W'; Reply (p2, m, 1); }
      else if (a1 == 'S' && a2 == 'P') { m[0] = 'W'; Reply (p1, m, 1); m[0] = 'L'; Reply (p2, m, 1); }
      else if (a1 == 'S' && a2 == 'S') { m[0] = 'T'; Reply (p1, m, 1); m[0] = 'T'; Reply (p2, m, 1); }
      a1 = a2 = 0;
    }
  }
}
예제 #9
0
/*!
Registers the function as a function in excel.
\sa XlfExcel, XlfCmdDesc.
*/
int xlw::XlfFuncDesc::DoRegister(const std::string& dllName, const std::string& suggestedHelpId) const
{
    if (returnTypeCode_.empty())
        returnTypeCode_= XlfExcel::Instance().xlfOperType();
    if(returnTypeCode_ == "XLW_FP")
        returnTypeCode_= XlfExcel::Instance().fpType();
    return RegisterAs(dllName, suggestedHelpId, 1);
}
예제 #10
0
static
VOID
SwitchpTask()
{
    SWITCH_DIRECTION directions[NUM_SWITCHES];

    VERIFY(SUCCESSFUL(RegisterAs(SWITCH_SERVER_NAME)));

    IO_DEVICE com1;
    VERIFY(SUCCESSFUL(Open(UartDevice, ChannelCom1, &com1)));

    for (UINT i = 0; i < NUM_SWITCHES; i++)
    {
        UCHAR sw = SwitchpFromIndex(i);

        VERIFY(SUCCESSFUL(SwitchpDirection(&com1, sw, SwitchCurved)));

        directions[i] = SwitchCurved;

        ShowSwitchDirection(i, sw, SwitchCurved);
    }

    VERIFY(SUCCESSFUL(SwitchpDisableSolenoid(&com1)));

    while (1)
    {
        INT senderId;
        SWITCH_REQUEST request;

        VERIFY(SUCCESSFUL(Receive(&senderId, &request, sizeof(request))));

        switch(request.type)
        {
            case SetDirectionRequest:
            {
                VERIFY(SUCCESSFUL(SwitchpDirection(&com1, request.sw, request.direction)));
                VERIFY(SUCCESSFUL(SwitchpDisableSolenoid(&com1)));

                UINT switchIndex = SwitchpToIndex(request.sw);
                directions[switchIndex] = request.direction;

                VERIFY(SUCCESSFUL(Reply(senderId, NULL, 0)));

                ShowSwitchDirection(switchIndex, request.sw, request.direction);

                break;
            }

            case GetDirectionRequest:
            {
                UINT switchIndex = SwitchpToIndex(request.sw);
                SWITCH_DIRECTION direction = directions[switchIndex];
                VERIFY(SUCCESSFUL(Reply(senderId, &direction, sizeof(direction))));
                break;
            }
        }
    }
}
예제 #11
0
파일: clock.c 프로젝트: RobertElder/CS452
void ClockServer_Start() {
	ClockServer server;
	ClockServer_Initialize(&server);
	
	GenericMessage * receive_msg = (GenericMessage *) server.receive_buffer;
	int source_tid;
	
	assert(sizeof(NotifyMessage) <= MESSAGE_SIZE, "NotifyMessage size too big");
	assert(sizeof(ClockMessage) <= MESSAGE_SIZE, "ClockMessage size too big");
	
	robprintfbusy((const unsigned char *)"ClockServer TID=%d: start\n", server.tid);
	
	int return_code = RegisterAs((char *)CLOCK_SERVER_NAME);
	assert(return_code == 0, "ClockServer: Failed to register name");
	
	int tid = Create(HIGHEST, ClockNotifier_Start);
	assert(tid > 0, "ClockNotifier tid not positive");
	
	// For Debugging
	*TIMER4_VAL_HIGH |= 1 << 8;
	server.last_timer_value = *TIMER4_VAL_LOW;
	
	while (server.running) {
		Receive(&source_tid, server.receive_buffer, MESSAGE_SIZE);
		//robprintfbusy((const unsigned char *)"ClockServer: received %d message type\n", receive_msg->message_type);
		
		switch(receive_msg->message_type) {
		case MESSAGE_TYPE_NOTIFIER:
			ClockServer_HandleNotifier(&server, source_tid, (NotifyMessage*) receive_msg);
			break;
		case MESSAGE_TYPE_TIME_REQUEST:
			ClockServer_HandleTimeRequest(&server, source_tid, (ClockMessage*) receive_msg);
			break;
		case MESSAGE_TYPE_DELAY_REQUEST:
			ClockServer_HandleDelayRequest(&server, source_tid, (ClockMessage*) receive_msg, 0);
			break;
		case MESSAGE_TYPE_DELAY_UNTIL_REQUEST:
			ClockServer_HandleDelayRequest(&server, source_tid, (ClockMessage*) receive_msg, 1);
			break;
		case MESSAGE_TYPE_SHUTDOWN:
			ClockServer_HandleShutdownRequest(&server, source_tid, (ClockMessage*) receive_msg);
			break;
		default:
			assertf(0, "ClockServer: unknown message type %d", receive_msg->message_type);
			break;
		}
		
		ClockServer_UnblockDelayedTasks(&server);
		Pass();
	}
	
	robprintfbusy((const unsigned char *)"ClockServer TID=%d: end\n", server.tid);
	
	Exit();
}
예제 #12
0
파일: io.c 프로젝트: mdbaker60/CS452_Kernel
void InputInit() {
  struct IOMessagebuf bufMsg;
  struct IOMessage *msg = (struct IOMessage *)&bufMsg;
  int reply, src;
  struct IONode nodes[100];
  struct IONode *first[2] = {NULL, NULL};
  struct IONode *last[2] = {NULL, NULL};
  int buffer1[BUFFERSIZE];
  int buffer2[BUFFERSIZE];
  int bufHead[2] = {0, 0};
  int bufTail[2] = {0, 0};

  int notifier1Tid = Create(7, notifier);
  int notifier2Tid = Create(7, bufferedNotifier);
  int eventType = TERMIN_EVENT;
  Send(notifier2Tid, (char *)&eventType, sizeof(int), (char *)&reply, sizeof(int));
  eventType = TRAIIN_EVENT;
  Send(notifier1Tid, (char *)&eventType, sizeof(int), (char *)&reply, sizeof(int));
  RegisterAs("Input Server");

  while(true) {
    Receive(&src, (char *)&bufMsg, sizeof(struct IOMessagebuf));
    switch(bufMsg.type) {
      case IONOTIFIER:
	reply = 0;
	Reply(src, (char *)&reply, sizeof(int));
	if(src == notifier1Tid){
	  handleNewInput(&first[0], last[0], buffer1, &bufHead[0], bufTail[0], (char)msg->data);
	}else if(src == notifier2Tid) {
	  int *buffer = bufMsg.data;
	  while(*buffer != (int)'\0') {
	    handleNewInput(&first[1], last[1], buffer2, &bufHead[1], bufTail[1], *buffer);
	    buffer++;
	  }
	}
	break;
      case IOINPUT:
        nodes[src & 0x7F].tid = src;
	if (msg->channel == 1){
	  handleNewInputTask(&first[0], &last[0], buffer1, bufHead[0], &bufTail[0], &nodes[src & 0x7F]);
	}else if(msg->channel == 2) {
	  handleNewInputTask(&first[1], &last[1], buffer2, bufHead[1], &bufTail[1], &nodes[src & 0x7F]);
	}
	break;
    }
  }
}
예제 #13
0
파일: tasks.c 프로젝트: RobertElder/CS452
void IdleTask_Start(){
	RegisterAs((char*) IDLE_TASK_NAME);

	/* While we are waiting for events, this task and the administrator just send messages back and forth */
	char send_buffer[MESSAGE_SIZE] __attribute__ ((aligned (4)));
	char reply_buffer[MESSAGE_SIZE] __attribute__ ((aligned (4)));
	GenericMessage * send_message = (GenericMessage *) send_buffer;
	GenericMessage * reply_message = (GenericMessage *) reply_buffer;
	send_message->message_type = MESSAGE_TYPE_HELLO;
	
	int admin_tid;
	int tid_i = 0;
	while (1) {
		admin_tid = WhoIs((char*) ADMINISTRATOR_TASK_NAME);
		
		if (admin_tid) {
			break;
		}
		
		tid_i++;
		assert(tid_i < 1000, "IdleTask: admin tid not found");
	}
	
	int i = 0;
	while(1){
		if (i > 5000) {
			Send(admin_tid, send_buffer, MESSAGE_SIZE, reply_buffer, MESSAGE_SIZE);
			assertf(reply_message->message_type == MESSAGE_TYPE_ACK || reply_message->message_type == MESSAGE_TYPE_SHUTDOWN, "fail\n");
		
			if(reply_message->message_type == MESSAGE_TYPE_SHUTDOWN){
				break;
				robprintfbusy((const unsigned char *)"IdleTask_Start: Got shutdown\n" );
			}
			
			i = 0;
		} else {
			Pass();
		}
		
		i++;
	}

	Exit();
	assert(0,"Nope.");
}
void route_server() {
	bwdebug( DBG_SYS, ROUTE_SRV_DEBUG_AREA, "ROUTE_SERVER: enters" );
	RegisterAs( ROUTE_SERVER_NAME ); 
	
	// Data structures
	int sender_tid;
	Route_msg route_msg;
	
	while(1) {
		bwdebug( DBG_SYS, ROUTE_SRV_DEBUG_AREA, "ROUTE_SERVER: listening for a request" );
		Receive( &sender_tid, ( char * ) &route_msg, sizeof( route_msg )  );

		bwdebug( DBG_SYS, ROUTE_SRV_DEBUG_AREA, "ROUTE_SERVER: Received request [ sender_tid: %d type: %d ]", 
			sender_tid, route_msg.type );

		switch( route_msg.type ){
			//This message can arrive from:
			//	Train A
			//	Train B
			//	Train AI
			case GET_SHORTEST_ROUTE_MSG:

                get_shortest_route(
                    route_msg.track, route_msg.train_direction,
                    route_msg.current_landmark, route_msg.train_shift,
                    route_msg.target_node, route_msg.target_shift,
                    route_msg.switches,
                    route_msg.route_found,
                    route_msg.landmarks,
                    route_msg.num_landmarks,
                    route_msg.edges);

				bwdebug( DBG_SYS, ROUTE_SRV_DEBUG_AREA, "ROUTE_SERVER: Replying request [ sender_tid: %d type: %d ]", 
					sender_tid, route_msg.type );
				Reply( sender_tid, 0, 0 );

				break;

			default:
				bwdebug( DBG_SYS, ROUTE_SRV_DEBUG_AREA, 
					"ROUTE_SERVER: Invalid request. [type: %d]", route_msg.type );
				break;
		}
	}
}
예제 #15
0
void clockServerTask()
{
    // Initialize variables
    int tid = 0;
    unsigned int tick = 0;
    ClockReq req;
    req.type = 0;
    req.data = 0;
    DelayedQueue q;
    initDelayedTasks(&q);

    // Register with name server
    RegisterAs("clockServer");

    // Spawn notifier
    Create(PRIORITY_CLOCK_NOTIFIER, &clockNotifier);

    // Main loop for serving requests
    for (;;)
    {
        Receive(&tid, &req, sizeof(req));
        switch (req.type)
        {
        case NOTIFICATION:
            Reply(tid, 0, 0);
            tick++;
            removeExpiredTasks(&q, tick);
            break;
        case TIME:
            Reply(tid, &tick, sizeof(tick));
            break;
        case DELAY:
            insertDelayedTask(&q, tid, req.data + tick);
            break;
        case DELAY_UNTIL:
            insertDelayedTask(&q, tid, req.data);
            break;
        default:
            bwprintf(COM2, "[Clockserver] Invalid request type: %d\n\r", req.type);
            for (;;);
            break;
        }
    }
}
예제 #16
0
void routeFinder( ) {
	track_node track[TRACK_MAX];
	init_tracka(track);

	RegisterAs( "route" );
	int myAdmin = MyParentTid();
	int monitor = WhoIs( "monitor" );

	// int printer = MyParentTid();
	ComReqStruct reply, reservation,send;
	int sender;
	int trains[2]; // first train use the first Path structure, second train use the second path
	trains[0] = 0;
	trains[1] = 0;
	Path paths[2];

	FOREVER {
		Receive( &sender, (char *)&reply, sizeof(ComReqStruct) );

		int src  = reply.data1;	// No offset right now
		int dest = reply.data2;

		// Begin finding the shortest path from the src to the dest
		int i;
		if ( trains[0] == 0 || sender == trains[0] ) {
			trains[0] = sender;
			i = 0;
		} else if ( trains[1] == 0 || sender == trains[1] ) {
			trains[1] = sender;
			i = 1;
		}

		route( track, &paths[i], src, dest );

		// ComReqStruct fus, roh;
		// fus.type = UPDATE_STAT;
		// fus.data1 = (int *)&paths[i];
		// Send( MyParentTid(), (char *)&fus, sizeof(ComReqStruct), (char *)&roh, sizeof(ComReqStruct) );

		Reply( sender, (char *)&paths[i], sizeof(Path) );
	}
}
예제 #17
0
void sem_server()
{
    Sem_request request;
    Semaphore* sem;
    int tid;
    int status;

    status = RegisterAs( SEMAPHORE_SERVER_NAME );
    assert( status == REGISTER_AS_SUCCESS );

    while( 1 ) {
        status = Receive( &tid, ( char* )&request, sizeof( request ) );
        assert( status == sizeof( request ) );

        sem = request.sem;

        switch( request.type ) {
        case SEM_RELEASE:
            sem->count += 1;
            status = Reply( tid, ( char* )&status, sizeof( status ) );
            assert( status == SYSCALL_SUCCESS );
            break;
        case SEM_AC_ALL:
            if( sem->count > 0 ) {
                sem->count = 1;
            }
        // Fall through
        case SEM_ACQUIRE:
            status = rbuf_put( &sem->wait_queue, ( uchar* )&tid );
            assert( status == ERR_NONE );
            break;
        }

        while( sem->count > 0 && ! rbuf_empty( &sem->wait_queue ) ) {
            sem->count -= 1;
            rbuf_get( &sem->wait_queue, ( uchar* )&tid );
            status = Reply( tid, ( char* )&status, sizeof( status ) );
            assert( status == SYSCALL_SUCCESS );
        }
    }
}
예제 #18
0
파일: rps_server.c 프로젝트: dzelemba/cs452
void rps_server_run() {
  RegisterAs("RPS Server");

  int tid;
  rps_request req;
  while (1) {
    Receive(&tid, (char *)&req, sizeof(rps_request));
    switch (req.type) {
      case SIGNUP:
        _signup(tid);
        break;
      case PLAY:
        _play(tid, req.move);
        break;
      case QUIT:
        _quit(tid);
        break;
      default:
        ERROR("Invalid rps request type %d\n", req.type);
    }
  }
}
예제 #19
0
main() {
    char sendData='s';
    char strWrite[20];

    int	tid_sensorSrv;

    unsigned char sensorSendData[5], sensor;

    RegisterAs("SensorReporter");
    Delay(10);

    tid_sensorSrv = WhoIs( "SensorSrv");

    while( 1 ) {
	Send(tid_sensorSrv,NULL,NULL, &sensorSendData,5*sizeof(char));
	sensor = sensorSendData[0];
	sprintf(strWrite,"se %c %d\n",SEN_MODULE_CHAR(sensor),
	    SEN_NUMBER(sensor));
	Write(strWrite, strLen(strWrite), WYSE);
	Delay( 5 );
    } /* while */


}
예제 #20
0
파일: display.c 프로젝트: shepheb/kernel
//responsible for displaying all the necessary information to the screen many times per second.
//runs at fairly low priority by design.
//output includes:
// * switch states
// * sensor triggering timestamps
// * current positions of up to 3 trains relative to parts of the track
// almost never blocks, just keeps spinning when nothing higher-priority needs to run
void display_server(void){

	TrainState trains[MAX_TRAINS];
	int train_count = 0;
	
	SensorState sensors[SENSOR_HISTORY_LEN];
	int sensor_start = 0;
	int sensor_len   = 0;
	SwitchState switches[18+4];

	int active = 0;

	int i;
	// initialze switches 1-18
	for(i=0; i < 18; i++){
		switches[i].number = i+1;
		switches[i].state  = '?';
	}

	// and switches 153-156
	for(i=0; i < 4; i++){
		switches[i+18].number = i+153;
		switches[i+18].state  = '?';
	}

	RegisterAs("displayserver");

	int clockserverTid = WhoIs("clockserver");
	if(clockserverTid < 0){
		bwprintf(COM2, "Display server got tid %d for clocckserver\n\r", clockserverTid);
		Halt();
	}

	Create(PRIORITY_MID, &display_notifier);
	Create(PRIORITY_MID, &display_sensor_notifier);

	int tid, len;
	MsgPrintf msg;
	int printf_col = 0;

	// now we can start drawing and receiving messages in a loop. 
	FOREVER {
		len = Receive(&tid, (char*) &msg, sizeof(msg));
		
		if(len > 0){
			// I never have a useful Reply, so Reply immediately
			Reply(tid, NULL, 0);

			switch(msg.type){
				case MSG_DISPLAY_REGISTER: ;
					// add a train with the provided number and speed 0

					// if this is the first train, initialize the display
					if(train_count == 0){
						clear_screen();

						initialize_scrolling();

						refresh_switches(switches);
						refresh_sensors(sensors, sensor_start, sensor_len);

						active = 1;
					}

					MsgRegister *msgReg = (MsgRegister*) &msg;
					trains[train_count].number = msgReg->train;
					trains[train_count].speed  = 0;
					trains[train_count].route_len = 0;
					train_count++;

					break;

				case MSG_DISPLAY_DEREGISTER: ;
					// look up the train in the trains array, and pack the ones after it
					// special case for the last train

					msgReg = (MsgRegister*) &msg;

					if(train_count == 1){
						//clear_screen();
						restore_scrolling();
						move_cursor(SCREEN_BOTTOM, 1);

						active = 0;
						train_count = 0;
					} else if(train_count == 0){
						// do nothing
					} else {
						int i = 0;
						for(i=0; i < train_count; i++){
							if(trains[i].number == msgReg->train){
								break;
							}
						}

						// if we find the train, shift the rest of the array down
						if(i < train_count){
							for(i=i+1; i < train_count; i++){
								//copy to the previous one
								trains[i-1] = trains[i];
							}

							train_count--;
						}
					}

					break;

				case MSG_DISPLAY_SPEED: ;
					// update the given train's speed
					MsgSpeed *msgSpeed = (MsgSpeed*) &msg;
					// flip through my trains for this number
					for(i = 0; i < train_count; i++){
						if(trains[i].number == msgSpeed->train){
							trains[i].speed = msgSpeed->speed;
							break;
						}
					}
					// will be redisplayed below

					break;

				case MSG_DISPLAY_SWITCH: ;
					MsgSwitch *msgSwitch = (MsgSwitch*) &msg;
					if(msgSwitch->number <= 18){
						switches[msgSwitch->number-1].state = msgSwitch->state;
					} else {
						switches[msgSwitch->number-153+18].state = msgSwitch->state;
					}

					if(active){
						refresh_switches(switches);
					}

					break;

				case MSG_DISPLAY_ROUTE: ;
					// somewhat more complicated. copy the route for the given train
					// first find the train index
					MsgRouteSegment *msgRoute = (MsgRouteSegment*) &msg;

					for(i = 0; i < train_count; i++){
						if(trains[i].number == msgRoute->train){
							trains[i].route_len = msgRoute->route_len;
							int j;
							for(j = 0; j < msgRoute->route_len; j++){
								trains[i].route[j] = msgRoute->route[j];
							}
						}
					}

					break;

				case MSG_SENSOR_CLIENT: ; // message from the sensor server
					// work through the array from the sensor server, and update my list of sensors
					// remember that the sensors array starts at start and start gets decremented
					MsgSensorResponse *msgResp = (MsgSensorResponse*) &msg;
					int timestamp = Time(clockserverTid);
					for(i = 0; i < msgResp->length; i++){
						sensor_start--;
						if(sensor_start < 0) sensor_start = SENSOR_HISTORY_LEN-1;
						if(sensor_len < SENSOR_HISTORY_LEN) sensor_len++;

						getSensorName(msgResp->triggered[i], &(sensors[sensor_start]));
						sensors[sensor_start].time = timestamp;
					}

					if(active && msgResp->length > 0){
						refresh_sensors(sensors, sensor_start, sensor_len);
					}

					break;

				case MSG_DISPLAY_PRINTF: ;
					move_cursor(SCREEN_BOTTOM, printf_col);

					switch(msg.argc){
						case 0: aprintf(COM2, msg.format); break;
						case 1: aprintf(COM2, msg.format, msg.argv[0]); break;
						case 2: aprintf(COM2, msg.format, msg.argv[0], msg.argv[1]); break;
						case 3: aprintf(COM2, msg.format, msg.argv[0], msg.argv[1], msg.argv[2]); break;
						case 4: aprintf(COM2, msg.format, msg.argv[0], msg.argv[1], msg.argv[2], msg.argv[3]); break;
						case 5: aprintf(COM2, msg.format, msg.argv[0], msg.argv[1], msg.argv[2], msg.argv[3], msg.argv[4]); break;
						default: aprintf(COM2, "Bad argc: %d\n\r", msg.argc); break;
					}

					int len = strlen(msg.format);
					if(msg.format[len-1] == '\n' || msg.format[len-1] == '\r'){
						printf_col = 0;
					} else {
						printf_col += len;
					}


					break;
				
				case MSG_TICK: ;
					// display the train position
					// very crude for now. also only handling one train
					if(active){
						int i;
						int base_row;
						for(i = 0; i < train_count; i++){
							base_row = TRAIN_TOP + TRAIN_SIZE*i;
							move_and_clear(base_row, TRAIN_LEFT);
							aprintf(COM2, "Train %2d: ", trains[i].number);

							move_and_clear(base_row+1, TRAIN_LEFT);
							aprintf(COM2, "Speed: %2d ", trains[i].speed);

							if(trains[i].route_len > 0){
								SensorState ss;
								Sensor *s = (Sensor*) (trains[i].route[0]);
								getSensorName(s->alignment == 'F' ? s->forward_num : s->backward_num, &ss);
								move_and_clear(base_row+2, TRAIN_LEFT);
								aprintf(COM2, "Current sensor:\t%c%2d ", ss.module, ss.number);

								s = (Sensor*) (trains[i].route[ trains[i].route_len-1 ]);
								getSensorName(s->alignment == 'F' ? s->forward_num : s->backward_num, &ss);
								move_and_clear(base_row+3, TRAIN_LEFT);
								aprintf(COM2, "Next sensor:\t%c%2d ", ss.module, ss.number);
							} else {
								move_and_clear(base_row+2, TRAIN_LEFT);
								aprintf(COM2, "No route supplied.");
							}
						}
					}

					break;

				default: ;
					aprintf(COM2, "Display server: bogus type %d\n\r", msg.type);

			}

		}


	}


}
예제 #21
0
void trackServer() {
    RegisterAs("trackServer");
    int tid = 0;
    TrackServerReply reply;
    TrackServerMessage message;
    initTurnouts();

    for (;;) {
        int len = Receive(&tid, &message, sizeof(message));
        uassert(len == sizeof(TrackServerMessage));

        int numReserve = message.numReserve;
        int numRelease = message.numRelease;
        uassert(numReserve >= 0 && numRelease >= 0);

        reply = Success;

        // renounce ownership of each node in this array
        // if the caller does not own this track, then warn and do nothing
        // else return ReleaseSuccess
        for (int i = 0; i < numRelease; i++)
        {
            track_node *releaseNode = message.releaseNodes[i];
            uassert(releaseNode != 0);
            if (releaseNode->owner != -1 && releaseNode->owner != tid)
            {
                printf(COM2, "Tid %d trying to release node %s that doesn't belong to it", tid, releaseNode->name);
            }
            releaseNode->owner = -1;
        }

        // try to reserve each node in the reserve array,
        // if fails, then reply ReservationFailure
        // else, reply ReservationSuccess
        for (int i = 0; i < numReserve; i++)
        {
            track_node *reserveNode = message.reserveNodes[i];
            uassert(reserveNode != 0);

            if (!isReservable(reserveNode, tid))
            {
                if (reserveNode->owner != -1 && reserveNode->owner != tid)
                {
                    reply = ReserveFailSameDir;
                }
                else
                {
                    // head on collision
                    reply = ReserveFailOppositeDir;
                }
                break;
            }
            else
            {
                reserveNode->owner = tid;
            }
        }

        Reply(tid, &reply, sizeof(reply));
    }
    Exit();
}
예제 #22
0
void RegisterMulti(int trainNum){
  char name[] = MULTI_TRAIN_NAME;
  name[3] = '0'+trainNum/10;
  name[4] = '0'+trainNum%10;
  RegisterAs(name);
}
// Entry point of track-server
void track_server_entry() {

	RegisterAs(TRACK_SERVER);

	// Initialize the track
	track_init();

	// Initialize the reservation list
	reservation_init(train_reservations);

	// So we can update our own cached copy of the switch table
	int switch_courier_tid = CreateSwitchCourier(PRIORITY_HIGHEST - 1);

	int sender_tid;

	// Message buffer large enough to hold the largest message request
	char message_buffer[32];
	while (1) {
		Receive(&sender_tid, message_buffer, sizeof(message_buffer));

		if (sender_tid == switch_courier_tid) {
			// This is an update from the switch server, record the switch that changed
			// so that our cached table of switches is in sync
			int reply = 0;
			Reply(sender_tid, (char*)&reply, sizeof(reply));
			struct switch_report* report = (struct switch_report*)message_buffer;
			switch_table[(int)report->sw] = report->direction;
		} else {
			// API requests to the track_server

			struct track_reply_message reply = {-1, -1};
			int op = *(int*)message_buffer;

			switch(op) {

				// Handle track reservation requests
				case TRACK_OP_RESERVATION: {
					int reply = -1;
					struct reservation_request_message* reservation_msg = (struct reservation_request_message*)message_buffer;

					// Make the location be a sensor and positive offset that fits in the edge
					if (normalize_location(track, switch_table, &reservation_msg->position) != -1) {
						// Check if we can reserve this space for the train
						int status = reservation_verify(reservation_msg->train, &(reservation_msg->position), reservation_msg->length, reservation_msg->branch_safety);
						reply = status;

						if (status == 0) {
							// We succeeded. Reserve the track

							// Find the train's reservation_node
							struct reservation_node* train_r = get_reservation(train_reservations, reservation_msg->train);
							if (train_r != 0) {
								clear_train_reservations(train_r);

								// Add new reservation
								reservation_insert(train_r,
												&(reservation_msg->position),
												reservation_msg->length,
												reservation_msg->branch_safety);
							}
						} else if (status == -2) {
							// Reached max reservation
						}
					} else {
						Printf("Could not normalize\r");
					}

					Reply(sender_tid, (char*)&reply, sizeof(reply));
				} break;

				case TRACK_OP_RESERVATION_STRING: {
					struct reservation_request_message* reservation_msg = (struct reservation_request_message*)message_buffer;
					struct reservation_node* train_r = get_reservation(train_reservations, reservation_msg->train);

					char buf[300];
					*buf = 0; // null termination character
					int len = 0;
					if (train_r != 0) {
						len = reservation_print(train_r, buf);
					}

					Reply(sender_tid, (char*)buf, len); // +1 for null termination char
				} break;

				case TRACK_OP_NODE_IS_RESERVED: {

					struct reservation_request_message* reservation_msg = (struct reservation_request_message*)message_buffer;
					int reserved = node_is_reserved(reservation_msg->train, reservation_msg->position.node);

					Reply(sender_tid, (char*)&reserved, sizeof(reserved));
				} break;

				// Handle requests for calculating the distance between 2 nodes
				case TRACK_OP_TRACK_DISTANCE: {
					struct track_request_message* track_msg = (struct track_request_message*)message_buffer;
					if (track_msg->node1 < TRACK_MAX && track_msg->node2 < TRACK_MAX) {
						reply.distance = dist_between_nodes(track_msg->node1, track_msg->node2);
					}

					Reply(sender_tid, (char*)&reply, sizeof(reply));
				} break;

				case TRACK_OP_TRACK_DISTANCE_UNTIL_GOAL: {
					struct track_request_message* track_msg = (struct track_request_message*)message_buffer;
					int distance = 0;
					if (track_msg->node1 < TRACK_MAX && track_msg->node2 < TRACK_MAX) {
						distance = dist_until_goal(track_msg->node1, track_msg->offset1, track_msg->node2, track_msg->offset2, track_msg->distance);
					}

					Reply(sender_tid, (char*)&distance, sizeof(distance));
				} break;

				// Handle requests for getting the next sensor on the track
				case TRACK_OP_TRACK_NEXT_SENSOR: {
					struct track_request_message* track_msg = (struct track_request_message*)message_buffer;
					if (track_msg->node1 >= A1 && track_msg->node1 <= E16) {
						int distance;
						int next_sensor = next_sensor_node(track_msg->node1, track_msg->node2, &distance);

						reply.node = next_sensor;
						reply.distance = distance;
					}

					Reply(sender_tid, (char*)&reply, sizeof(reply));
				} break;

				case TRACK_OP_NORMALIZE: {
					struct track_request_message *msg = (struct track_request_message*)message_buffer;

					struct location loc;
					loc.node = msg->node1;
					loc.offset = msg->offset1;
					if (normalize_location(track, switch_table, &loc) == -1) {
						Reply(sender_tid, (char*)&loc, 0); // reply size 0 means error!
					}

					Reply(sender_tid, (char*)&loc, sizeof(loc));
				} break;

				// Handle requests for getting the reverse node of a given node
				case TRACK_OP_TRACK_REVERSE_NODE: {
					struct track_request_message* track_msg = (struct track_request_message*)message_buffer;
					if (track_msg->node1 < TRACK_MAX) {
						reply.node = track[track_msg->node1].reverse->num;
					}

					Reply(sender_tid, (char*)&reply, sizeof(reply));
				} break;

				case TRACK_OP_ROUTE: {
					struct track_request_message* track_msg = (struct track_request_message*)message_buffer;
					int train = track_msg->train;
					int start_node_num = track_msg->node1;
					int end_node_num = track_msg->node2;

					short path[TRACK_MAX];
					int num_nodes = 0;

					if (IS_SENSOR(start_node_num) && IS_SENSOR(end_node_num)) {
						struct track_node *start_node = &track[start_node_num];
						struct track_node *end_node = &track[end_node_num];
						mark_path(train, track, start_node, end_node);

						if (end_node->routing_info.visited == 1) {
							// we have a path!
							// store all nodes, from bottom up
							struct track_node *cur_node = end_node;
							struct location loc;
							while (cur_node->routing_info.previous != 0 && cur_node != start_node) {
								node_to_location(cur_node, &loc);
								path[num_nodes] = loc.node;
								num_nodes++;

								if (cur_node->routing_info.previous == cur_node->reverse) {
									// the next node is the reverse of this node, so we squeeze in a "REVERSE" in the path
									path[num_nodes] = -99; // magic number for REVERSE commands
									num_nodes++;
								}

								cur_node = cur_node->routing_info.previous;
							}

							// we didn't store the beginning node in our path, so we should do that now
							if (cur_node == start_node) {
								node_to_location(start_node, &loc);
								path[num_nodes] = loc.node;
								num_nodes++;
							}

						} else {
							Printf("Could not find route! num_nodes = %d\r", num_nodes);
						}

					}

					Reply(sender_tid, (char*)path, sizeof(short) * num_nodes);
				} break;

				case TRACK_OP_SWITCH_DIRECTION: {

					struct track_request_message* track_msg = (struct track_request_message*)message_buffer;

					int switch_node = track_msg->node1;
					int next_node = track_msg->node2;

					AssertF(track[switch_node].type == NODE_BRANCH, "TrackSwitchDirection not given a switch node! Given node num %d, type %d", track[switch_node].num, track[switch_node].type);

					int reserved = node_is_reserved(track_msg->train, switch_node);

					if (reserved) {
//						Printf("Attempting to switch %s if reserved .. \r", track[switch_node].name);
						int direction = -1;


						if (track[switch_node].edge[DIR_CURVED].dest == &(track[next_node])) {
							direction = SWITCH_CURVED;
						} else {
							direction = SWITCH_STRAIGHT;
						}

						SwitchSetDirection(track[switch_node].num, direction, WhoIs(SWITCH_SERVER));
						switch_table[track[switch_node].num] = direction;
					}

					Reply(sender_tid, (char*)&reserved, sizeof(reserved));
				} break;

				default:
					AssertF(0, "Invalid message %d to the track server from %d", op, sender_tid);
					Reply(sender_tid, (char*)&reply, sizeof(reply));
					break;
			}
		}
	}
	Assert("Track server is quitting");
	Exit();
}
예제 #24
0
static void timeserver_task() {
  int numTick= 0;
  char name[] = TIMESERVER_NAME;
  RegisterAs(name);

  // Initialize stack of delay tasks.
  for (int i = 0; i < TIMER_SERVER_SIZE-1; i++) {
    RegisteredTask* t = &(taskStack[i]);
    t->next = &(taskStack[i+1]);
    t->tid = -1;
  }
  {
    RegisteredTask* t = &(taskStack[TIMER_SERVER_SIZE-1]);
    t->next = (RegisteredTask*) -1;
    t->tid = -1;
  }
  RegisteredTask* taskSlots = &(taskStack[0]);
  RegisteredTask* tasks = (RegisteredTask*)-1;

  int notifierId = Create(HIGHEST_PRIORITY, timernotifier_task);

  // Start serving..
  for (;;) {
    int msgBuff = -1;
    int tid = -1;
    int len = Receive(&tid, (char*)&msgBuff, 4);
    ASSERT(len == 0 || len == 4, "Bad message to time server.");

    if (tid == notifierId) {
      numTick += 1;
      Reply(tid, (char*)NULL, 0); // Reply to notifier
    } else if (len == 0) {
      // Timing request
      Reply(tid, (char*)&numTick, 4);
    } else {
      if (msgBuff & 0xf0000000) {
        // Delay message
        msgBuff += numTick;
      }
      // Delay until message, dont need to add current time.
      msgBuff &= 0x00ffffff;

      // Insert into linked list
      RegisteredTask* current = tasks;
      RegisteredTask* previous = (RegisteredTask*)-1;
      while (current != (RegisteredTask*)-1 && (msgBuff > current->time)) {
        previous = current;
        current = current->next;
      }

      // Insert right before t1, which is t2
      RegisteredTask* newTask = taskSlots;
      taskSlots = taskSlots->next;
      //ASSERT(newTask != (RegisteredTask*)-1);
      if (previous != (RegisteredTask*)-1) {
        previous->next = newTask;
      } else {
        tasks = newTask;
      }
      newTask->next = current;
      newTask->time = msgBuff;
      newTask->tid  = tid;
    }

    // Reply to applicable queues...
    while (tasks != (RegisteredTask*)-1 && tasks->time <= numTick) {
      Reply(tasks->tid, (char*)NULL, 0);
      RegisteredTask* unusedTask = tasks;
      tasks = tasks->next;
      unusedTask->next = taskSlots;
      taskSlots = unusedTask;
    }
  } // End of serve loop
}
예제 #25
0
void clockserver() {
	char cs_name[] = CS_REG_NAME;
	assert(RegisterAs(cs_name) == 0, "Clockserver register failed");

	unsigned int time = 0;
	TimeReply reply;
	ClockServerMsg message;
	int tid;

	/* heap implement */
	Heap minheap;
	HeapNode *heap_data[TASK_MAX];
	heapInitial(&minheap, heap_data, TASK_MAX);
	HeapNode nodes[TASK_MAX];
	heapNodesInitial(nodes, TASK_MAX);
	int tid_array[TASK_MAX]; 	//actual datum in HeapNode
	int i = -1;
	for (i = 0; i < TASK_MAX; i++) {
		tid_array[i] = -1;
	}
	int notifier_tid = Create(1, notifier);

	while (1) {
		Receive(&tid, (char *)&message, sizeof(ClockServerMsg));
		if (tid == notifier_tid) {
			Reply(tid, NULL, 0);
			time++;
			DEBUG(DB_CS, "| CS:\tTime : %d\n", time);
			while (minheap.heapsize > 0 && time >= minheap.data[0]->key) {
				HeapNode *top = minHeapPop(&minheap);
				Reply(*(int *)(top->datum), NULL, 0);
			}
			continue;
		}

		switch(message.type) {
			case CS_QUERY_TYPE_DELAY:
				// delay
				tid_array[tid % TASK_MAX] = tid;
				nodes[tid % TASK_MAX].key = message.delayQuery.delay_tick + time;
				nodes[tid % TASK_MAX].datum = &(tid_array[tid % TASK_MAX]);
				minHeapInsert(&minheap, &(nodes[tid % TASK_MAX]));
				break;
			case CS_QUERY_TYPE_DELAY_UNTIL:
				// delay until
				if (message.delayUntilQuery.delay_time <= time) {
					Reply(tid, NULL, 0);
				} else {
					tid_array[tid % TASK_MAX] = tid;
					nodes[tid % TASK_MAX].key = message.delayUntilQuery.delay_time;
					nodes[tid % TASK_MAX].datum = &(tid_array[tid % TASK_MAX]);
					minHeapInsert(&minheap, &(nodes[tid % TASK_MAX]));
				}
				break;
			case CS_QUERY_TYPE_TIME:
				// time
				reply.time = time;
				Reply(tid, (char*)(&reply), sizeof(TimeReply));
				break;
			default:
				assert(0, "Clockserver received unknown query type");
				break;
		}
	}
}
예제 #26
0
파일: rps.c 프로젝트: taylorstark/CS452
static
VOID
RpspServerTask
    (
        VOID
    )
{
    INT player1;
    RPS_SERVER_REQUEST player1Request;
    INT player2;
    RPS_SERVER_REQUEST player2Request;
    RPS_SERVER_RESPONSE results[MaxMove][MaxMove];

    RegisterAs(RPS_SERVER_NAME);

    // Set up possible results
    results[RockMove][RockMove] = TieResponse;
    results[RockMove][PaperMove] = LoseResponse;
    results[RockMove][ScissorsMove] = WinResponse;
    results[PaperMove][RockMove] = WinResponse;
    results[PaperMove][PaperMove] = TieResponse;
    results[PaperMove][ScissorsMove] = LoseResponse;
    results[ScissorsMove][RockMove] = LoseResponse;
    results[ScissorsMove][PaperMove] = WinResponse;
    results[ScissorsMove][ScissorsMove] = TieResponse;

    // Wait for players
    Receive(&player1, &player1Request, sizeof(player1Request));
    ASSERT(SignupRequest == player1Request.type);

    Receive(&player2, &player2Request, sizeof(player2Request));
    ASSERT(SignupRequest == player2Request.type);

    // Let the players know the game is about to start
    Reply(player1, NULL, 0);
    Reply(player2, NULL, 0);

    // Start the game
    while(1)
    {
        bwprintf(BWCOM2, "Server: Starting match \r\n");

        // Wait for hands from both players
        Receive(&player1, &player1Request, sizeof(player1Request));
        Receive(&player2, &player2Request, sizeof(player2Request));

        // Figure out who won
        if(PlayRequest == player1Request.type &&
           PlayRequest == player2Request.type)
        {
            RPS_SERVER_RESPONSE player1Response = results[player1Request.move][player2Request.move];
            RPS_SERVER_RESPONSE player2Response = results[player2Request.move][player1Request.move];

            Reply(player1, &player1Response, sizeof(player1Response));
            Reply(player2, &player2Response, sizeof(player2Response));
        }
        else
        {
            break;

        }

        // Wait for clients to print out results
        Receive(&player1, NULL, 0);
        Receive(&player2, NULL, 0);
        Reply(player1, NULL, 0);
        Reply(player2, NULL, 0);

        // Wait for the TA before starting another round
        bwprintf(BWCOM2, "Server: Match over. Press any key to start next match \r\n\r\n");
        bwgetc(BWCOM2);
    }

    // Looks like someone quit
    if(QuitRequest == player1Request.type &&
       QuitRequest == player2Request.type)
    {
        RpsServerHandleBothPlayersQuitting(player1, player2);
    }
    else if(QuitRequest == player1Request.type)
    {
        RpspServerHandleOnePlayerQuitting(player1, player2);
    }
    else if(QuitRequest == player2Request.type)
    {
        RpspServerHandleOnePlayerQuitting(player2, player1);
    }
    else
    {
        ASSERT(FALSE);
    }
}
예제 #27
0
파일: rpsserver.c 프로젝트: aianus/trains
void rps_server () {

    RegisterAs("RPSServer");

    RPSMessage msg, reply;
    tid_t tid;

    unsigned int num_matches = MAX_TASKS/2 + 1;

    RPSMatch matches[num_matches];

    unsigned int i;
    for (i = 0; i < num_matches; ++i) {
        reset_match_spot(&matches[i]);
    }

    struct circular_queue waiting_for_match;
    circular_queue_initialize(&waiting_for_match);


    RPSMatch *match;

    while (1) {
//        bwprintf(COM2, "RPS Server waiting for message\n");

        // Receive a request and process it
        Receive(&tid, (char *) &msg, sizeof(msg));

        switch (msg.type) {
        case SIGNUP:
 //           bwprintf(COM2, "RPS Server got a signup from %d\n", tid);
            // Put the task on the queue
            circular_queue_push(&waiting_for_match, (void *) tid);
            // If there are two tasks on the queue, pop them off to create a pair
            if (2 == circular_queue_size(&waiting_for_match)) {
                RPSMatch *match = find_free_match_spot(matches, num_matches);
                match->task1 = (tid_t) circular_queue_pop(&waiting_for_match);
                match->task2 = (tid_t) circular_queue_pop(&waiting_for_match);
                reply.type = GOAHEAD;
                Reply(match->task1, (char *) &reply, sizeof(reply));
                Reply(match->task2, (char *) &reply, sizeof(reply));
            }
            break;
        case PLAY:
//            bwprintf(COM2, "RPS Server got a play of %d from %d\n", msg.move, tid);
            // Check that the task is in a pair and we're expecting a play
            match = find_match_containing_tid(matches, num_matches, tid);
            // Register the play
            if (tid == match->task1) {
                match->t1Move = msg.move;
            } else {
                match->t2Move = msg.move;
            }

//            bwprintf(COM2, "\n\n\nStored Moves Are: \n");
//            bwprintf(COM2, "%d Move: %d and %d Move: %d\n\n\n", match->task1, match->t1Move, match->task2, match->t2Move);
            // If both tasks in the pair have played, reply with the result
            if (match->t1Move != NONE && match->t2Move != NONE) {
                RPSMessage t1Reply;
                RPSMessage t2Reply;

                t1Reply.type = t2Reply.type = RESULT;

                if (match->t1Move == FORFEIT) {
                    t2Reply.result = FORFEIT;
                    Reply(match->task2, (char *) &t2Reply, sizeof(t2Reply));
                    reset_match_spot(match);
                    break;
                } else if (match->t2Move == FORFEIT) {
                    t1Reply.result = FORFEIT;
                    Reply(match->task1, (char *) &t1Reply, sizeof(t1Reply));
                    reset_match_spot(match);
                    break;
                }

                unsigned int winner = 0;
                if (ROCK == match->t1Move) {
                    if (ROCK == match->t2Move) {
                        winner = 0;
                    }
                    else if (PAPER == match->t2Move) {
                        winner = 2;
                    } else if (SCISSORS == match->t2Move) {
                        winner = 1;
                    }
                } else if (PAPER == match->t1Move) {
                    if (ROCK == match->t2Move) {
                        winner = 1;
                    }
                    else if (PAPER == match->t2Move) {
                        winner = 0;
                    } else if (SCISSORS == match->t2Move) {
                        winner = 2;
                    }
                } else if (SCISSORS == match->t1Move) {
                    if (ROCK == match->t2Move) {
                        winner = 2;
                    }
                    else if (PAPER == match->t2Move) {
                        winner = 1;
                    } else if (SCISSORS == match->t2Move) {
                        winner = 0;
                    }
                }

                switch (winner) {
                case 0:
                    t1Reply.result = t2Reply.result = DRAW;
                    break;
                case 1:
                    t1Reply.result = WIN;
                    t2Reply.result = LOSE;
                    break;
                case 2:
                    t1Reply.result = LOSE;
                    t2Reply.result = WIN;
                    break;
                }
                bwprintf (COM2,
                          "Round ended with %d playing %s and %d playing %s\n",
                          match->task1,
                          MOVE_STRINGS[match->t1Move],
                          match->task2,
                          MOVE_STRINGS[match->t2Move]);
                bwprintf (COM2,
                          "Press any key to continue ");
                bwgetc(COM2);
                bwputc(COM2, '\n');
                match->t1Move = match->t2Move = NONE;
                Reply(match->task1, (char *) &t1Reply, sizeof(t1Reply));
                Reply(match->task2, (char *) &t2Reply, sizeof(t2Reply));
            }
            break;
        case QUIT:
            //bwprintf(COM2, "RPS Server got a QUIT from %d\n", tid);
            match = find_match_containing_tid(matches, num_matches, tid);
            if (match->task1 == tid) {
                match->t1Move = FORFEIT;
                if (match->t2Move == FORFEIT) {
                    reset_match_spot(match);
                }
            } else {
                match->t2Move = FORFEIT;
                if (match->t1Move == FORFEIT) {
                    reset_match_spot(match);
                }
            }
            reply.type = QUIT;
            Reply(tid, (char*) &reply, sizeof(reply));
            break;
        default:
            // Error or something
            break;
        }
    }

    Exit();
}
예제 #28
0
파일: reserve.c 프로젝트: shepheb/kernel
// reservation server protocol:
// send a MSG_RESERVE_REQUEST with the list of nodes you want to reserve
// if blocking, you'll block until the nodes are all available, at which point you'll get an ok
// if non-blocking, you'll immediately either get an ok or a fail, depending on whether the request is satisfiable
// when you want to unreserve, send a MSG_RESERVE_RELEASE with the nodes you want to release; you'll get NOTHING BACK
void reservation_server(void) {

	// allocate a list of blocked tasks and the requests they made
	BlockList bl[MAX_ENGINEERS];
	// initialize all of the bl elements to invalid
	int blIndex;
	for (blIndex=0; blIndex<MAX_ENGINEERS; blIndex++) {
		bl[blIndex].tid = -1; // tid == -1 means invalid
	}


	// deadlock detection algorithm:
	// * maintain hold list (hl) in addition to bl.
	// * accomodateRequest also returns a list of engineers I'm waiting on
	// * if I do need to block, this list is necessarily non-empty
	// * then check the block lists for these same engineers and see if they're blocked on anything I hold
	// * if so, that's a deadlock.
	// but there's no way I can implement this tonight.


	RegisterAs("reservationserver");

	FOREVER {

		// receive buffers
		int tid;
		MsgReservation request;
		MsgReservation reply;

		Receive(&tid, (char *)&request, sizeof(MsgReservation));

		switch(request.type) {

			case MSG_RESERVE_REQUEST_BLOCKING: ;
				Node *rcNode = resConflict(request.numNodes, request.nodes, tid);
				if (rcNode == NULL) { // if the request can be accomodated, log it
					logReservation(request.numNodes, request.nodes, tid, request.iAmPacman, request.trainNum, request.curDir);
				} else { // else if the request cannot be accomodated
					// deadlock detection

					printf0("Res Serv.: Checking for deadlock...\n\r");

					// the tid of the task that currently has this reservation
					int otherTid = (rcNode->type == NODE_SWITCH) ? ((Switch *)(rcNode))->reserverTid : ((Sensor *)(rcNode))->reserverTid;
					int blIndex = findTidInBlockList(otherTid, bl);

					printf2("Res Serv.: otherTid: %d, otherIsblocked? %d!\n\r", otherTid, blIndex != -1);

					// if this other tid is blocked and wants a node we own, that's a deadlock
					if (blIndex != -1 && blWantsNodeHeldBy(bl[blIndex], tid)) {

						// we now know we have a deadlock, so it's time to resolve it
						printf2("Res Serv.: DEADLOCK between tr. %d and tr. %d!\n\r", request.trainNum, bl[blIndex].trainNum);

						// if we're the pacman or
						// the other one isn't a pacman and we have the lower train number
						if (request.iAmPacman ||
							(!((rcNode->type == NODE_SWITCH) ? ((Switch *)rcNode)->reserverIAmPacman : ((Sensor *)rcNode)->reserverIAmPacman)
								&& (request.trainNum <= ((rcNode->type == NODE_SWITCH) ? ((Switch *)rcNode)->reserverTrainNum : ((Sensor *)rcNode)->reserverTrainNum) ))) {

							// find a node to move to
							Node *nodeToMoveTo = moveAway(request.trainLoc, request.curDir == 'F' ? 'B' : 'F');

							printf1("Res Serv.: GTFO self (train %d) to ", request.trainNum);
							if (nodeToMoveTo == NULL) {
								printf0("NULL");
							} else {
								printNode2(nodeToMoveTo);
							}
							printf1(", curDir %c!\n\r", (int)request.curDir);

							if (nodeToMoveTo == NULL) { // if we can't move away, it's the game over case
								printf0("res. serv.: case 1.\n\r");

								int pacmanServerTid = WhoIs("pacmanserver");
								char c = MSG_PACMAN_GAMEOVER;
								int retVal = Send(pacmanServerTid, &c, 1, NULL, 0);
								printf1("res. serv.: retVal from Reply to PMS: %d\n\r", retVal);

								reply.type = MSG_RESERVE_GAMEOVER;
								retVal = Reply(tid, (char *)&reply, sizeof(MsgReservation));
								printf1("res. serv.: retVal from Reply to train: %d\n\r", retVal);

								int i;
								for (i=0; i<MAX_ENGINEERS; i++) {
									if (bl[i].tid != -1) {
										reply.type = MSG_RESERVE_GAMEOVER;
										retVal = Reply(bl[blIndex].tid, (char *)&reply, sizeof(MsgReservation));
										printf1("res. serv.: retVal from Reply to train: %d\n\r", retVal);
									}
								}
							} else { // else if we can move away, send the move reply
								reply.type = MSG_RESERVE_MOVE;
								reply.numNodes = 1;
								reply.nodes[0] = nodeToMoveTo;
								printf0("res. serv.: about to reply case 2.\n\r");
								int retVal = Reply(tid, (char *)&reply, sizeof(MsgReservation));
								printf1("res. serv.: retVal from Reply to train: %d\n\r", retVal);
							}

						} else { // else the other train needs to move out of the way

							// find a node to move to
							Node *nodeToMoveTo = moveAway(bl[blIndex].trainLoc, bl[blIndex].curDir == 'F' ? 'B' : 'F');

							printf1("Res Serv.: GTFO other (train %d) to ", bl[blIndex].trainNum);
							if (nodeToMoveTo == NULL) {
								printf0("NULL");
							} else {
								printNode2(nodeToMoveTo);
							}
							printf1(", curDir %c!\n\r", (int)bl[blIndex].curDir);

							if (nodeToMoveTo == NULL) { // if we can't move away, it's the game over case
								printf0("res. serv.: case 1.\n\r");

								int pacmanServerTid = WhoIs("pacmanserver");

								char c = MSG_PACMAN_GAMEOVER;
								int retVal = Send(pacmanServerTid, &c, 1, NULL, 0);
								printf1("res. serv.: retVal from Reply to PMS: %d\n\r", retVal);

								reply.type = MSG_RESERVE_GAMEOVER;
								retVal = Reply(tid, (char *)&reply, sizeof(MsgReservation));
								printf1("res. serv.: retVal from Reply to train: %d\n\r", retVal);

								int i;
								for (i=0; i<MAX_ENGINEERS; i++) {
									if (bl[i].tid != -1) {
										reply.type = MSG_RESERVE_GAMEOVER;
										retVal = Reply(bl[blIndex].tid, (char *)&reply, sizeof(MsgReservation));
										printf1("res. serv.: retVal from Reply to train: %d\n\r", retVal);
									}
								}

							} else { // else if we can move away, send the move reply

								reply.type = MSG_RESERVE_MOVE;
								reply.numNodes = 1;
								reply.nodes[0] = nodeToMoveTo;
								printf0("res. serv.: about to reply case 2.\n\r");
								int retVal = Reply(bl[blIndex].tid, (char *)&reply, sizeof(MsgReservation));
								printf1("res. serv.: retVal from Reply to train: %d\n\r", retVal);

								// remove the other train from the block list, since he's no longer going to be blocked
								bl[blIndex].tid = -1;

								// now, block the current train, waiting for the other one to get ouf of the way
								blockTask(tid, request.iAmPacman, request.trainNum, request.trainLoc, request.curDir, request.numNodes, request.nodes, bl);
							}
						}

					} else { // else if it's not a deadlock, just a reservation conflict, handle it normally by blocking
						blockTask(tid, request.iAmPacman, request.trainNum, request.trainLoc, request.curDir, request.numNodes, request.nodes, bl);
					}
				}
				break;
			case MSG_RESERVE_REQUEST_NONBLOCKING:
				if (resConflict(request.numNodes, request.nodes, tid) == NULL) { // if the request can be accomodated, log it and reply
					logReservation(request.numNodes, request.nodes, tid, request.iAmPacman, request.trainNum, request.curDir);
					reply.type = MSG_RESERVE_OK;
					Reply(tid, (char *)&reply, sizeof(MsgReservation));
				} else { // else if the request cannot be accomodated, send a fail message back
					reply.type = MSG_RESERVE_FAIL;
					Reply(tid, (char *)&reply, sizeof(MsgReservation));
				}
				break;
			case MSG_RESERVE_RELEASE:
				logRelease(request.numNodes, request.nodes, request.trainNum); // log the release
				Reply(tid, NULL, 0); // reply with a NULL buffer
				// now, check if any waiting task can now be awoken due to the release
				for (blIndex = 0; blIndex<MAX_ENGINEERS; blIndex++) {
					// if the bl entry is valid and we can now accomodate it, do so
					if (bl[blIndex].tid != -1 && resConflict(bl[blIndex].numNodes, bl[blIndex].nodes, bl[blIndex].tid) == NULL) {
						// log the reservation
						logReservation(bl[blIndex].numNodes, bl[blIndex].nodes, bl[blIndex].tid, bl[blIndex].iAmPacman, bl[blIndex].trainNum, bl[blIndex].curDir);
						// reply to the task, telling it the reserve has finally been processed
						reply.type = MSG_RESERVE_OK;
						Reply(bl[blIndex].tid, (char *)&reply, sizeof(MsgReservation));
						// ...and invalidate its entry in the block list
						bl[blIndex].tid = -1;
					}
				}
				break;
			default:
				bwprintf(COM2, "ERROR: illegal reservation request type %d! Halt!!!", request.type);
				Halt();
				break;
		} // switch
	} // FOREVER

	return; // can't happen due to above FOREVER loop
}
예제 #29
0
파일: main.c 프로젝트: mercurycc/cs452
void RPSServer() {
	char* rps_server_play_names[ 3 ];
	int quit = 0;
	struct Group group[32] = {{0}};
	int index = 0;
	int signup_waiter = -1;
	int winner = 0;
	int status;
	int i = 0;

	rps_server_play_names[ 0 ] = "ROCK";
	rps_server_play_names[ 1 ] = "PAPER";
	rps_server_play_names[ 2 ] = "SCISSORS";
	
	
	bwprintf( COM2, "RPS Server start.\n" );

	for ( i = 0; i < 32; i++ ){
		group[i].occupied = 0;
	}

	/* Register */
	status = RegisterAs( "RPSServer" );
	assert( status == 0 );

	while ( !quit ) {
		int tid;
		struct RPSmsg msg;
		struct RPSreply reply;
		int status = 0;

		status = Receive( &tid, (char*)&msg, sizeof( msg ) );
		assert( status == sizeof( msg ) );

		// parse command
		switch ( msg.command ) {
		case SUICIDE:
			if ( tid != MyParentTid() ){
				bwprintf( COM2, "Receive fake suicide command from task 0x%x\n", tid );
			} else {
				quit = 1;
				/* At this point all clients should have already quited */
				reply.result = RESULT_QUIT;
				status = Reply( tid, ( char* )&reply, sizeof( reply ) );
				assert( status == SYSCALL_SUCCESS );
			}
			break;
		case SIGN_UP:
			if ( signup_waiter == -1 ) {
				signup_waiter = tid;
			} else {
				index = 0;
				while ( ( index < 32 ) && group[index].occupied ){
					index++;
				}
				if ( index >= 32 ) {
					bwprintf( COM2, "server full.\n" );
				}

				group[index].p = 0;
				group[index].occupied = 1;
				group[index].c = 0;

				reply.result = index;
				status = Reply( signup_waiter, (char*)&reply, sizeof( reply ) );
				DEBUG_PRINT( DBG_USER, "return status = %d\n", status );
				assert( status == SYSCALL_SUCCESS );
				status = Reply( tid, (char*)&reply, sizeof( reply ) );
				assert( status == SYSCALL_SUCCESS );

				/* Reset signup_waiter */
				signup_waiter = -1;
			}
			break;
		case QUIT:
		case ROCK:
		case PAPER:
		case SCISSORS:
			index = msg.group_num;
			if ( group[index].c ) {
				winner = ( ( group[index].c + 1 ) - ( msg.command - 2 ) ) % 3;
				if ( ( group[index].c == QUIT ) || ( msg.command == QUIT ) ) {
					// both quit
					reply.result = RESULT_QUIT;
					status = Reply( group[index].p, (char*)&reply, sizeof( reply ) );
					assert( status == SYSCALL_SUCCESS );
					status = Reply( tid, (char*)&reply, sizeof( reply ) );
					assert( status == SYSCALL_SUCCESS );
				} else if ( winner == 1 ) {
					reply.result = RESULT_WIN;
					status = Reply( group[index].p, (char*)&reply, sizeof( reply ) );
					assert( status == SYSCALL_SUCCESS );
					reply.result = RESULT_LOSE;
					status = Reply( tid, (char*)&reply, sizeof( reply ) );
					assert( status == SYSCALL_SUCCESS );
				} else if ( winner == 2 ) {
					reply.result = RESULT_LOSE;
					status = Reply( group[index].p, (char*)&reply, sizeof( reply ) );
					assert( status == SYSCALL_SUCCESS );
					reply.result = RESULT_WIN;
					status = Reply( tid, (char*)&reply, sizeof( reply ) );
					assert( status == SYSCALL_SUCCESS );
				} else {
					// draw
					reply.result = RESULT_DRAW;
					status = Reply( group[index].p, (char*)&reply, sizeof( reply ) );
					assert( status == SYSCALL_SUCCESS );
					status = Reply( tid, (char*)&reply, sizeof( reply ) );
					assert( status == SYSCALL_SUCCESS );
				}

				if( ( group[index].c == QUIT ) || ( msg.command == QUIT ) ){
					bwprintf( COM2, "[ Server ] Group %d requested quit\n", index );
				} else {
					bwprintf( COM2, "[ Server ] Group %d player %d bet %s, player %d bet %s ",
						  index,
						  group[ index ].p, rps_server_play_names[ group[ index ].c - ROCK ],
						  tid, rps_server_play_names[ msg.command - ROCK ] );
					if( winner == 1 ){
						bwprintf( COM2, "winner %d\n", group[ index ].p );
					} else if( winner == 2 ) {
						bwprintf( COM2, "winner %d\n", tid );
					} else {
						bwprintf( COM2, "draw\n" );
					}
				}
				
				/* Pause */
				bwgetc( COM2 );
				
				group[index].p = 0;
				group[index].c = 0;
			} else {
				group[index].p = tid;
				group[index].c = msg.command;
			}
			break;
		default:
			bwprintf( COM2, "Invalid command: 0x%x\n", msg.command );
			break;
		}
	}

	bwprintf( COM2, "RPS Server exit.\n" );
	Exit();
}
예제 #30
0
static void sensorServer() {
  char com1Name[] = IOSERVERCOM1_NAME;
  int com1 = WhoIs(com1Name);

  char sensorName[] = SENSOR_NAME;
  RegisterAs(sensorName);

  int i, j;
  CURR_SENSOR_BOX = 0;
  CURR_HIGH_BITS = 0;
  responseIndex = 0;
  for (i = 0; i < NUM_SENSOR_BOX; ++i) {
    for (j = 0; j < 16; ++j) {
      SENSOR_VALUE[i][j] = 0;
    }
  }

  subscriberIndex = 0;
  subscriberUpdateIndex = 0;
  sensorBufferHead = 0;
  sensorBufferTail = 0;

  int queryWorker = Create(7, sensorQueryWorker);
  Create(8, sensorQueryResponseWorker);
  int queryTimeoutWorker = Create(7, sensorQueryTimeoutWorker);
  int queryResponseTimeoutWorker = Create(7, sensorQueryResponseTimeoutWorker);
  int courier  = Create(7, sensorCourier);

  int queryWorkerReady = 0;
  int queryTimeout = 0;
  int queryResponseTimeout = 0;
  int startQueryResponseTimeout = 0;
  int courierReady = 0;

  char timerName[] = TIMESERVER_NAME;
  int timer = WhoIs(timerName);

  IGNORE_RESULT = 1;

  // sensor server is time sensitive, it delays and tries
  // to avoid the initialization period where there are
  // a lot of chars in com1 buffer
  Delay(700, timer);

  // Clear sensor memory after reading.
  Putc(com1, 192);
  // end init

  for ( ;; ) {
    if (queryTimeout && queryWorkerReady) {
      queryTimeout = 0;
      queryWorkerReady = 0;
      Reply(queryWorker, (char *)NULL, 0);
      Reply(queryTimeoutWorker, (char *)NULL, 0);
    }

    int tid = -1;
    SensorMsg msg;
    Receive(&tid, (char*)&msg, sizeof(SensorMsg));
    switch (msg.type) {
      case QUERY_WORKER: {
        queryWorkerReady = 1;
        break;
      }
      case QUERY_RESPONSE_WORKER: {
        Reply(tid, (char *)NULL, 0);
        char response = msg.data;
        if (responseIndex == 0) {
          if (queryResponseTimeout) {
            queryResponseTimeout = 0;
            Reply(queryResponseTimeoutWorker, (char *)NULL, 0);
          } else {
            startQueryResponseTimeout = 1;
          }
        }
        responseBuffer[responseIndex++] = response;
        if (responseIndex == 10) {
          for (int i = 0; i < 10; i++) {
            sensorResponded(responseBuffer[i], msg.time);
          }
          responseIndex = 0;
        }
        break;
      }
      case QUERY_TIMEOUT_WORKER: {
        queryTimeout = 1;
        break;
      }
      case QUERY_RESPONSE_TIMEOUT_WORKER: {
        if (startQueryResponseTimeout) {
          startQueryResponseTimeout = 0;
          Reply(queryResponseTimeoutWorker, (char *)NULL, 0);
        } else {
          queryResponseTimeout = 1;
          responseIndex = 0;
          CURR_SENSOR_BOX = 0;
          CURR_HIGH_BITS = 0;
        }
        break;
      }
      case QUERY_RECENT: {
        sensorSubscriber[subscriberIndex++] = tid;
        Reply(tid, (char *)NULL, 0);
        break;
      }
      case SENSOR_COURIER: {
        courierReady = 1;
        break;
      }
      case FAKE_TRIGGER: {
        Reply(tid, (char *)NULL, 0);
        Sensor s;
        s.box = msg.box;
        s.val = msg.data;
        s.time = msg.time;
        add_to_buffer(s);
        break;
      }
      default: {
        ASSERT(FALSE, "invalid sensor msg type.");
      }
    }

    if (courierReady && !buffer_empty() && subscriberIndex != 0) {
      Sensor s = sensorBuffer[sensorBufferTail];

      SensorWorkUnit work;
      work.sensor = s;
      work.tid = sensorSubscriber[subscriberUpdateIndex++];

      Reply(courier, (char *)&work, sizeof(SensorWorkUnit));
      if (subscriberUpdateIndex == subscriberIndex) {
        subscriberUpdateIndex = 0;
        remove_from_buffer();
      }
    }
  }
}