37 #include <sys/signal.h>
41 #include <sys/types.h>
74 int my_popen(
char *cmd,
char **args,
int n, pid_t *pid);
101 #if defined(O_NONBLOCK)
103 if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
106 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
112 return ioctl(fd, FIOBIO, &flags);
134 my_popen(
char *cmd,
char **args,
int n, pid_t *pid)
147 argv = malloc((n+2) *
sizeof *argv);
149 argv[0] = basename(cmd);
151 DBGPRINTF(
"cmd:%s base:%s\n", cmd, argv[0]);
153 for(i=1; i<n+1; i++) {
154 DBGPRINTF(
"%s\n", args[i-1]);
158 argv[i] = (
char *)NULL;
165 if((*pid = fork()) > 0) {
180 dup2(p[1], STDOUT_FILENO);
183 dup2(p[1], STDERR_FILENO);
192 ERRPRINTF(
"child: exec failure, exiting.\n");
217 printf(
"received SIGCHLD\n");
238 struct timeval wall_t, used_t;
239 long long complexity;
243 rc = sscanf(output,
"%ld %ld\n%ld %ld\n%lld", &(wall_t.tv_sec),
244 &(wall_t.tv_usec), &(used_t.tv_sec), &(used_t.tv_usec),
252 LOGPRINTF(
"wall secs: %ld usecs: %ld\n", wall_t.tv_sec, wall_t.tv_usec);
253 LOGPRINTF(
"used secs: %ld usecs: %ld\n", used_t.tv_sec, used_t.tv_usec);
255 if(wall_t.tv_sec == 0 && wall_t.tv_usec == 0) {
256 ERRPRINTF(
"Zero execution wall-time parsed from bench output.\n");
260 if(complexity == 0) {
261 ERRPRINTF(
"Zero complexity value parsed from bench output.\n");
268 ERRPRINTF(
"Errory allocating benchmark structure.\n");
276 ERRPRINTF(
"Error copying benchmark parameters.\n");
283 b->
next = (
void *)NULL;
318 return (
double)tv.tv_sec + (double)tv.tv_usec/1000000.0;
356 if(tmp_args == NULL) {
357 ERRPRINTF(
"Error duplicating exe arg string.\n");
362 tmp_args_len = (int)strlen(tmp_args) +1;
366 tok = strtok_r(tmp_args, sep, &last);
367 DBGPRINTF(
"token %d:%s\n", count, tok);
371 tok = strtok_r(NULL, sep, &last);
377 arg_strings = malloc(arg_n *
sizeof *arg_strings);
378 if(arg_strings == NULL) {
379 ERRPRINTF(
"Error allocating argument array.\n");
383 DBGPRINTF(
"arg_n:%d\n", arg_n);
390 for(i=0; i<tmp_args_len; i++) {
392 if(tmp_args[i] !=
'\0') {
393 arg_strings[j++] = strdup(&tmp_args[i]);
398 if(tmp_args[i] ==
'\0') {
403 DBGPRINTF(
"%d:%c\n", i, tmp_args[i]);
409 ERRPRINTF(
"Error copying tokens into array.\n");
417 for(i=0; i<arg_n; i++, j++) {
418 arg_strings[j] = malloc((1+snprintf(NULL, 0,
"%d", params[i])) *
419 sizeof *arg_strings[j]);
421 sprintf(arg_strings[j],
"%d", params[i]);
423 DBGPRINTF(
"arg_strings[%d]:%s\n", j, arg_strings[j]);
431 arg_strings = malloc(arg_n *
sizeof *arg_strings);
432 for(i=0; i<arg_n; i++) {
434 arg_strings[i] = malloc((1+snprintf(NULL, 0,
"%d", params[i]))
435 *
sizeof *arg_strings[i]);
437 sprintf(arg_strings[i],
"%d", params[i]);
444 for(i=0; i>arg_n; i++) {
445 free(arg_strings[i]);
446 arg_strings[i] = NULL;
468 if(kill(bench_pid, SIGKILL) != 0) {
469 ERRPRINTF(
"error sending kill to benchmark.\n");
473 ERRPRINTF(
"Error closing file pointer to command\n");
503 struct timeval tv_select_wait;
512 fp = fdopen(fd,
"r");
514 ERRPRINTF(
"Error opening file descriptor\n");
522 output = calloc(bs,
sizeof *output);
532 FD_SET(fd, &read_set);
533 tv_select_wait.tv_sec = 5;
534 tv_select_wait.tv_usec = 0;
540 select_ret = select(fd+1, &read_set, NULL, NULL, &tv_select_wait);
545 ERRPRINTF(
"Error waiting for benchmark output.\n");
557 else if(select_ret == 0) {
562 else if(select_ret > 0) {
571 r_count = fread(&output[output_index],
sizeof *output,
582 tmp_output = realloc(output,
583 output_size + r_count *
sizeof *output);
585 if(tmp_output == NULL) {
587 ERRPRINTF(
"Error reallocating mem. to read buffer.\n");
607 output_index += r_count;
608 output_size += r_count;
615 output[output_index] =
'\0';
646 LOGPRINTF(
"signal_quit set, closing files and freeing"
648 LOGPRINTF(
"killing benchmark process pid:%d\n", (
int)bench_pid);
667 ERRPRINTF(
"Error closing file pointer to command\n");
702 ret = (
int*)malloc(
sizeof *ret);
728 ERRPRINTF(
"Error selecting new benchmark point.\n");
747 ERRPRINTF(
"Error spawning benchmark process, fd:%d pid:%d\n", (
int)fd,
768 ERRPRINTF(
"Error reading benchmark output.\n");
778 else if(temp_ret == 1) {
779 DBGPRINTF(
"Recieved quit while reading benchmark output.\n");
792 if(waitpid(bench_pid, &bench_status, 0) != bench_pid) {
793 ERRPRINTF(
"Error waiting for benchmark to terminate.\n");
799 ERRPRINTF(
"benchmark exited with abnormal status:%s.\n",
802 ERRPRINTF(
"output was:\n--------\n%s---------\n", output);
817 DBGPRINTF(
"---output---\n%s------------\n", output);
822 ERRPRINTF(
"Error parsing benchmark output\n");
846 DBGPRINTF(
"Inserting benchmark with naive construction method.\n");
861 DBGPRINTF(
"Inserting benchmark with GBBP.\n");
875 ERRPRINTF(
"Interval error when inserting new benchmark.\n");
879 ERRPRINTF(
"Error inserting new benchmark.\n");
911 DBGPRINTF(
"Writing model ...\n");
914 ERRPRINTF(
"Error writing model to disk.\n");
926 DBGPRINTF(
"Not writing model "
927 "(unwritten_num_execs/thres:%d/%d "
928 "unwritten_time_spend/thres:%f/%d) ...\n",
938 LOGPRINTF(
"benchmark thread: finished.\n");
955 LOGPRINTF(
"locking executing_benchmark.\n");
958 LOGPRINTF(
"unlocking executing_benchmark.\n");
972 switch(bench_status) {
977 return "argument number fail";
980 return "argument parse failure";
983 return "memory allocation failutre";
986 return "routine execution failure";
989 return "general failure";
992 return "unknown exit status";