/* One group of senders and receivers */ static unsigned int group(pthread_t *pth, unsigned int num_fds, int ready_out, int wakefd) { unsigned int i; struct sender_context *snd_ctx = malloc(sizeof(struct sender_context) + num_fds * sizeof(int)); if (!snd_ctx) barf("malloc()"); for (i = 0; i < num_fds; i++) { int fds[2]; struct receiver_context *ctx = malloc(sizeof(*ctx)); if (!ctx) barf("malloc()"); /* Create the pipe between client and server */ fdpair(fds); ctx->num_packets = num_fds * loops; ctx->in_fds[0] = fds[0]; ctx->in_fds[1] = fds[1]; ctx->ready_out = ready_out; ctx->wakefd = wakefd; pth[i] = create_worker(ctx, (void *)receiver); snd_ctx->out_fds[i] = fds[1]; if (!thread_mode) close(fds[0]); } /* Now we have all the fds, fork the senders */ for (i = 0; i < num_fds; i++) { snd_ctx->ready_out = ready_out; snd_ctx->wakefd = wakefd; snd_ctx->num_fds = num_fds; pth[num_fds+i] = create_worker(snd_ctx, (void *)sender); } /* Close the fds we have left */ if (!thread_mode) for (i = 0; i < num_fds; i++) close(snd_ctx->out_fds[i]); /* Return number of children to reap */ return num_fds * 2; }
void *hackbench_thread(void *t) { unsigned int i, num_groups, total_children; int readyfds[2], wakefds[2]; char dummy; num_groups = 50; t = NULL; fdpair(readyfds); fdpair(wakefds); while (1) { total_children = 0; for (i = 0; i < num_groups; i++) total_children += group(readyfds[1], wakefds[0]); /* Wait for everyone to be ready */ for (i = 0; i < total_children; i++) if (Read(readyfds[0], &dummy, 1) != 1) barf("Reading for readyfds"); /* Kick them off */ if (write(wakefds[1], &dummy, 1) != 1) barf("Writing to start them"); /* Reap them all */ for (i = 0; i < total_children; i++) { int status; wait(&status); if (!WIFEXITED(status)) exit(1); } if (!trywait_sem(&hackthread.sem.stop)) break; } post_sem(&hackthread.sem.complete); return NULL; }
/* One group of senders and receivers */ static unsigned int group(int ready_out, int wakefd) { unsigned int i; int out_fds[NUM_FDS]; for (i = 0; i < NUM_FDS; i++) { int fds[2]; /* Create the pipe between client and server */ fdpair(fds); /* Fork the receiver. */ switch (fork()) { case -1: barf("fork()"); case 0: close(fds[1]); receiver(NUM_FDS*LOOPS, fds[0], ready_out, wakefd); exit(0); } out_fds[i] = fds[1]; close(fds[0]); } /* Now we have all the fds, fork the senders */ for (i = 0; i < NUM_FDS; i++) { switch (fork()) { case -1: barf("fork()"); case 0: sender(out_fds, ready_out, wakefd); exit(0); } } /* Close the fds we have left */ for (i = 0; i < NUM_FDS; i++) close(out_fds[i]); /* Return number of children to reap */ return NUM_FDS * 2; }
int main(int argc, char *argv[]) { unsigned int i; struct timeval start, stop, diff; int readyfds[2], wakefds[2]; char dummy; process_options (argc, argv); printf("Running in %s mode with %d groups using %d file descriptors each (== %d tasks)\n", (process_mode == 0 ? "threaded" : "process"), num_groups, 2*num_fds, num_groups*(num_fds*2)); printf("Each sender will pass %d messages of %d bytes\n", loops, datasize); fflush(NULL); child_tab = calloc(num_fds * 2 * num_groups, sizeof(childinfo_t)); if (!child_tab) barf("main:malloc()"); fdpair(readyfds); fdpair(wakefds); /* Catch some signals */ signal(SIGINT, sigcatcher); signal(SIGTERM, sigcatcher); signal(SIGHUP, SIG_IGN); total_children = 0; for (i = 0; i < num_groups; i++) { int c = group(child_tab, total_children, num_fds, readyfds[1], wakefds[0]); if( c != (num_fds*2) ) { fprintf(stderr, "%i children started. Expected %i\n", c, num_fds*2); reap_workers(child_tab, total_children + c, 1); barf("Creating workers"); } total_children += c; } /* Wait for everyone to be ready */ for (i = 0; i < total_children; i++) if (read(readyfds[0], &dummy, 1) != 1) { reap_workers(child_tab, total_children, 1); barf("Reading for readyfds"); } gettimeofday(&start, NULL); /* Kick them off */ if (write(wakefds[1], &dummy, 1) != 1) { reap_workers(child_tab, total_children, 1); barf("Writing to start senders"); } /* Reap them all */ reap_workers(child_tab, total_children, 0); gettimeofday(&stop, NULL); /* Print time... */ timersub(&stop, &start, &diff); printf("Time: %lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000); free(child_tab); exit(0); }
/* One group of senders and receivers */ static unsigned int group(childinfo_t *child, unsigned int tab_offset, unsigned int num_fds, int ready_out, int wakefd) { unsigned int i; struct sender_context* snd_ctx = malloc (sizeof(struct sender_context) +num_fds*sizeof(int)); if (!snd_ctx) { sneeze("malloc() [sender ctx]"); return 0; } for (i = 0; i < num_fds; i++) { int fds[2]; struct receiver_context* ctx = malloc (sizeof(*ctx)); if (!ctx) { sneeze("malloc() [receiver ctx]"); return (i > 0 ? i-1 : 0); } /* Create the pipe between client and server */ fdpair(fds); ctx->num_packets = num_fds*loops; ctx->in_fds[0] = fds[0]; ctx->in_fds[1] = fds[1]; ctx->ready_out = ready_out; ctx->wakefd = wakefd; child[tab_offset+i] = create_worker(ctx, (void *)(void *)receiver); if( child[tab_offset+i].error < 0 ) { return (i > 0 ? i-1 : 0); } snd_ctx->out_fds[i] = fds[1]; if (process_mode) close(fds[0]); } /* Now we have all the fds, fork the senders */ for (i = 0; i < num_fds; i++) { snd_ctx->ready_out = ready_out; snd_ctx->wakefd = wakefd; snd_ctx->num_fds = num_fds; child[tab_offset+num_fds+i] = create_worker(snd_ctx, (void *)(void *)sender); if( child[tab_offset+num_fds+i].error < 0 ) { return (num_fds+i)-1; } } /* Close the fds we have left */ if (process_mode) for (i = 0; i < num_fds; i++) close(snd_ctx->out_fds[i]); /* Return number of children to reap */ return num_fds * 2; }
int main(int argc, char *argv[]) { unsigned int i, num_groups = 10, total_children; struct timeval start, stop, diff; unsigned int num_fds = 20; int readyfds[2], wakefds[2]; char dummy; pthread_t *pth_tab; if (argv[1] && strcmp(argv[1], "-pipe") == 0) { use_pipes = 1; argc--; argv++; } if (argc >= 2 && (num_groups = atoi(argv[1])) == 0) print_usage_exit(); printf("Running with %d*40 (== %d) tasks.\n", num_groups, num_groups*40); fflush(NULL); if (argc > 2) { if ( !strcmp(argv[2], "process") ) process_mode = 1; else if ( !strcmp(argv[2], "thread") ) process_mode = 0; else print_usage_exit(); } if (argc > 3) loops = atoi(argv[3]); pth_tab = malloc(num_fds * 2 * num_groups * sizeof(pthread_t)); if (!pth_tab) barf("main:malloc()"); fdpair(readyfds); fdpair(wakefds); total_children = 0; for (i = 0; i < num_groups; i++) total_children += group(pth_tab+total_children, num_fds, readyfds[1], wakefds[0]); /* Wait for everyone to be ready */ for (i = 0; i < total_children; i++) if (read(readyfds[0], &dummy, 1) != 1) barf("Reading for readyfds"); gettimeofday(&start, NULL); /* Kick them off */ if (write(wakefds[1], &dummy, 1) != 1) barf("Writing to start them"); /* Reap them all */ for (i = 0; i < total_children; i++) reap_worker(pth_tab[i]); gettimeofday(&stop, NULL); /* Print time... */ timersub(&stop, &start, &diff); printf("Time: %lu.%03lu\n", diff.tv_sec, diff.tv_usec/1000); exit(0); }