Master* master_new(Options* options) { utility_assert(options); /* Don't do anything in this function that will cause a log message. The * global engine is still NULL since we are creating it now, and logging * here will cause an assertion error. */ Master* master = g_new0(Master, 1); MAGIC_INIT(master); master->options = options; master->random = random_new(options_getRandomSeed(options)); gint minRunAhead = (SimulationTime)options_getMinRunAhead(options); master->minJumpTimeConfig = ((SimulationTime)minRunAhead) * SIMTIME_ONE_MILLISECOND; /* these are only avail in glib >= 2.30 * setup signal handlers for gracefully handling shutdowns */ // TODO // g_unix_signal_add(SIGTERM, (GSourceFunc)_master_handleInterruptSignal, master); // g_unix_signal_add(SIGHUP, (GSourceFunc)_master_handleInterruptSignal, master); // g_unix_signal_add(SIGINT, (GSourceFunc)_master_handleInterruptSignal, master); message("simulation master created"); return master; }
Master* master_new(Configuration* config) { MAGIC_ASSERT(config); /* Don't do anything in this function that will cause a log message. The * global engine is still NULL since we are creating it now, and logging * here will cause an assertion error. */ Master* master = g_new0(Master, 1); MAGIC_INIT(master); master->config = config; master->random = random_new(config->randomSeed); master->runTimer = g_timer_new(); master->minJumpTimeConfig = ((SimulationTime)config->minRunAhead) * SIMTIME_ONE_MILLISECOND; /* these are only avail in glib >= 2.30 * setup signal handlers for gracefully handling shutdowns */ // TODO // g_unix_signal_add(SIGTERM, (GSourceFunc)_master_handleInterruptSignal, master); // g_unix_signal_add(SIGHUP, (GSourceFunc)_master_handleInterruptSignal, master); // g_unix_signal_add(SIGINT, (GSourceFunc)_master_handleInterruptSignal, master); return master; }
TEST(RandomClass, CreateXOrShiftObject) { Random* pRandom; uint32_t nResult = 0; pRandom = random_new(setXorShiftSeed, nextXorShiftUInt32); POINTERS_EQUAL(setXorShiftSeed, pRandom->setSeed); POINTERS_EQUAL(nextXorShiftUInt32, pRandom->getNextUInt32); }
Engine* engine_new(Configuration* config) { MAGIC_ASSERT(config); /* Don't do anything in this function that will cause a log message. The * global engine is still NULL since we are creating it now, and logging * here will cause an assertion error. */ Engine* engine = g_new0(Engine, 1); MAGIC_INIT(engine); engine->config = config; engine->random = random_new(config->randomSeed); engine->runTimer = g_timer_new(); /* initialize the singleton-per-thread worker class */ engine->workerKey.index = 0; engine->preloadKey.index = 0; /* holds all events if single-threaded, and non-node events otherwise. */ engine->masterEventQueue = asyncpriorityqueue_new((GCompareDataFunc)shadowevent_compare, NULL, (GDestroyNotify)shadowevent_free); engine->workersIdle = g_cond_new(); engine->engineIdle = g_mutex_new(); engine->registry = registry_new(); registry_register(engine->registry, SOFTWARE, NULL, software_free); registry_register(engine->registry, CDFS, NULL, cdf_free); registry_register(engine->registry, PLUGINPATHS, g_free, g_free); engine->minTimeJump = config->minRunAhead * SIMTIME_ONE_MILLISECOND; engine->internet = internetwork_new(); engine->lock = g_mutex_new(); /* get the raw speed of the experiment machine */ gchar* contents = NULL; gsize length = 0; GError* error = NULL; if(!g_file_get_contents(CONFIG_CPU_MAX_FREQ_FILE, &contents, &length, &error)) { engine->rawFrequencyKHz = 0; } else { engine->rawFrequencyKHz = (guint)atoi(contents); } return engine; }
void test_seeding(unsigned int num) { struct random *p1, *p2; unsigned int seed[] = { 1, 2, 3, 4 }; int err; p1 = random_new(); p2 = random_new(); assert(p1); assert(p2); err = random_set_seed(p1, seed, ARRAY_SIZE(seed)); assert(err == 0); err = random_set_seed(p2, seed, ARRAY_SIZE(seed)); assert(err == 0); while(num--) assert(random_uint(p1) == random_uint(p2)); random_delete(p1); random_delete(p2); }
/* Initialize new World */ struct World * world_new(uint32_t seed){ struct World * self; struct Random * random; if (!size){ size = mm_new(sizeof(struct World)); } if ((self = mm_alloc(size))){ self->seed = seed; random = random_new(seed); self->altitude = terrain_new(random_random(random)); self->climate = climate_new(random_random(random)); self->evil = climate_new(random_random(random)); random_del(random); } return self; }
Slave* slave_new(Master* master, Configuration* config, guint randomSeed) { Slave* slave = g_new0(Slave, 1); MAGIC_INIT(slave); g_mutex_init(&(slave->lock)); g_mutex_init(&(slave->pluginInitLock)); slave->master = master; slave->config = config; slave->random = random_new(randomSeed); slave->rawFrequencyKHz = utility_getRawCPUFrequency(CONFIG_CPU_MAX_FREQ_FILE); if(slave->rawFrequencyKHz == 0) { info("unable to read '%s' for copying", CONFIG_CPU_MAX_FREQ_FILE); } slave->hosts = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); slave->programs = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, (GDestroyNotify)program_free); slave->dns = dns_new(); slave->nWorkers = (guint) configuration_getNWorkerThreads(config); slave->mainThreadWorker = worker_new(slave); slave->cwdPath = g_get_current_dir(); slave->dataPath = g_build_filename(slave->cwdPath, "shadow.data", NULL); slave->hostsPath = g_build_filename(slave->dataPath, "hosts", NULL); if(g_file_test(slave->dataPath, G_FILE_TEST_EXISTS)) { gboolean success = utility_removeAll(slave->dataPath); utility_assert(success); } gchar* templateDataPath = g_build_filename(slave->cwdPath, "shadow.data.template", NULL); if(g_file_test(templateDataPath, G_FILE_TEST_EXISTS)) { gboolean success = utility_copyAll(templateDataPath, slave->dataPath); utility_assert(success); } g_free(templateDataPath); return slave; }
void test_randomness(void) { struct random *rand; unsigned int n, i, num; rand = random_new(); assert(rand); num = 100; for(i = 0; i < num; ++i) { n = random_uint(rand); fprintf(stdout, "%-10u\t", n); if((i % 3) == 0) fprintf(stdout, "\n"); } fprintf(stdout, "\n"); random_delete(rand); }
void test_duplicates(unsigned int num) { const struct map_config map_conf = { .size = MAP_DEFAULT_SIZE, .lower_bound = MAP_DEFAULT_LOWER_BOUND, .upper_bound = MAP_DEFAULT_UPPER_BOUND, .static_size = false, .key_compare = &compare_int, .key_hash = &hash_uint, .data_delete = NULL, }; struct map *m; struct random *random; unsigned int i, n, dups1, dups2;; int err; m = map_new(&map_conf); random = random_new(); assert(m); assert(random); dups1 = 0; for(i = 0; i < num; ++i) { n = random_uint(random); if(map_contains(m, (void *)(long) n)) { dups1 += 1; } else { err = map_insert(m, (void *)(long) n, (void *)(long) n); if(err < 0) { fprintf(stderr, "Warning: " "Map unable to insert %u in %uth iteration: %s\n", n, i, strerror(-err)); } } } random_delete(random); map_clear(m); srand(time(NULL)); dups2 = 0; for(i = 0; i < num; ++i) { n = rand(); if(map_contains(m, (void *)(long) n)) { dups2 += 1; } else { err = map_insert(m, (void *)(long) n, (void *)(long) n); if(err < 0) { fprintf(stderr, "Warning: " "Map unable to insert %u in %uth iteration: %s\n", n, i, strerror(-err)); } } } map_delete(m); fprintf(stdout, "random: After %u iterations there are %u (%lf %%) duplicates\n" "rand(): After %u iterations there are %u (%lf %%) duplicates\n", num, dups1, (double) dups1 / num, num, dups2, (double) dups2 / num); } void test_range(unsigned int num) { struct random *rand; unsigned int i, n; rand = random_new(); assert(rand); for(i = 0; i < num; ++i) { n = random_uint_range(rand, 0, 100); assert(n <= 100); n = random_uint_range(rand, 1000, 10000); assert(n >= 1000 && n <= 10000); n = random_uint_range(rand, 99999, 123456); assert(n >= 99999 && n <= 123456); n = random_uint_range(rand, (unsigned int) 1e6 + 1, (unsigned int) 1e8); assert(n >= (unsigned int) 1e6 + 1 && n <= (unsigned int) 1e8); n = random_uint_range(rand, 0, 0); assert(n == 0); n = random_uint_range(rand, 100, 100); assert(n == 100); } random_delete(rand); } int main(int argc, char *argv[]) { unsigned int num; if(argc == 2) num = atoi(argv[1]); else num = 0; test_randomness(); if(num) { test_seeding(num); test_duplicates(num); test_range(num); } fprintf(stdout, "Tests finished\n"); return EXIT_SUCCESS; }
JNIEXPORT void JNICALL Java_edu_wlu_cs_levy_breezyslam_algorithms_RMHCSLAM_init (JNIEnv *env, jobject thisobject, jint random_seed) { ptr_to_obj(env, thisobject, random_new(random_seed)); }
Host* host_new(GQuark id, gchar* hostname, gchar* ipHint, gchar* geocodeHint, gchar* typeHint, guint64 requestedBWDownKiBps, guint64 requestedBWUpKiBps, guint cpuFrequency, gint cpuThreshold, gint cpuPrecision, guint nodeSeed, SimulationTime heartbeatInterval, GLogLevelFlags heartbeatLogLevel, gchar* heartbeatLogInfo, GLogLevelFlags logLevel, gboolean logPcap, gchar* pcapDir, gchar* qdisc, guint64 receiveBufferSize, gboolean autotuneReceiveBuffer, guint64 sendBufferSize, gboolean autotuneSendBuffer, guint64 interfaceReceiveLength) { Host* host = g_new0(Host, 1); MAGIC_INIT(host); host->id = id; host->name = g_strdup(hostname); host->random = random_new(nodeSeed); /* get unique virtual address identifiers for each network interface */ Address* loopbackAddress = dns_register(worker_getDNS(), host->id, host->name, "127.0.0.1"); Address* ethernetAddress = dns_register(worker_getDNS(), host->id, host->name, ipHint); /* connect to topology and get the default bandwidth */ guint64 bwDownKiBps = 0, bwUpKiBps = 0; topology_attach(worker_getTopology(), ethernetAddress, host->random, ipHint, geocodeHint, typeHint, &bwDownKiBps, &bwUpKiBps); /* prefer assigned bandwidth if available */ if(requestedBWDownKiBps) { bwDownKiBps = requestedBWDownKiBps; } if(requestedBWUpKiBps) { bwUpKiBps = requestedBWUpKiBps; } /* virtual addresses and interfaces for managing network I/O */ NetworkInterface* loopback = networkinterface_new(loopbackAddress, G_MAXUINT32, G_MAXUINT32, logPcap, pcapDir, qdisc, interfaceReceiveLength); NetworkInterface* ethernet = networkinterface_new(ethernetAddress, bwDownKiBps, bwUpKiBps, logPcap, pcapDir, qdisc, interfaceReceiveLength); host->interfaces = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) networkinterface_free); g_hash_table_replace(host->interfaces, GUINT_TO_POINTER((guint)networkinterface_getIPAddress(ethernet)), ethernet); g_hash_table_replace(host->interfaces, GUINT_TO_POINTER((guint)htonl(INADDR_LOOPBACK)), loopback); host->defaultInterface = ethernet; /* thread-level event communication with other nodes */ g_mutex_init(&(host->lock)); host->events = eventqueue_new(); host->availableDescriptors = g_queue_new(); host->descriptorHandleCounter = MIN_DESCRIPTOR; /* virtual descriptor management */ host->descriptors = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, descriptor_unref); host->receiveBufferSize = receiveBufferSize; host->sendBufferSize = sendBufferSize; host->autotuneReceiveBuffer = autotuneReceiveBuffer; host->autotuneSendBuffer = autotuneSendBuffer; host->shadowToOSHandleMap = g_hash_table_new(g_direct_hash, g_direct_equal); host->osToShadowHandleMap = g_hash_table_new(g_direct_hash, g_direct_equal); host->unixPathToPortMap = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); /* applications this node will run */ host->applications = g_queue_new(); host->cpu = cpu_new(cpuFrequency, cpuThreshold, cpuPrecision); host->tracker = tracker_new(heartbeatInterval, heartbeatLogLevel, heartbeatLogInfo); host->logLevel = logLevel; host->logPcap = logPcap; host->pcapDir = pcapDir; message("Created Host '%s', ip %s, " "%"G_GUINT64_FORMAT" bwUpKiBps, %"G_GUINT64_FORMAT" bwDownKiBps, %"G_GUINT64_FORMAT" initSockSendBufSize, %"G_GUINT64_FORMAT" initSockRecvBufSize, " "%u cpuFrequency, %i cpuThreshold, %i cpuPrecision, %u seed", g_quark_to_string(host->id), networkinterface_getIPName(host->defaultInterface), bwUpKiBps, bwDownKiBps, sendBufferSize, receiveBufferSize, cpuFrequency, cpuThreshold, cpuPrecision, nodeSeed); return host; }
/* Checks that the guessed balls in the state match up with the real balls * for all possible lasers (i.e. not just the ones that the player might * have already guessed). This is required because any layout with >4 balls * might have multiple valid solutions. Returns non-zero for a 'correct' * (i.e. consistent) layout. */ static int check_guesses(game_state *state, int cagey) { game_state *solution, *guesses; int i, x, y, n, unused, tmp; int ret = 0; if (cagey) { /* * First, check that each laser the player has already * fired is consistent with the layout. If not, show them * one error they've made and reveal no further * information. * * Failing that, check to see whether the player would have * been able to fire any laser which distinguished the real * solution from their guess. If so, show them one such * laser and reveal no further information. */ guesses = dup_game(state); /* clear out BALL_CORRECT on guess, make BALL_GUESS BALL_CORRECT. */ for (x = 1; x <= state->w; x++) { for (y = 1; y <= state->h; y++) { GRID(guesses, x, y) &= ~BALL_CORRECT; if (GRID(guesses, x, y) & BALL_GUESS) GRID(guesses, x, y) |= BALL_CORRECT; } } n = 0; for (i = 0; i < guesses->nlasers; i++) { if (guesses->exits[i] != LASER_EMPTY && guesses->exits[i] != laser_exit(guesses, i)) n++; } if (n) { /* * At least one of the player's existing lasers * contradicts their ball placement. Pick a random one, * highlight it, and return. * * A temporary random state is created from the current * grid, so that repeating the same marking will give * the same answer instead of a different one. */ random_state *rs = random_new((char *)guesses->grid, (state->w+2)*(state->h+2) * sizeof(unsigned int)); n = random_upto(rs, n); random_free(rs); for (i = 0; i < guesses->nlasers; i++) { if (guesses->exits[i] != LASER_EMPTY && guesses->exits[i] != laser_exit(guesses, i) && n-- == 0) { state->exits[i] |= LASER_WRONG; tmp = laser_exit(state, i); if (RANGECHECK(state, tmp)) state->exits[tmp] |= LASER_WRONG; state->justwrong = TRUE; free_game(guesses); return 0; } } } n = 0; for (i = 0; i < guesses->nlasers; i++) { if (guesses->exits[i] == LASER_EMPTY && laser_exit(state, i) != laser_exit(guesses, i)) n++; } if (n) { /* * At least one of the player's unfired lasers would * demonstrate their ball placement to be wrong. Pick a * random one, highlight it, and return. * * A temporary random state is created from the current * grid, so that repeating the same marking will give * the same answer instead of a different one. */ random_state *rs = random_new((char *)guesses->grid, (state->w+2)*(state->h+2) * sizeof(unsigned int)); n = random_upto(rs, n); random_free(rs); for (i = 0; i < guesses->nlasers; i++) { if (guesses->exits[i] == LASER_EMPTY && laser_exit(state, i) != laser_exit(guesses, i) && n-- == 0) { fire_laser(state, i); state->exits[i] |= LASER_OMITTED; tmp = laser_exit(state, i); if (RANGECHECK(state, tmp)) state->exits[tmp] |= LASER_OMITTED; state->justwrong = TRUE; free_game(guesses); return 0; } } } free_game(guesses); } /* duplicate the state (to solution) */ solution = dup_game(state); /* clear out the lasers of solution */ for (i = 0; i < solution->nlasers; i++) { tmp = range2grid(solution, i, &x, &y, &unused); assert(tmp); GRID(solution, x, y) = 0; solution->exits[i] = LASER_EMPTY; } /* duplicate solution to guess. */ guesses = dup_game(solution); /* clear out BALL_CORRECT on guess, make BALL_GUESS BALL_CORRECT. */ for (x = 1; x <= state->w; x++) { for (y = 1; y <= state->h; y++) { GRID(guesses, x, y) &= ~BALL_CORRECT; if (GRID(guesses, x, y) & BALL_GUESS) GRID(guesses, x, y) |= BALL_CORRECT; } } /* for each laser (on both game_states), fire it if it hasn't been fired. * If one has been fired (or received a hit) and another hasn't, we know * the ball layouts didn't match and can short-circuit return. */ for (i = 0; i < solution->nlasers; i++) { if (solution->exits[i] == LASER_EMPTY) fire_laser(solution, i); if (guesses->exits[i] == LASER_EMPTY) fire_laser(guesses, i); } /* check each game_state's laser against the other; if any differ, return 0 */ ret = 1; for (i = 0; i < solution->nlasers; i++) { tmp = range2grid(solution, i, &x, &y, &unused); assert(tmp); if (solution->exits[i] != guesses->exits[i]) { /* If the original state didn't have this shot fired, * and it would be wrong between the guess and the solution, * add it. */ if (state->exits[i] == LASER_EMPTY) { state->exits[i] = solution->exits[i]; if (state->exits[i] == LASER_REFLECT || state->exits[i] == LASER_HIT) GRID(state, x, y) = state->exits[i]; else { /* add a new shot, incrementing state's laser count. */ int ex, ey, newno = state->laserno++; tmp = range2grid(state, state->exits[i], &ex, &ey, &unused); assert(tmp); GRID(state, x, y) = newno; GRID(state, ex, ey) = newno; } state->exits[i] |= LASER_OMITTED; } else { state->exits[i] |= LASER_WRONG; } ret = 0; } } if (ret == 0 || state->nguesses < state->minballs || state->nguesses > state->maxballs) goto done; /* fix up original state so the 'correct' balls end up matching the guesses, * as we've just proved that they were equivalent. */ for (x = 1; x <= state->w; x++) { for (y = 1; y <= state->h; y++) { if (GRID(state, x, y) & BALL_GUESS) GRID(state, x, y) |= BALL_CORRECT; else GRID(state, x, y) &= ~BALL_CORRECT; } } done: /* fill in nright and nwrong. */ state->nright = state->nwrong = state->nmissed = 0; for (x = 1; x <= state->w; x++) { for (y = 1; y <= state->h; y++) { int bs = GRID(state, x, y) & (BALL_GUESS | BALL_CORRECT); if (bs == (BALL_GUESS | BALL_CORRECT)) state->nright++; else if (bs == BALL_GUESS) state->nwrong++; else if (bs == BALL_CORRECT) state->nmissed++; } } free_game(solution); free_game(guesses); state->reveal = 1; return ret; }
Scheduler* scheduler_new(SchedulerPolicyType policyType, guint nWorkers, gpointer threadUserData, guint schedulerSeed, SimulationTime endTime) { Scheduler* scheduler = g_new0(Scheduler, 1); MAGIC_INIT(scheduler); /* global lock */ g_mutex_init(&(scheduler->globalLock)); scheduler->startBarrier = countdownlatch_new(nWorkers+1); scheduler->finishBarrier = countdownlatch_new(nWorkers+1); scheduler->executeEventsBarrier = countdownlatch_new(nWorkers+1); scheduler->collectInfoBarrier = countdownlatch_new(nWorkers+1); scheduler->prepareRoundBarrier = countdownlatch_new(nWorkers+1); scheduler->endTime = endTime; scheduler->currentRound.endTime = scheduler->endTime;// default to one single round scheduler->currentRound.minNextEventTime = SIMTIME_MAX; scheduler->threadToWaitTimerMap = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_timer_destroy); scheduler->hostIDToHostMap = g_hash_table_new(g_direct_hash, g_direct_equal); scheduler->random = random_new(schedulerSeed); /* ensure we have sane default modes for the number of workers we are using */ if(nWorkers == 0) { scheduler->policyType = SP_SERIAL_GLOBAL; } else if(nWorkers > 0 && policyType == SP_SERIAL_GLOBAL) { policyType = SP_PARALLEL_HOST_STEAL; } else { scheduler->policyType = policyType; } /* create the configured policy to handle queues */ switch(scheduler->policyType) { case SP_PARALLEL_HOST_SINGLE: { scheduler->policy = schedulerpolicyhostsingle_new(); break; } case SP_PARALLEL_HOST_STEAL: { scheduler->policy = schedulerpolicyhostsingle_new(); break; } case SP_PARALLEL_THREAD_SINGLE: { scheduler->policy = schedulerpolicythreadsingle_new(); break; } case SP_PARALLEL_THREAD_PERTHREAD: { scheduler->policy = schedulerpolicythreadperthread_new(); break; } case SP_PARALLEL_THREAD_PERHOST: { scheduler->policy = schedulerpolicythreadperhost_new(); break; } case SP_SERIAL_GLOBAL: default: { scheduler->policy = schedulerpolicyglobalsingle_new(); break; } } utility_assert(scheduler->policy); /* make sure our ref count is set before starting the threads */ scheduler->referenceCount = 1; scheduler->threadItems = g_queue_new(); /* start up threads and create worker storage, each thread will call worker_new, * and wait at startBarrier until we are ready to launch */ for(gint i = 0; i < nWorkers; i++) { GString* name = g_string_new(NULL); g_string_printf(name, "worker-%i", (i)); SchedulerThreadItem* item = g_new0(SchedulerThreadItem, 1); item->notifyDoneRunning = countdownlatch_new(1); WorkerRunData* runData = g_new0(WorkerRunData, 1); runData->userData = threadUserData; runData->scheduler = scheduler; runData->threadID = i; runData->notifyDoneRunning = item->notifyDoneRunning; gint returnVal = pthread_create(&(item->thread), NULL, (void*(*)(void*))worker_run, runData); if(returnVal != 0) { critical("unable to create worker thread"); return NULL; } returnVal = pthread_setname_np(item->thread, name->str); if(returnVal != 0) { warning("unable to set name of worker thread to '%s'", name->str); } utility_assert(item->thread); g_queue_push_tail(scheduler->threadItems, item); logger_register(logger_getDefault(), item->thread); g_string_free(name, TRUE); } message("main scheduler thread will operate with %u worker threads", nWorkers); return scheduler; }