/* run : worker thread for ball control along with AI generation */ void run(void *vsocket){ int sock = *(int *)&vsocket; int echolen; RTIME sleep; // as nano-seconds if(ballThreadSpeed % 6 == 0) ballThreadSpeed++; sleep = (RTIME)(50000000 / (ballThreadSpeed % 6)); rt_task_suspend(NULL); while (true){ ballmove(); echolen = strlen(ballData); if(send(sock, ballData, echolen, 0) != echolen) rt_err("send()"); if(AIMode){ opponentMovement(AImoveGenerate()); echolen = strlen(moveData[1]); if(send(sock, moveData[1], echolen, 0) != echolen) rt_err("send()"); } if(reset){ resetBall(); echolen = strlen(gameData); if(send(sock, gameData, echolen, 0) != echolen) rt_err("send()"); } if(bounceplayer){ bounceDirection(player,ball.radius); bounceplayer = false; } if(bounceOpponent){ bounceDirection(opponent,ball.radius); bounceOpponent = false; } rt_task_sleep(sleep); } }
/* alarm_handler ** is triggered once 10s is passed to inform player ** wait time has expired - issue start */ void alarm_handler(void *arg) { int sock = *(int *)&arg; int echolen; /* start the countdown */ rt_task_set_periodic(NULL, TM_NOW, 8000000000ULL); rt_task_wait_period(NULL); if(!issuedStart) rt_task_delete(NULL); //not need two players connected rt_mutex_acquire(&autoStart, TM_INFINITE); issuedStart = true; rt_mutex_release(&autoStart); AIMode = true; printf("FORCED START client playing with AI!\n"); /* below we emulate the add, start */ addPong(); echolen = strlen(pongData[0]); if(send(sock, pongData[0],echolen, 0) != echolen) rt_err("send()"); echolen = strlen(pongData[1]); if(send(sock, pongData[1],echolen, 0) != echolen) rt_err("send()"); start(); echolen = strlen(gameData); if(send(sock, gameData, echolen, 0) != echolen) rt_err("send()"); echolen = strlen(ballData); if(send(sock, ballData, echolen, 0) != echolen) rt_err("send()"); if(rt_task_resume(&recvThread[0])) rt_err("rt_task_resume()"); if(rt_task_resume(&ballThread)) rt_err("rt_task_resume()"); }
int main(int argc, char **argv) { printf("%s\n","Created Model"); int serversock, clientsock; size_t clientlen; struct sockaddr_in server_addr, client_addr, view_addr[2]; unsigned int port; unsigned int view_port; char *portNum; mlockall(MCL_CURRENT | MCL_FUTURE); signal(SIGKILL, cleanup); if(argc < 1){ usage(*argv); exit(0); } int c; while((c = getopt(argc, argv, "p:b:v:")) != -1){ switch(c){char data[1024]; case 'p': port = atoi(strdup(optarg)); break; case 'v': view_port = atoi(strdup(optarg)); break; /* many potential super fast speeds can be achieved */ case 'b': ballThreadSpeed = atoi(optarg) > 0 ? atoi(optarg) : BTHREAD_RATIO; break; default: usage(*argv); exit(0); break; } } mThreadPid = getpid(); initializePong(); /* if(rt_task_create(&ballThread, "ball_Thread" ,4096, 99, 0)) rt_err("rt_task_create()"); if(rt_task_create(&recvThread[0], "Recv_Thread", 4096, 99, T_JOINABLE)) rt_err("rt_task_create()"); if(rt_task_create(&recvThread[1], "Recv2_Thread", 4096, 99, T_JOINABLE)) rt_err("rt_task_create()"); */ /* task creation */ char temp_ball_Thread[1000]; char temp_Recv_Thread[1000]; char temp_Recv2_Thread[1000]; sprintf(temp_ball_Thread,"BallThread%d",port); sprintf(temp_Recv_Thread,"RecvThread%d",port); sprintf(temp_Recv2_Thread,"RecvThread2%d",port); if(rt_task_create(&ballThread, temp_ball_Thread ,4096, 99, 0)) rt_err("rt_task_create()"); if(rt_task_create(&recvThread[0], temp_Recv_Thread, 4096, 99, T_JOINABLE)) rt_err("rt_task_create()"); if(rt_task_create(&recvThread[1], temp_Recv2_Thread, 4096, 99, T_JOINABLE)) rt_err("rt_task_create()"); /* creation of mutexes for buffer */ unsigned int i = 0; for(; i < 3; i++){ char buf[8]; sprintf(buf, "Mutex %d %d", i, port); if(rt_mutex_create(&txMutex[i], buf)) rt_err("rt_mutex_create()"); } char temp_start_mutex[1000]; sprintf(temp_start_mutex,"AutoStartMutex%d",port); if(rt_mutex_create(&autoStart, temp_start_mutex)) rt_err("rt_mutex_create()"); i = 0; /* socket creation and structure initialization*/ if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) errx(EXIT_FAILURE, "socket()", strerror(-errno)); int yes = 1; if(setsockopt(serversock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1){ perror("Setsockopt"); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(port); /* server port */ if (bind(serversock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0){ close(serversock); errx(EXIT_FAILURE, "bind():", strerror(errno)); } /* listens for Game Controller only*/ if (listen(serversock, 1) < 0) errx(EXIT_FAILURE, "listen():", strerror(-errno)); int viewSocket; if ((viewSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) rt_err("socket()"); /* connection loop */ printf("Waiting for connections ...\n"); while(true){ char *currClient; clientlen = sizeof(struct sockaddr_in); clientsock = accept(serversock, (struct sockaddr *)&client_addr, (socklen_t *)&clientlen); currClient = (char *)inet_ntoa(client_addr.sin_addr); if(i > 1 || (i < 1 && !issuedStart)){ //game in play by force or 2 players close(clientsock); fprintf(stderr, "rejecting %s " "only 2 clients allowed!\n", currClient); continue; } //spawn the receive thread for simulator player_t players[2]; players[i].socket = clientsock; players[i].vsocket = viewSocket; players[i].addr = client_addr; if(rt_task_start(&recvThread[i], recv_data, (void *)&players[i])) rt_err("rt_task_start()"); i++; viewMode++; /* 1st player connected */ if(i == 1){ initSock = clientsock; /* spawn task to countdown */ if(rt_task_spawn(&alarmTask, "AutoStart", 4096, 99, 0, alarm_handler, (void *)viewSocket)) rt_err("rt_task_spawn()"); /* start the ball thread and it handles further movement */ if(rt_task_start(&ballThread, run,(void*)viewSocket)) rt_err("rt_task_start()"); printf("1 Player Connected ...\n"); /* now need to connect to the view */ memset(&view_addr[0], 0, sizeof(view_addr[0])); view_addr[0].sin_family = AF_INET; view_addr[0].sin_addr.s_addr = inet_addr(currClient); view_addr[0].sin_port = htons(view_port); /* Establish connection to view */ if (connect(viewSocket,(struct sockaddr *) &view_addr[0], sizeof(view_addr[0])) < 0) rt_err("connect()"); } /* the case when both players start before one-shot alarm */ if(i == 2){ /*Now need to connect the second view if there is one*/ if ((viewSocket2= socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) rt_err("socket()");/*2 View mode case*/ memset(&view_addr[1], 0, sizeof(view_addr[1])); view_addr[1].sin_family = AF_INET; view_addr[1].sin_addr.s_addr = inet_addr(currClient); view_addr[1].sin_port = htons(view_port); if (connect(viewSocket2,(struct sockaddr *) &view_addr[1], sizeof(view_addr[1])) < 0) rt_err("connect()2"); rt_mutex_acquire(&autoStart, TM_INFINITE); issuedStart = false; rt_mutex_release(&autoStart); rt_task_resume(&recvThread[0]); rt_task_resume(&recvThread[1]); } } //join on receive rt_task_join(&recvThread[0]); rt_task_join(&recvThread[1]); return 0; }
/* alarm_handler ** is triggered once 10s is passed to inform player ** wait time has expired - issue start */ void alarm_handler(void *arg) { int sock = *(int *)&arg; int echolen; /* start the countdown */ rt_task_set_periodic(NULL, TM_NOW, 1000000000ULL); int i; for(i = 15; i >= 0; i--){ rt_task_wait_period(NULL); rt_mutex_acquire(&txMutex[E_WAIT], TM_INFINITE); memset(countData, 0, sizeof(countData)); sprintf(countData, "count;%d;", i); padString(countData); rt_mutex_release(&txMutex[E_WAIT]); echolen = strlen(countData); if(send(sock, countData,echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, countData, echolen, 0) != echolen) rt_err("send()"); } } if(!issuedStart) rt_task_delete(NULL); //not need two players connected rt_mutex_acquire(&autoStart, TM_INFINITE); issuedStart = true; rt_mutex_release(&autoStart); AIMode = true; printf("FORCED START client playing with AI!\n"); /* below we emulate the add, start */ addPong(); echolen = strlen(pongData[0]); if(send(sock, pongData[0],echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, pongData[0], echolen, 0) != echolen) rt_err("send()"); } echolen = strlen(pongData[1]); if(send(sock, pongData[1],echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, pongData[1], echolen, 0) != echolen) rt_err("send()"); } start(); echolen = strlen(gameData); if(send(sock, gameData, echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, gameData, echolen, 0) != echolen) rt_err("send()"); } echolen = strlen(ballData); if(send(sock, ballData, echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, ballData, echolen, 0) != echolen) rt_err("send()"); } if(rt_task_resume(&recvThread[0])) rt_err("rt_task_resume()"); if(rt_task_resume(&ballThread)) rt_err("rt_task_resume()"); }
void recv_data(void *arg) { player_t *client = (player_t *)arg; char buffer[BUFSIZ]; unsigned int echolen; rt_task_suspend(NULL); //will wait on main to signal for(;;){ memset(buffer,0,sizeof(buffer)); int status; if((status = recv(client->socket, buffer, BUFSIZ, 0)) < 0) rt_err("recv()"); /* player cannot start until the given time */ if(!strcmp(buffer,"START")){ start(); /* score initialization from start()*/ echolen = strlen(gameData); if(send(client->vsocket, gameData, echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, gameData, echolen, 0) != echolen) rt_err("send()"); } /* Ball initial position */ echolen = strlen(ballData); if(send(client->vsocket, ballData, echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, ballData, echolen, 0) != echolen) rt_err("send()"); } /* ball Thread can now run */ if(rt_task_resume(&ballThread)) rt_err("rt_task_resume()"); continue; } else if(!strcmp(buffer,"RESET")){ resetScore(); echolen = strlen(gameData); if(send(client->vsocket, gameData, echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, gameData, echolen, 0) != echolen) rt_err("send()"); } continue; } else if(!strcmp(buffer, "ADD")){ addPong(); echolen = strlen(pongData[0]); if(send(client->vsocket, pongData[0],echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, pongData[0], echolen, 0) != echolen) rt_err("send()"); } echolen = strlen(pongData[1]); if(send(client->vsocket, pongData[1],echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, pongData[1], echolen, 0) != echolen) rt_err("send()"); } continue; } /* parsing L(k) and R(k) */ if(client->socket == initSock){ if(!strcmp(buffer, "LEFT") || !strcmp(buffer, "RIGHT")){ move(buffer[0]); //either 'L' or 'R' -> {L/R1} echolen = strlen(moveData[0]); if(send(client->vsocket, moveData[0],echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, moveData[0], echolen, 0) != echolen) rt_err("send()"); } } } else if(client->socket != initSock){ if(!strcmp(buffer,"LEFT") || !strcmp(buffer, "RIGHT")){ opponentMovement(buffer[0]); // {L/R2} echolen = strlen(moveData[1]); if(send(client->vsocket, moveData[1],echolen, 0) != echolen) rt_err("send()"); /*2 View mode case*/ if(viewMode > 1){ if(send(viewSocket2, moveData[1], echolen, 0) != echolen) rt_err("send()"); } } } /* TODO Cases to think about 1. need 2 alert other players about P(X) exiting 2. close this socket, potentially alert main that another client can connect 3. ^ if possible pause game save state -> MILESTONE 3 */ if(!strcmp(buffer,"EXIT")){ char data[1024]; printf("%d","A"); //recv(client->vsocket,data,sizeof(data),0); kill(mThreadPid, SIGKILL); } } }
// do a depth-first or breadth-first search in state space up to specified depth // bfs: boolean flag if to do a breadth-first seach (depth_max is ignored in this case) // buffer_len: size of state buffer // hash_entries, hash_retries: parameters of hash table to finf duplicate states // graph_out: if != NULL state graph will be output to this tream in graphviz dot format // print_hex: if to print states in hex // ini_state: state to start simulation at (or NULL to use default) void search (nipsvm_bytecode_t *bytecode, int bfs, unsigned int depth_max, unsigned long buffer_len, unsigned long hash_entries, unsigned long hash_retries, FILE *graph_out, int print_hex, nipsvm_state_t *ini_state) // extern { char *p_buffer, *p_buf; t_hashtab hashtab; unsigned long buf_len; nipsvm_state_t *state; st_search_context ctx; struct timeval time_start, time_end, time_diff; double us_state; // allocate buffer for states p_buffer = (char *)malloc( buffer_len ); if( p_buffer == NULL ) rt_err( "out of memory (state buffer for search)" ); p_buf = p_buffer; buf_len = buffer_len; // allocate hash table hashtab = hashtab_new( hash_entries, hash_retries ); if( hashtab == NULL ) rt_err( "out of memory (hash table)" ); // tell user to wait if( bfs ) printf( "doing breadth-first search, please wait...\n" ); else printf( "doing depth-first search up to depth %u, please wait...\n", depth_max ); // remember start time gettimeofday( &time_start, NULL ); // set up context for successor state generation nipsvm_init (&ctx.nipsvm, bytecode, &search_succ_cb, &search_err_cb); // get initial state if( ini_state == NULL ) { ini_state = nipsvm_initial_state (&ctx.nipsvm); } // insert initial state into table { size_t sz = nipsvm_state_size (ini_state); state = nipsvm_state_copy (sz, ini_state, &p_buf, &buf_len); hashtab_insert (hashtab, sz, ini_state); } // set up rest of context for search ctx.depth_max = depth_max; ctx.depth_reached = 0; ctx.state_cnt = 0; ctx.transition_cnt = 0; ctx.n_atomic_steps = 0; ctx.max_state_size = 0; ctx.p_buf = p_buf; ctx.buf_len = buf_len; ctx.hashtab = hashtab; ctx.error = 0; ctx.graph_out = graph_out; ctx.graph_out_pred = state; ctx.print_hex = print_hex; // start search if( bfs ) search_internal_bfs( state, &ctx ); else search_internal_dfs_to_depth( state, 0, &ctx ); nipsvm_finalize (&ctx.nipsvm); // update pointer and length of state buffer p_buf = ctx.p_buf; buf_len = ctx.buf_len; // remember end time gettimeofday( &time_end, NULL ); // get time difference time_diff.tv_usec = time_end.tv_usec - time_start.tv_usec; time_diff.tv_sec = time_end.tv_sec - time_start.tv_sec; if( time_diff.tv_usec < 0 ) { time_diff.tv_usec += 1000000; time_diff.tv_sec--; } // get time per state (in microseconds) us_state = ((double)time_diff.tv_sec * 1000000.0 + (double)time_diff.tv_usec) / (double)ctx.state_cnt; // print statistics table_statistics_t t_stats; table_statistics (hashtab, &t_stats); unsigned long used_buffer_space = buffer_len - buf_len; double table_fill_ratio = 100.0 * (double)t_stats.entries_used / (double)t_stats.entries_available; double state_memory_fill_ratio = 100.0 * (double)used_buffer_space / (double)buffer_len; printf( "\n" ); if( bfs ) printf( "breadth-first search %s:\n", ctx.error ? "aborted" : "completed" ); else printf( "depth-first search up to depth %u %s:\n", depth_max, ctx.error ? "aborted" : "completed" ); printf( " states visited: %lu\n", ctx.state_cnt ); printf( " transitions visited: %lu\n", ctx.transition_cnt ); printf( " atomic steps: %lu\n", ctx.n_atomic_steps ); printf( " maximum state size: %u\n", ctx.max_state_size ); if( ! bfs ) printf( " reached depth: %u\n", ctx.depth_reached ); printf( " total time: %lu.%06lu s\n" " time per state: %f us\n", time_diff.tv_sec, (unsigned long)time_diff.tv_usec, us_state ); printf( "\n" ); printf( "state memory statistics:\n" ); printf( " total: %0.2fMB\n", buffer_len / 1048576.0 ); printf( " used: %0.2fMB (%0.1f%%)\n", used_buffer_space / 1048576.0, state_memory_fill_ratio ); printf( "\n" ); printf( "state table statistics:\n" " memory usage: %0.2fMB\n", t_stats.memory_size / 1048576.0 ); printf( " buckets used/available: %lu/%lu (%0.1f%%)\n", t_stats.entries_used, t_stats.entries_available, table_fill_ratio ); printf( " max. no. of retries: %lu\n", t_stats.max_retries ); printf( " conflicts (resolved): %lu\n", t_stats.conflicts ); // free state buffer and hash table free( p_buffer ); hashtab_free( hashtab ); }
int main(int argc, char **argv) { int serversock, clientsock; size_t clientlen; struct sockaddr_in server_addr, client_addr, view_addr; unsigned int port = MODEL_DEFAULT_PORT; //models and view iff on same cpu char *ipAddress; mlockall(MCL_CURRENT | MCL_FUTURE); if(argc < 3){ usage(*argv); exit(0); } int c; while((c = getopt(argc, argv, "i:b:")) != -1){ switch(c){ case 'i': ipAddress = strdup(optarg); break; /* many potential super fast speeds can be achieved */ case 'b': ballThreadSpeed = atoi(optarg) > 0 ? atoi(optarg) : BTHREAD_RATIO; break; default: usage(*argv); exit(0); break; } } initializePong(); /* task creation */ if(rt_task_create(&ballThread, "BallThread", 4096, 99, 0)) rt_err("rt_task_create()"); if(rt_task_create(&recvThread[0], "RecvThread", 4096, 99, T_JOINABLE)) rt_err("rt_task_create()"); if(rt_task_create(&recvThread[1], "RecvThread1", 4096, 99, T_JOINABLE)) rt_err("rt_task_create()"); /* creation of mutexes for buffer */ unsigned int i = 0; for(; i < 3; i++){ char buf[8]; sprintf(buf, "Mutex %d", i); if(rt_mutex_create(&txMutex[i], buf)) rt_err("rt_mutex_create()"); } if(rt_mutex_create(&autoStart, "AutoStartMutex")) rt_err("rt_mutex_create()"); i = 0; /* socket creation and structure initialization*/ if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) errx(EXIT_FAILURE, "socket()", strerror(-errno)); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; /* Internet/IP */ server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(port); /* server port */ if (bind(serversock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0){ close(serversock); errx(EXIT_FAILURE, "bind():", strerror(errno)); } /* listens for Game Controller only*/ if (listen(serversock, 1) < 0) errx(EXIT_FAILURE, "listen():", strerror(-errno)); /* now need to connect to the view */ int viewSocket; if ((viewSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) rt_err("socket()"); memset(&view_addr, 0, sizeof(view_addr)); view_addr.sin_family = AF_INET; view_addr.sin_addr.s_addr = inet_addr(ipAddress); view_addr.sin_port = htons(VIEW_DEFAULT_PORT); /* Establish connection to view */ if (connect(viewSocket, (struct sockaddr *) &view_addr, sizeof(view_addr)) < 0) rt_err("connect()"); /* connection loop */ printf("Waiting for connections ...\n"); while(true){ char *currClient; clientlen = sizeof(struct sockaddr_in); clientsock = accept(serversock, (struct sockaddr *)&client_addr, (socklen_t *)&clientlen); currClient = (char *)inet_ntoa(client_addr.sin_addr); if(i > 1 || (i < 1 && !issuedStart)){ //game in play by force or 2 players close(clientsock); fprintf(stderr, "rejecting %s " "only 2 clients allowed!\n", currClient); continue; } //spawn the receive thread for simulator player_t players[2]; players[i].socket = clientsock; players[i].vsocket = viewSocket; players[i].addr = client_addr; if(rt_task_start(&recvThread[i], recv_data, (void *)&players[i])) rt_err("rt_task_start()"); i++; /* 1st player connected */ if(i == 1){ initSock = clientsock; /* spawn task to countdown */ if(rt_task_spawn(&alarmTask, "AutoStart", 4096, 99, 0, alarm_handler, (void *)viewSocket)) rt_err("rt_task_spawn()"); /* start the ball thread and it handles further movement */ if(rt_task_start(&ballThread, run,(void*)viewSocket)) rt_err("rt_task_start()"); printf("1 Player Connected ...\n"); } /* the case when both players start before one-shot alarm */ if(i == 2){ rt_mutex_acquire(&autoStart, TM_INFINITE); issuedStart = false; rt_mutex_release(&autoStart); rt_task_resume(&recvThread[0]); rt_task_resume(&recvThread[1]); } } //join on receive rt_task_join(&recvThread[0]); rt_task_join(&recvThread[1]); return 0; }