void idle_task_code(void) { volatile int i = 0; while(1) { i++; char c = bwgetc(COM2); if (c =='q') break; } kprintf("Idle task exits\n\r"); Exit(); }
int Getc(int channel) { /* To be implemented later char c; int i; i = WhoIs("serial"); Send(1, ); */ return bwgetc(channel); }
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(); }
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(); }
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); } }