int main(int argc, char *argv[]) { printf("Start of %s.\n", argv[0]); nthreads = 5, ncores = 5; if (SDF_TRUE != internal_testhomedir_init()) { return -1; } else if (argc > 1) { niterator = atoi(argv[1]); } else if (argc > 2) { ncores = atoi(argv[2]); if (ncores > MAX_CORES) ncores = MAX_CORES; } else if (argc > 3) { nthreads = atoi(argv[3]); if (nthreads > MAX_FTH_THREAD) nthreads = MAX_FTH_THREAD; } plat_assert_always(niterator > 0); plat_assert_always(nthreads > 0); plat_assert_always(ncores > 0); int ret = execute_test(); printf("End of %s.\n", argv[0]); // plat_log_parse_arg("sdf/shared=debug"); plat_shmem_alloc_get_stats(&g_end_sm_stats); print_sm_stats(g_init_sm_stats, g_end_sm_stats); return (ret); }
/** @brief Sanity check that everything is as initialized */ static void test_middle(text_sp_t shared_text, const char *data, size_t paddr) { const struct text *local_text = NULL; size_t data_len; size_t size; size_t current_paddr; int status; /* * #plat_shmem_ptr_to_paddr returns consistent non-null values for * physmem across invocations. */ current_paddr = plat_shmem_ptr_to_paddr(shared_text); plat_assert_always(current_paddr == paddr); data_len = strlen(data) + 1; size = sizeof (*local_text) + data_len; text_sp_var_rref(&local_text, shared_text, size); plat_assert_always(local_text); plat_assert_always(local_text->data_len == data_len); status = memcmp(local_text->data, data, local_text->data_len); plat_assert_always(!status); text_sp_var_rrelease(&local_text, size); }
int execute_test() { fthInit(); int size = 1024; char str[size]; uint64_t i; pthread_attr_t attr; pthread_attr_init(&attr); pthread_t fthPthread[MAX_CORES]; for (i = 0; i < ncores; i++) { pthread_create(&fthPthread[i], &attr, &pthread_routine, (void*) i); } for (i = 0; i < ncores; i++) { pthread_join(fthPthread[i], NULL); } HomeDir_printStats(homedir, str, size); printf("%s\n", str); printf("The status should be: nputs is %d, ngets is %d, nremoves is %d," "nhits is %d, nmisses is %d\n", nputs, ngets, nremoves, nhits, nmisses); fflush(stdout); //Compare with stats_puts, stats_gets, stats_removes, //stats_hits, stats_misses in homedir plat_assert_always(nputs == homedir->stats_puts); plat_assert_always(ngets == homedir->stats_gets); plat_assert_always(nremoves == homedir->stats_removes); plat_assert_always(nhits == homedir->stats_hits); plat_assert_always(nmisses == homedir->stats_misses); HomeDir_destroy(homedir); return 0; }
/* * XXX - the variable length mechanations stink. We have the size in the header * and might as well use it. The debugging tools can unprotect the header to get at the size for * mapping. */ static text_sp_t test_start(const char *data) { text_sp_t shared_text; struct text *local_text = NULL; size_t data_len; size_t size; data_len = strlen(data) + 1; size = sizeof (*local_text) + data_len; /* * Physical memory works just like normal memory; only the * allocator is different. */ shared_text = plat_shmem_var_phys_alloc(text_sp, size); plat_assert_always(!text_sp_is_null(shared_text)); text_sp_var_rwref(&local_text, shared_text, size); plat_assert_always(local_text); local_text->data_len = data_len; memcpy(local_text->data, data, data_len); text_sp_var_rwrelease(&local_text, size); return (shared_text); }
void testcreate() { uint64_t cguid = 1; SDF_container_type_t ctype = SDF_BLOCK_CONTAINER; SDF_boolean_t bEntryCreated; for (int blockNum = 0; blockNum < numBlocks; blockNum++) { local_key_t *lkey = get_local_block_key(blockNum); DirEntry *entry = HomeDir_get_create(homedir, cguid, ctype, lkey, &bEntryCreated); plat_assert_always(SDF_TRUE == bEntryCreated && NULL != entry); // {{ fthWaitEl_t *wait = reqq_lock(entry->q); // LOCK REQQ fthThread_t *top = reqq_peek(entry->q); plat_assert_always(top == fthSelf()); fthThread_t *self = reqq_dequeue(entry->q); plat_assert_always(self == fthSelf()); reqq_unlock(entry->q, wait); // UNLOCK REQQ // }} if (bEntryCreated) { free_local_key(lkey); // HomeDir_get_create makes a copy if created via LinkedDirList_put } } printf("Thread 1: Created %d blocks in the directory\n", numBlocks); }
void testremove() { uint64_t cguid = 1; SDF_container_type_t ctype = SDF_BLOCK_CONTAINER; for (int blockNum = 0; blockNum < numBlocks; blockNum++) { local_key_t *lkey = get_local_block_key(blockNum); DirEntry *entry = HomeDir_remove(homedir, cguid, ctype, lkey); // {{ plat_assert_always(entry); fthThread_t *top = reqq_peek(entry->q); if (top) plat_assert_always(top == fthSelf()); fthWaitEl_t *wait = reqq_lock(entry->q); fthThread_t *self = reqq_dequeue(entry->q); if (self) plat_assert_always(self == fthSelf()); reqq_unlock(entry->q, wait); reqq_destroy(entry->q); plat_assert_always(NULL == entry->home); plat_free(entry); // }} free_local_key(lkey); } printf("Thread 1: Removed %d blocks from the directory\n", numBlocks); }
void testget() { uint64_t cguid = 1; SDF_container_type_t ctype = SDF_BLOCK_CONTAINER; for (int blockNum = 0; blockNum < numBlocks*2; blockNum++) { local_key_t *lkey = get_local_block_key(blockNum); DirEntry *entry = HomeDir_get(homedir, cguid, ctype, lkey); // {{ if (blockNum < numBlocks) { plat_assert_always(entry); fthWaitEl_t *wait = reqq_lock(entry->q); // LOCK REQQ fthThread_t *top = reqq_peek(entry->q); plat_assert_always(top == fthSelf()); fthThread_t *self = reqq_dequeue(entry->q); plat_assert_always(self == fthSelf()); reqq_unlock(entry->q, wait); // UNLOCK REQQ if (NULL != (top = reqq_peek(entry->q))) { fthResume(top, 0); printf("Thread 1: yielding after setting thread 2 to run for block=%u\n", blockNum); fthYield(1); } } // }} free_local_key(lkey); } printf("Thread 1: Got %d blocks from the directory\n", numBlocks); }
int main () { int ret; int tmp; struct plat_shmem_config *shmem_config = plat_alloc(sizeof(struct plat_shmem_config)); plat_shmem_config_init(shmem_config); plat_shmem_prototype_init(shmem_config); const char *path = plat_shmem_config_get_path(shmem_config); tmp = plat_shmem_attach(path); if (tmp) { plat_log_msg(20073, PLAT_LOG_CAT_PLATFORM_TEST_SHMEM, PLAT_LOG_LEVEL_FATAL, "shmem_attach(%s) failed: %s", path, plat_strerror(-tmp)); plat_abort(); } sem_init(&general_sem, 0, 0); fthInit(); mboxShmem = ptofMbox_sp_alloc(); plat_assert_always(!ptofMbox_sp_is_null(mboxShmem)); mbox = ptofMbox_sp_rwref(&mbox, mboxShmem); ptofMboxInit(mbox); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); printf("starting fth scheduler pthread ....\n"); if ((ret = pthread_create(&sched_thread, &attr, fthSchedPthread, NULL))) { plat_assert_always(0 == 1); } /* wait for all the threads to get created */ plat_assert_always(0==sem_wait(&general_sem)); // runThreadPool(pool); /* kick off the mail blast */ printf("Starting the mail blast 0\n"); for(int ii=0; ii < NUM_THREADS ; ii++) { mail_sp_t mailShm = mail_sp_alloc(); mail_t *mail = mail_sp_rwref(&mail, mailShm); mail->counter = ii; printf(" Posting mail with counter %d\n", mail->counter); ptofMboxPost(mboxShmem, shmem_cast(shmem_void, mailShm)); } /* We wait for all the messages to be delievered before exiting */ plat_assert_always(0==sem_wait(&general_sem)); // pthread_join(sched_thread, NULL); return 0; }
int main(int argc, char **argv) { int ret = 0; int shmem_attached = 0; struct plat_opts_config_fthSignalTest config; int status; memset(&config, 0, sizeof(config)); plat_shmem_config_init(&config.shmem); if (plat_opts_parse_fthSignalTest(&config, argc, argv)) { ret = 2; } if (!ret) { status = plat_shmem_prototype_init(&config.shmem); if (status) { plat_log_msg(20876, LOG_CAT, PLAT_LOG_LEVEL_FATAL, "shmem init failure: %s", plat_strerror(-status)); ret = 1; } } if (!ret) { status = plat_shmem_attach(plat_shmem_config_get_path(&config.shmem)); if (status) { plat_log_msg(20877, LOG_CAT, PLAT_LOG_LEVEL_FATAL, "shmem attach failure: %s", plat_strerror(-status)); ret = 1; } else { shmem_attached = 1; } } if (!ret) { fthInit(); fthSignalInit(); fthSignal(SIGABRT, &handle_signal_fth); plat_kill(getpid(), SIGABRT); fthSchedulerPthread(0); plat_assert_always(signal_received == SIGABRT); } if (shmem_attached) { status = plat_shmem_detach(); if (status) { plat_log_msg(20880, LOG_CAT, PLAT_LOG_LEVEL_FATAL, "shmem detach failure: %s", plat_strerror(-status)); ret = 1; } } plat_shmem_config_destroy(&config.shmem); return (ret); }
void testget(uint64_t seq) { uint64_t cguid = 1; SDF_container_type_t ctype = SDF_BLOCK_CONTAINER; for (int i = 0; i < niterator; i++) { local_key_t *lkey = get_local_block_key(0); DirEntry *entry = HomeDir_get(homedir, cguid, ctype, lkey); if (entry == NULL) { (void) __sync_fetch_and_add(&nmisses, 1); printf("Miss\n"); continue; } else { (void) __sync_fetch_and_add(&ngets, 1); (void) __sync_fetch_and_add(&nhits, 1); } // {{ /*if (blockNum < numBlocks) {*/ fthWaitEl_t *wait = reqq_lock(entry->q); // LOCK REQQ fthThread_t *top = reqq_peek(entry->q); plat_assert_always(top != 0); // plat_assert_always(top == fthSelf()); fthThread_t *self = reqq_dequeue(entry->q); plat_assert_always(self != 0); // plat_assert_always(self == fthSelf()); reqq_unlock(entry->q, wait); // UNLOCK REQQ /* if (NULL != (top = reqq_peek(entry->q))) { fthResume(top, 0); printf( "Thread 1: yielding after setting thread 2 to run for block=%u\n", blockNum); fthYield(1); }*/ //} // }} free_local_key(lkey); } }
void test_fn(threadPool_t * pool, uint64_t mail) { mail_sp_t mailShm; plat_assert_always(pool); test_fn_num_time_called++; /* The rock_ is what the user passes in at createThreadPool time. It can be any arbitrary pointer or any 64 bit quantity you like */ plat_assert_always(pool->rock_ == 1); printf("Got mail %lld...", mail); uint64_to_shmem_ptr_cast(mailShm, mail); mail_t *local = mail_sp_rwref(&local, mailShm); printf("...with counter..%d...\n", local->counter); if(test_fn_num_time_called == 10){ sem_post(&general_sem); } }
void testcreate(uint64_t seq) { uint64_t cguid = 1; SDF_container_type_t ctype = SDF_BLOCK_CONTAINER; SDF_boolean_t bEntryCreated; for (int i = 0; i < niterator; i++) { local_key_t *lkey = get_local_block_key(0); DirEntry *entry = HomeDir_get_create(homedir, cguid, ctype, lkey, &bEntryCreated); if (SDF_TRUE == bEntryCreated) { printf("fth %d create block\n", seq); fflush(stdout); //record actions (void) __sync_fetch_and_add(&nputs, 1); } else { (void) __sync_fetch_and_add(&ngets, 1); (void) __sync_fetch_and_add(&nhits, 1); } plat_assert_always(entry != NULL); // {{ fthWaitEl_t *wait = reqq_lock(entry->q); // LOCK REQQ fthThread_t *top = reqq_peek(entry->q); plat_assert_always(top != 0); // plat_assert_always(top == fthSelf()); fthThread_t *self = reqq_dequeue(entry->q); plat_assert_always(self != 0); // plat_assert_always(self == fthSelf()); reqq_unlock(entry->q, wait); // UNLOCK REQQ // }} if (bEntryCreated) { free_local_key(lkey); // HomeDir_get_create makes a copy if created via LinkedDirList_put } } }
void testremove(uint64_t seq) { uint64_t cguid = 1; SDF_container_type_t ctype = SDF_BLOCK_CONTAINER; for (int i = 0; i < niterator; i++) { local_key_t *lkey = get_local_block_key(0); DirEntry *entry = HomeDir_remove(homedir, cguid, ctype, lkey); if (entry) { printf("fth %d remove block\n", seq); fflush(stdout); (void)__sync_fetch_and_add(&nremoves, 1); } else { free_local_key(lkey); continue; } // {{ plat_assert_always(entry); fthThread_t *top = reqq_peek(entry->q); if (top) plat_assert_always(top == fthSelf()); fthWaitEl_t *wait = reqq_lock(entry->q); fthThread_t *self = reqq_dequeue(entry->q); if (self) plat_assert_always(self == fthSelf()); reqq_unlock(entry->q, wait); reqq_destroy(entry->q); plat_assert_always(NULL == entry->home); plat_free(entry); // }} free_local_key(lkey); } }
void testRoutine2(uint64_t arg) { uint64_t cguid = 1; SDF_container_type_t ctype = SDF_BLOCK_CONTAINER; int blockNum; SDF_boolean_t bEntryCreated; for (blockNum = 0; blockNum < numBlocks; blockNum++) { local_key_t *lkey = get_local_block_key(blockNum); DirEntry *entry = HomeDir_get_create(homedir, cguid, ctype, lkey, &bEntryCreated); // {{ fthThread_t *top = reqq_peek(entry->q); if (top != fthSelf()) { fthWaitEl_t *wait = reqq_lock(entry->q); uint16_t sz = reqq_enqueue(entry->q, fthSelf()); reqq_unlock(entry->q, wait); printf("Thread 2: Size of request queue when second thread added itself = %u.\n", sz); if (sz > 1) { printf("Thread 2: going to wait\n"); fthWait(); printf("Thread 2: resumed after wait\n"); fthWaitEl_t *wait = reqq_lock(entry->q); fthThread_t *top = reqq_peek(entry->q); if (top == fthSelf()) { fthThread_t *self = reqq_dequeue(entry->q); plat_assert_always(self == top); } reqq_unlock(entry->q, wait); } } // }} } }
int main(int argc, char **argv) { int ret = 0; int shmem_attached = 0; struct plat_opts_config_fthGetTimeSpeed config; int status; int i; struct state *state; struct thread_state *thread_state; long count; memset(&config, 0, sizeof(config)); plat_shmem_config_init(&config.shmem); config.npthread = DEFAULT_NPTHREAD; config.secs = DEFAULT_LIMIT_SECS; config.multiq = DEFAULT_MULTIQ; config.mode = DEFAULT_MODE; if (plat_opts_parse_fthGetTimeSpeed(&config, argc, argv)) { ret = 2; } if (!ret) { status = plat_shmem_prototype_init(&config.shmem); if (status) { plat_log_msg(20876, LOG_CAT, PLAT_LOG_LEVEL_FATAL, "shmem init failure: %s", plat_strerror(-status)); ret = 1; } } if (!ret) { status = plat_shmem_attach(plat_shmem_config_get_path(&config.shmem)); if (status) { plat_log_msg(20877, LOG_CAT, PLAT_LOG_LEVEL_FATAL, "shmem attach failure: %s", plat_strerror(-status)); ret = 1; } else { shmem_attached = 1; } } if (!ret) { if (config.multiq) { fthInitMultiQ(1, config.npthread); } else { fthInit(); } plat_calloc_struct(&state); plat_assert_always(state); state->config = &config; state->ts = plat_calloc(config.npthread, sizeof (state->ts[0])); plat_assert_always(state->ts); for (i = 0; i < state->config->npthread; ++i) { plat_calloc_struct(&thread_state); plat_assert_always(thread_state); thread_state->state = state; thread_state->index = i; state->ts[i] = thread_state; XResume(fthSpawn(&time_main, 40960), (uint64_t)thread_state); } signal(SIGALRM, alarm_handler); signal(SIGINT, alarm_handler); alarm(state->config->secs); for (i = 0; i < state->config->npthread; ++i) { status = pthread_create(&state->ts[i]->pthread, NULL, &pthread_main, NULL); plat_assert_always(!status); } count = 0; for (i = 0; i < state->config->npthread; ++i) { status = pthread_join(state->ts[i]->pthread, NULL); plat_assert_always(!status); count += state->ts[i]->count; plat_free(state->ts[i]); } plat_free(state->ts); plat_free(state); printf("%ld\n", count/config.secs); } if (shmem_attached) { status = plat_shmem_detach(); if (status) { plat_log_msg(20880, LOG_CAT, PLAT_LOG_LEVEL_FATAL, "shmem detach failure: %s", plat_strerror(-status)); ret = 1; } } plat_shmem_config_destroy(&config.shmem); return (ret); }
int main(int argc, char **argv) { struct plat_opts_config_shmemtest_phys config; int status; size_t paddr_before; struct plat_shmem_alloc_stats init_stats; struct plat_shmem_alloc_stats end_stats; text_sp_t shared_text; const char text_of_doom[] = "Killroy was here"; /* Physmem ininitialization is the same as regular memory */ memset(&config, 0, sizeof(config)); plat_shmem_config_init(&config.shmem); if (plat_opts_parse_shmemtest_phys(&config, argc, argv)) { return (2); } status = plat_shmem_prototype_init(&config.shmem); plat_assert_always(!status); status = plat_shmem_attach(plat_shmem_config_get_path(&config.shmem)); plat_assert_always(!status); status = plat_shmem_alloc_get_stats(&init_stats); plat_assert_always(!status); shared_text = test_start(text_of_doom); plat_assert_always(!text_sp_is_null(shared_text)); paddr_before = plat_shmem_ptr_to_paddr(shared_text); plat_assert_always(paddr_before); test_middle(shared_text, text_of_doom, paddr_before); /* Detach and re-attach */ status = plat_shmem_detach(); plat_assert_always(!status); status = plat_shmem_attach(plat_shmem_config_get_path(&config.shmem)); plat_assert_always(!status); test_middle(shared_text, text_of_doom, paddr_before); test_end(shared_text, text_of_doom); status = plat_shmem_alloc_get_stats(&end_stats); plat_assert_always(!status); plat_assert_always(init_stats.allocated_bytes == end_stats.allocated_bytes); plat_assert_always(init_stats.allocated_count == end_stats.allocated_count); status = plat_shmem_detach(); plat_assert_always(!status); plat_shmem_config_destroy(&config.shmem); return (0); }