PUBLIC void vm_restore_from(FILE *f, int load_threads) { void *handle = start_load(f); symtab = (VECTOR) load(handle); if (load_threads) load_restartable_threads(handle, f); end_load(handle); }
// // This function is called to calibrate the "background load" which can be // applied during testing. It will be called before any commands from the // host are managed. // static void calibrate_load(int desired_load) { long long no_load_idle, load_idle; int percent_load; int high, low; // Set limits high = MAX_LOAD_THREAD_LEVEL; low = MIN_LOAD_THREAD_LEVEL; test_printf("Start Network Characterization - SLAVE\n"); // Compute the "no load" idle value idle_thread_count = 0; cyg_semaphore_post(&idle_thread_sem); // Start idle thread test_printf("Start Network Characterization - SLAVE\n"); cyg_thread_delay(1*100); // Pause for one second test_printf("Start Network Characterization - SLAVE\n"); cyg_semaphore_wait(&idle_thread_sem); // Stop idle thread test_printf("Start Network Characterization - SLAVE\n"); no_load_idle = idle_thread_count; diag_printf("No load = %d\n", (int)idle_thread_count); // First ensure that the HIGH level is indeed higher while (true) { load_thread_level = high; start_load(desired_load); // Start up a given load idle_thread_count = 0; cyg_semaphore_post(&idle_thread_sem); // Start idle thread cyg_thread_delay(1*100); // Pause for one second cyg_semaphore_wait(&idle_thread_sem); // Stop idle thread load_idle = idle_thread_count; start_load(0); // Shut down background load percent_load = 100 - ((load_idle * 100) / no_load_idle); diag_printf("High Load[%ld] = %d => %d%%\n", load_thread_level, (int)idle_thread_count, percent_load); if ( percent_load > desired_load ) break; // HIGH level is indeed higher low = load_thread_level; // known to be lower high *= 2; // else double it and try again } // Now chop down to the level required while (true) { load_thread_level = (high + low) / 2; start_load(desired_load); // Start up a given load idle_thread_count = 0; cyg_semaphore_post(&idle_thread_sem); // Start idle thread cyg_thread_delay(1*100); // Pause for one second cyg_semaphore_wait(&idle_thread_sem); // Stop idle thread load_idle = idle_thread_count; start_load(0); // Shut down background load percent_load = 100 - ((load_idle * 100) / no_load_idle); diag_printf("Load[%ld] = %d => %d%%\n", load_thread_level, (int)idle_thread_count, percent_load); if (((high-low) <= 1) || (abs(desired_load-percent_load) <= 2)) break; if (percent_load < desired_load) { low = load_thread_level; } else { high = load_thread_level; } } // Now we are within a few percent of the target; scale the load // factor to get a better fit, and test it, print the answer. load_thread_level *= desired_load; load_thread_level /= percent_load; start_load(desired_load); // Start up a given load idle_thread_count = 0; cyg_semaphore_post(&idle_thread_sem); // Start idle thread cyg_thread_delay(1*100); // Pause for one second cyg_semaphore_wait(&idle_thread_sem); // Stop idle thread load_idle = idle_thread_count; start_load(0); // Shut down background load percent_load = 100 - ((load_idle * 100) / no_load_idle); diag_printf("Final load[%ld] = %d => %d%%\n", load_thread_level, (int)idle_thread_count, percent_load); // no_load_idle_count_1_second = no_load_idle; }
// // Protocol driver for testing slave. // // This function is the main routine running here, handling requests sent from // the master and providing various responses. // static void nc_slave(test_param_t param) { int s, masterlen; struct sockaddr_in my_addr, master; struct nc_request req; struct nc_reply reply; int done = false; test_printf("Start test for eth%d\n", param); s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { pexit("datagram socket"); } memset((char *) &my_addr, 0, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_len = sizeof(my_addr); my_addr.sin_addr.s_addr = htonl(INADDR_ANY); my_addr.sin_port = htons(NC_SLAVE_PORT); if (bind(s, (struct sockaddr *) &my_addr, sizeof(my_addr)) < 0) { pexit("bind"); } while (!done) { masterlen = sizeof(master); if (recvfrom(s, &req, sizeof(req), 0, (struct sockaddr *)&master, &masterlen) < 0) { pexit("recvfrom"); } #if 0 test_printf("Request %d from %s:%d\n", ntohl(req.type), inet_ntoa(master.sin_addr), ntohs(master.sin_port)); #endif reply.response = htonl(NC_REPLY_ACK); reply.seq = req.seq; switch (ntohl(req.type)) { case NC_REQUEST_DISCONNECT: done = true; break; case NC_REQUEST_UDP_SEND: test_printf("UDP send - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen)); break; case NC_REQUEST_UDP_RECV: test_printf("UDP recv - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen)); break; case NC_REQUEST_UDP_ECHO: test_printf("UDP echo - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen)); break; case NC_REQUEST_TCP_SEND: test_printf("TCP send - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen)); break; case NC_REQUEST_TCP_RECV: test_printf("TCP recv - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen)); break; case NC_REQUEST_TCP_ECHO: test_printf("TCP echo - %d buffers, %d bytes\n", ntohl(req.nbufs), ntohl(req.buflen)); break; case NC_REQUEST_SET_LOAD: start_load(ntohl(req.nbufs)); break; case NC_REQUEST_START_IDLE: test_printf("Start IDLE thread\n"); idle_thread_count = 0; idle_thread_start_time = cyg_current_time(); cyg_semaphore_post(&idle_thread_sem); break; case NC_REQUEST_STOP_IDLE: cyg_semaphore_wait(&idle_thread_sem); idle_thread_stop_time = cyg_current_time(); test_printf("Stop IDLE thread\n"); reply.misc.idle_results.elapsed_time = htonl(idle_thread_stop_time - idle_thread_start_time); reply.misc.idle_results.count[0] = htonl(idle_thread_count >> 32); reply.misc.idle_results.count[1] = htonl((long)idle_thread_count); break; default: test_printf("Unrecognized request: %d\n", ntohl(req.type)); reply.response = htonl(NC_REPLY_NAK); reply.reason = htonl(NC_REPLY_NAK_UNKNOWN_REQUEST); break; } if (sendto(s, &reply, sizeof(reply), 0, (struct sockaddr *)&master, masterlen) < 0) { pexit("sendto"); } if (reply.response == ntohl(NC_REPLY_NAK)) { continue; } switch (ntohl(req.type)) { case NC_REQUEST_UDP_SEND: case NC_REQUEST_UDP_RECV: case NC_REQUEST_UDP_ECHO: do_udp_test(s, &req, &master); break; case NC_REQUEST_TCP_SEND: case NC_REQUEST_TCP_RECV: case NC_REQUEST_TCP_ECHO: do_tcp_test(s, &req, &master); break; case NC_REQUEST_START_IDLE: case NC_REQUEST_STOP_IDLE: case NC_REQUEST_SET_LOAD: default: break; } } close(s); }
static void echo_test(cyg_addrword_t p) { int s_source, s_sink, e_source, e_sink; struct sockaddr_in e_source_addr, e_sink_addr, local; int one = 1; fd_set in_fds; int i, num, len; struct test_params params,nparams; struct test_status status,nstatus; cyg_tick_count_t starttime, stoptime; s_source = socket(AF_INET, SOCK_STREAM, 0); if (s_source < 0) { pexit("stream socket"); } if (setsockopt(s_source, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { pexit("setsockopt /source/ SO_REUSEADDR"); } if (setsockopt(s_source, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one))) { pexit("setsockopt /source/ SO_REUSEPORT"); } memset(&local, 0, sizeof(local)); local.sin_family = AF_INET; local.sin_len = sizeof(local); local.sin_port = ntohs(SOURCE_PORT); local.sin_addr.s_addr = INADDR_ANY; if(bind(s_source, (struct sockaddr *) &local, sizeof(local)) < 0) { pexit("bind /source/ error"); } listen(s_source, SOMAXCONN); s_sink = socket(AF_INET, SOCK_STREAM, 0); if (s_sink < 0) { pexit("stream socket"); } memset(&local, 0, sizeof(local)); local.sin_family = AF_INET; local.sin_len = sizeof(local); local.sin_port = ntohs(SINK_PORT); local.sin_addr.s_addr = INADDR_ANY; if(bind(s_sink, (struct sockaddr *) &local, sizeof(local)) < 0) { pexit("bind /sink/ error"); } if (setsockopt(s_sink, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) { pexit("setsockopt /sink/ SO_REUSEADDR"); } if (setsockopt(s_sink, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one))) { pexit("setsockopt /sink/ SO_REUSEPORT"); } listen(s_sink, SOMAXCONN); e_source = 0; e_sink = 0; while (true) { // Wait for a connection on either of the ports FD_ZERO(&in_fds); FD_SET(s_source, &in_fds); FD_SET(s_sink, &in_fds); num = select(max(s_sink,s_source)+1, &in_fds, 0, 0, 0); if (FD_ISSET(s_source, &in_fds)) { len = sizeof(e_source_addr); if ((e_source = accept(s_source, (struct sockaddr *)&e_source_addr, &len)) < 0) { pexit("accept /source/"); } diag_printf("SOURCE connection from %s:%d\n", inet_ntoa(e_source_addr.sin_addr), ntohs(e_source_addr.sin_port)); } if (FD_ISSET(s_sink, &in_fds)) { len = sizeof(e_sink_addr); if ((e_sink = accept(s_sink, (struct sockaddr *)&e_sink_addr, &len)) < 0) { pexit("accept /sink/"); } diag_printf("SINK connection from %s:%d\n", inet_ntoa(e_sink_addr.sin_addr), ntohs(e_sink_addr.sin_port)); } // Continue with test once a connection is established in both directions if ((e_source != 0) && (e_sink != 0)) { break; } } // Wait for "source" to tell us the testing paramters if (do_read(e_source, &nparams, sizeof(nparams)) != sizeof(nparams)) { pexit("Can't read initialization parameters"); } params.nbufs = ntohl(nparams.nbufs); params.bufsize = ntohl(nparams.bufsize); params.load = ntohl(nparams.load); diag_printf("Using %d buffers of %d bytes each, %d%% background load\n", params.nbufs, params.bufsize, params.load); // Tell the sink what the parameters are if (do_write(e_sink, &nparams, sizeof(nparams)) != sizeof(nparams)) { pexit("Can't write initialization parameters"); } status.ok = 1; nstatus.ok = htonl(status.ok); // Tell the "source" to start - we're all connected and ready to go! if (do_write(e_source, &nstatus, sizeof(nstatus)) != sizeof(nstatus)) { pexit("Can't send ACK to 'source' host"); } idle_thread_count = 0; cyg_semaphore_post(&idle_thread_sem); // Start idle thread starttime = cyg_current_time(); start_load(params.load); // Echo the data from the source to the sink hosts for (i = 0; i < params.nbufs; i++) { if ((len = do_read(e_source, data_buf, params.bufsize)) != params.bufsize) { diag_printf("Can't read buf #%d: ", i+1); if (len < 0) { perror("I/O error"); } else { diag_printf("short read - only %d bytes\n", len); } } // else diag_printf("Got %d bytes\n",len); if ((len = do_write(e_sink, data_buf, params.bufsize)) != params.bufsize) { diag_printf("Can't write buf #%d: ", i+1); if (len < 0) { perror("I/O error"); } else { diag_printf("short write - only %d bytes\n", len); } } // else diag_printf("Sent %d bytes\n",len); } // Wait for the data to drain and the "sink" to tell us all is OK. if (do_read(e_sink, &status, sizeof(status)) != sizeof(status)) { pexit("Can't receive ACK from 'sink' host"); } start_load(0); cyg_semaphore_wait(&idle_thread_sem); // Stop idle thread stoptime = cyg_current_time(); stoptime -= starttime; // time taken in cS // expected idle loops in that time period for an idle system: starttime = no_load_idle_count_1_second * stoptime / 100; diag_printf( "%d ticks elapsed, %d kloops predicted for an idle system\n", (int)stoptime, (int)(starttime/1000) ); diag_printf( "actual kloops %d, CPU was %d%% idle during transfer\n", (int)(idle_thread_count/1000), (int)(idle_thread_count * 100 / starttime) ); // Now examine how close that loading actually was: start_load(params.load); // Start up a given load idle_thread_count = 0; cyg_semaphore_post(&idle_thread_sem); // Start idle thread cyg_thread_delay(1*100); // Pause for one second cyg_semaphore_wait(&idle_thread_sem); // Stop idle thread start_load(0); // Shut down background load i = 100 - ((idle_thread_count * 100) / no_load_idle_count_1_second ); diag_printf("Final load[%d] = %d => %d%%\n", load_thread_level, (int)idle_thread_count, i); //#ifdef CYGDBG_USE_ASSERTS #ifdef CYGDBG_NET_TIMING_STATS { extern void show_net_times(void); show_net_times(); } #endif //#endif }
/** * @brief The entry point of Naev. * * @param[in] argc Number of arguments. * @param[in] argv Array of argc arguments. * @return EXIT_SUCCESS on success. */ int main( int argc, char** argv ) { char buf[PATH_MAX]; /* Save the binary path. */ binary_path = strdup(argv[0]); /* Print the version */ LOG( " "APPNAME" v%s", naev_version(0) ); #ifdef GIT_COMMIT DEBUG( " git HEAD at " GIT_COMMIT ); #endif /* GIT_COMMIT */ /* Initializes SDL for possible warnings. */ SDL_Init(0); /* Initialize the threadpool */ threadpool_init(); /* Set up debug signal handlers. */ debug_sigInit(); /* Must be initialized before input_init is called. */ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { WARN("Unable to initialize SDL Video: %s", SDL_GetError()); return -1; } /* Get desktop dimensions. */ #if SDL_VERSION_ATLEAST(1,2,10) const SDL_VideoInfo *vidinfo = SDL_GetVideoInfo(); gl_screen.desktop_w = vidinfo->current_w; gl_screen.desktop_h = vidinfo->current_h; #else /* #elif SDL_VERSION_ATLEAST(1,2,10) */ gl_screen.desktop_w = 0; gl_screen.desktop_h = 0; #endif /* #elif SDL_VERSION_ATLEAST(1,2,10) */ /* We'll be parsing XML. */ LIBXML_TEST_VERSION xmlInitParser(); /* Input must be initialized for config to work. */ input_init(); conf_setDefaults(); /* set the default config values */ /* * Attempts to load the data path from datapath.lua * At this early point in the load process, the binary path * is the only place likely to be checked. */ conf_loadConfigPath(); /* Parse the user data path override first. */ conf_parseCLIPath( argc, argv ); /* Create the home directory if needed. */ if (nfile_dirMakeExist("%s", nfile_configPath())) WARN("Unable to create config directory '%s'", nfile_configPath()); /* Set the configuration. */ nsnprintf(buf, PATH_MAX, "%s"CONF_FILE, nfile_configPath()); #if HAS_UNIX /* TODO get rid of this cruft ASAP. */ int oldconfig = 0; if (!nfile_fileExists( buf )) { char *home, buf2[PATH_MAX]; home = SDL_getenv( "HOME" ); if (home != NULL) { nsnprintf( buf2, PATH_MAX, "%s/.naev/"CONF_FILE, home ); if (nfile_fileExists( buf2 )) oldconfig = 1; } } #endif /* HAS_UNIX */ conf_loadConfig(buf); /* Lua to parse the configuration file */ conf_parseCLI( argc, argv ); /* parse CLI arguments */ /* Enable FPU exceptions. */ #if defined(HAVE_FEENABLEEXCEPT) && defined(DEBUGGING) if (conf.fpu_except) feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); #endif /* defined(HAVE_FEENABLEEXCEPT) && defined(DEBUGGING) */ /* Open data. */ if (ndata_open() != 0) ERR("Failed to open ndata."); /* Load the start info. */ if (start_load()) ERR("Failed to load module start data."); /* Load the data basics. */ LOG(" %s", ndata_name()); DEBUG(); /* Display the SDL Version. */ print_SDLversion(); DEBUG(); /* random numbers */ rng_init(); /* * OpenGL */ if (gl_init()) { /* initializes video output */ ERR("Initializing video output failed, exiting..."); SDL_Quit(); exit(EXIT_FAILURE); } window_caption(); gl_fontInit( NULL, NULL, conf.font_size_def ); /* initializes default font to size */ gl_fontInit( &gl_smallFont, NULL, conf.font_size_small ); /* small font */ /* Display the load screen. */ loadscreen_load(); loadscreen_render( 0., "Initializing subsystems..." ); time_ms = SDL_GetTicks(); /* * Input */ if ((conf.joystick_ind >= 0) || (conf.joystick_nam != NULL)) { if (joystick_init()) WARN("Error initializing joystick input"); if (conf.joystick_nam != NULL) { /* use the joystick name to find a joystick */ if (joystick_use(joystick_get(conf.joystick_nam))) { WARN("Failure to open any joystick, falling back to default keybinds"); input_setDefault(); } free(conf.joystick_nam); } else if (conf.joystick_ind >= 0) /* use a joystick id instead */ if (joystick_use(conf.joystick_ind)) { WARN("Failure to open any joystick, falling back to default keybinds"); input_setDefault(); } } /* * OpenAL - Sound */ if (conf.nosound) { LOG("Sound is disabled!"); sound_disabled = 1; music_disabled = 1; } if (sound_init()) WARN("Problem setting up sound!"); music_choose("load"); /* FPS stuff. */ fps_setPos( 15., (double)(gl_screen.h-15-gl_defFont.h) ); /* Misc graphics init */ if (nebu_init() != 0) { /* Initializes the nebula */ /* An error has happened */ ERR("Unable to initialize the Nebula subsystem!"); /* Weirdness will occur... */ } gui_init(); /* initializes the GUI graphics */ toolkit_init(); /* initializes the toolkit */ map_init(); /* initializes the map. */ cond_init(); /* Initialize conditional subsystem. */ cli_init(); /* Initialize console. */ /* Data loading */ load_all(); /* Generate the CSV. */ if (conf.devcsv) dev_csv(); /* Unload load screen. */ loadscreen_unload(); /* Start menu. */ menu_main(); /* Force a minimum delay with loading screen */ if ((SDL_GetTicks() - time_ms) < NAEV_INIT_DELAY) SDL_Delay( NAEV_INIT_DELAY - (SDL_GetTicks() - time_ms) ); fps_init(); /* initializes the time_ms */ #if HAS_UNIX /* Tell the player to migrate their configuration files out of ~/.naev */ /* TODO get rid of this cruft ASAP. */ if ((oldconfig) && (!conf.datapath)) { char path[PATH_MAX], *script, *home; uint32_t scriptsize; int ret; nsnprintf( path, PATH_MAX, "%s/naev-confupdate.sh", ndata_getDirname() ); home = SDL_getenv("HOME"); ret = dialogue_YesNo( "Warning", "Your configuration files are in a deprecated location and must be migrated:\n" " \er%s/.naev/\e0\n\n" "The update script can likely be found in your Naev data directory:\n" " \er%s\e0\n\n" "Would you like to run it automatically?", home, path ); /* Try to run the script. */ if (ret) { ret = -1; /* Running from ndata. */ if (ndata_getPath() != NULL) { script = ndata_read( "naev-confupdate.sh", &scriptsize ); if (script != NULL) ret = system(script); } /* Running from laid-out files or ndata_read failed. */ if ((nfile_fileExists(path)) && (ret == -1)) { script = nfile_readFile( (int*)&scriptsize, path ); if (script != NULL) ret = system(script); } /* We couldn't find the script. */ if (ret == -1) { dialogue_alert( "The update script was not found at:\n\er%s\e0\n\n" "Please locate and run it manually.", path ); } /* Restart, as the script succeeded. */ else if (!ret) { dialogue_msg( "Update Completed", "Configuration files were successfully migrated. Naev will now restart." ); execv(argv[0], argv); } else { /* I sincerely hope this else is never hit. */ dialogue_alert( "The update script encountered an error. Please exit Naev and move your config and save files manually:\n\n" "\er%s/%s\e0 =>\n \eD%s\e0\n\n" "\er%s/%s\e0 =>\n \eD%s\e0\n\n" "\er%s/%s\e0 =>\n \eD%snebula/\e0\n\n", home, ".naev/conf.lua", nfile_configPath(), home, ".naev/{saves,screenshots}/", nfile_dataPath(), home, ".naev/gen/*.png", nfile_cachePath() ); } } else {