static int __parse_oneitem_int_section(const char *k, int *v, struct collection_item *ini, const char *section) { struct collection_item *item; int error; if (get_config_item(section, k, ini, &item)) { logsimple(_("error reading value for %s\n"), k); return CLC_CONFIG_RET_ERR_CONF; } else { if (!item) return 0; *v = get_int_config_value(item, 1, 10, &error); if (error) { logsimple(_("error getting %s\n"), k); return CLC_CONFIG_RET_ERR_CONF; } else if (debug_flag == 1) logdebug(_("%s has value %d\n"), k, *v); } return 0; }
static int __parse_oneitem_int(const char *k, int *v, struct collection_item *ini) { struct collection_item *item; int error; if (get_config_item(NULL, k, ini, &item)) { logsimple(_("error reading value for %s\n"), k); return NODE_CONFIG_RET_ERR_CONF; } else { if (!item) return 0; *v = get_int_config_value(item,1, 10, &error); if (error) { logsimple(_("error getting %s\n"), k); return NODE_CONFIG_RET_ERR_CONF; } } return 0; }
int main(int argc, char *argv[]) { int i; if (argc < 2) { printf("Invalid number of arguments!\n"); printf("Usage: %s [config file]\n", argv[0]); exit(EXIT_FAILURE); } read_config_file(argv[1]); // Initialize blocks int nblocks; get_int_config_value("nblocks", &nblocks); nthreads = nblocks; get_int_config_value("blocksize", &blocksize); get_int_config_value("batchsize", &batchsize); for (i = 0; i < nblocks; i++) { // Allocate block in correct node blocks[i] = valloc(blocksize * sizeof(long)); if (!blocks[i]) { perror("valloc"); exit(EXIT_FAILURE); } #if defined(AFFINITY) && defined(linux) char k[80]; sprintf(k, "block%d_node", i); int node; get_int_config_value(k, &node); unsigned long nodemask = 1 << node; if (mbind(blocks[i], blocksize * sizeof(long), MPOL_BIND, &nodemask, sizeof(nodemask) + 1, MPOL_MF_MOVE | MPOL_MF_STRICT) != 0) { perror("mbind (1)"); exit(EXIT_FAILURE); } #endif // Set block initial values int j; for (j = 0; j < blocksize; j++) { blocks[i][j] = j; } // Allocate lock in correct node locks[i] = valloc(sizeof(pthread_mutex_t)); if (!locks[i]) { perror("valloc"); exit(EXIT_FAILURE); } #if defined(AFFINITY) && defined(linux) if (mbind(locks[i], sizeof(pthread_mutex_t), MPOL_BIND, &nodemask, sizeof(nodemask) + 1, MPOL_MF_MOVE | MPOL_MF_STRICT) != 0) { perror("mbind (2)"); exit(EXIT_FAILURE); } #endif // Initialize lock pthread_mutex_init(locks[i], NULL); //printf("Initialized lock %d (address %p) in NUMA node %ld\n", i, locks[i], nodemask); } //long blockbytes = (blocksize * sizeof(long) / MB); //printf("Total memory allocated: %ld MB (block size %ld MB)\n", nblocks * blockbytes, blockbytes); // Launch measure thread pthread_t th; pthread_create(&th, NULL, measure_thread, NULL); // Apply (crappy version of) Fisher-Yates to sort list of threads to launch int shuffle[nthreads]; for (i = 0; i < nthreads; i++) { shuffle[i] = 0; } int sorted[nthreads]; int j = 0; while (j < nthreads) { int n = rand() % nthreads; i = 0; while (1) { if (shuffle[i] == 0) { --n; if (n < 0) break; } i = (i + 1) % nthreads; } shuffle[i] = 1; sorted[j++] = i; } // Launch worker threads struct worker_args args[nthreads]; pthread_t threads[nthreads]; #if defined(AFFINITY) pthread_attr_t a; pthread_attr_init(&a); #endif #if defined(AFFINITY) && defined(__sun) // set system-level contention (instead of process-level contention) pthread_attr_setscope(&a, PTHREAD_SCOPE_SYSTEM); #endif for (i = 0; i < nthreads; i++) { int id = sorted[i]; char k[80]; int block; sprintf(k, "thread%d_block", id); get_int_config_value(k, &block); #if defined(AFFINITY) int cpu; sprintf(k, "thread%d_core", id); get_int_config_value(k, &cpu); #endif #if defined(AFFINITY) && defined(linux) cpu_set_t c; CPU_ZERO(&c); CPU_SET(cpu, &c); #endif args[id].id = id; args[id].block = block; args[id].seed1 = rand(); args[id].seed2 = rand(); #if defined(AFFINITY) args[id].cpu = cpu; pthread_create(&threads[id], &a, worker_thread, &args[id]); #else pthread_create(&threads[id], NULL, worker_thread, &args[id]); #endif } for (i = 0; i < nthreads; i++) { pthread_join(threads[i], NULL); } return 0; }
int main(int argc, char *argv[]) { int i; if (argc < 2) { printf("Invalid number of arguments!\n"); printf("Usage: %s [config file]\n", argv[0]); exit(EXIT_FAILURE); } if (read_config_file(argv[1]) != 0) { printf("Error reading configuration file.\n"); exit(EXIT_FAILURE); } /* * Launch throughput measurement thread. */ pthread_t th; pthread_create(&th, NULL, measure_thread, NULL); /* * Initialize counters. */ if (get_int_config_value("ncounters", &ncounters) != 0) { printf("Error reading 'ncounters'.\n"); exit(EXIT_FAILURE); } if (ncounters > MAXCOUNTERS) { printf("MAXCOUNTERS exceeded!\n"); exit(EXIT_FAILURE); } for (i = 0; i < ncounters; i++) { counters[i] = valloc(sizeof(struct counter_aligned)); if (!counters[i]) { perror("valloc"); exit(EXIT_FAILURE); } #if defined(AFFINITY) /* * Allocate counter in the desired memory node. */ char k[80]; int node; sprintf(k, "counter%d_node", i); if (get_int_config_value(k, &node) != 0) { printf("Error reading '%s'.\n", k); exit(EXIT_FAILURE); } unsigned long nodemask = 1 << node; if (mbind(counters[i], sizeof(struct counter_aligned), MPOL_BIND, &nodemask, sizeof(nodemask) + 1, MPOL_MF_MOVE | MPOL_MF_STRICT) != 0) { perror("mbind"); exit(EXIT_FAILURE); } #endif counters[i]->c = 0; #if defined(PTHREAD_SPIN) pthread_spin_init(&counters[i]->spin, 0); #elif defined(PTHREAD_MUTEX) pthread_mutex_init(&counters[i]->mutex, NULL); #endif } /* * Launch worker threads. */ int nthreads; if (get_int_config_value("nthreads", &nthreads) != 0) { printf("Error reading 'nthreads'.\n"); exit(EXIT_FAILURE); } if (nthreads > MAXTHREADS) { printf("MAXTHREADS exceeded!\n"); exit(EXIT_FAILURE); } pthread_t threads[nthreads]; pthread_attr_t a; pthread_attr_init(&a); /* * Apply (crappy version of) Fisher-Yates to create a randomized list * with the threads to launch. This prevents a deterministic behavior * when affinity is OFF: the OS will be launching threads in different * orders across runs, making the execution vary more. */ int shuffle[nthreads]; for (i = 0; i < nthreads; i++) shuffle[i] = 0; int random[nthreads]; /* holds randomized output list */ int j = 0; while (j < nthreads) { int n = rand() % nthreads; i = 0; while (1) { if (shuffle[i] == 0) { --n; if (n < 0) break; } i = (i + 1) % nthreads; } shuffle[i] = 1; random[j++] = i; } /* * Launch worker threads. */ for (i = 0; i < nthreads; i++) { char k[80]; int counter; sprintf(k, "thread%d_counter", random[i]); if (get_int_config_value(k, &counter) != 0) { printf("Error reading '%s'.\n", k); exit(EXIT_FAILURE); } #if defined(AFFINITY) /* * Allocate worker thread in the desired CPU core. */ int cpu; sprintf(k, "thread%d_core", random[i]); if (get_int_config_value(k, &cpu) != 0) { printf("Error reading '%s'.\n", k); exit(EXIT_FAILURE); } cpu_set_t c; CPU_ZERO(&c); CPU_SET(cpu, &c); pthread_attr_setaffinity_np(&a, sizeof(c), &c); #endif pthread_create(&threads[random[i]], &a, worker_thread, counters[counter]); } /* * Wait for threads to finish. */ for (i = 0; i < nthreads; i++) pthread_join(threads[i], NULL); return 0; }