tool.h (3795B)
1 #include <time.h> 2 #include <stdarg.h> 3 #include <stdbool.h> 4 #include <inttypes.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <time.h> 8 9 #include "../src/nissy.h" 10 11 static void log_stderr(const char *, ...); 12 static void log_stdout(const char *, ...); 13 static double timerun(void (*)(void), const char *); 14 static void writetable(const char *, int64_t, const char *); 15 static int64_t generatetable(const char *, const char *, char **); 16 static int getdata(const char *, const char *, char **, const char *); 17 static void gendata_run(const char *, const char *, const char *, uint64_t[static 21]); 18 19 static void 20 log_stderr(const char *str, ...) 21 { 22 va_list args; 23 24 va_start(args, str); 25 vfprintf(stderr, str, args); 26 va_end(args); 27 } 28 29 static void 30 write_stdout(const char *str, ...) 31 { 32 va_list args; 33 34 va_start(args, str); 35 vfprintf(stdout, str, args); 36 va_end(args); 37 } 38 39 static double 40 timerun(void (*run)(void), const char *name) 41 { 42 struct timespec start, end; 43 double tdiff, tdsec, tdnano; 44 45 printf("\n"); 46 fflush(stdout); 47 48 if (run == NULL) { 49 printf("> %s: nothing to run!\n", name); 50 fflush(stdout); 51 return -1.0; 52 } 53 54 printf("Running tool: %s\n", name); 55 printf("==========\n"); 56 fflush(stdout); 57 58 clock_gettime(CLOCK_MONOTONIC, &start); 59 run(); 60 clock_gettime(CLOCK_MONOTONIC, &end); 61 62 tdsec = end.tv_sec - start.tv_sec; 63 tdnano = end.tv_nsec - start.tv_nsec; 64 tdiff = tdsec + 1e-9 * tdnano; 65 66 printf("==========\n"); 67 printf("\nTotal time: %.4fs\n", tdiff); 68 fflush(stdout); 69 70 return tdiff; 71 } 72 73 static void 74 writetable(const char *buf, int64_t size, const char *filename) 75 { 76 FILE *f; 77 78 if ((f = fopen(filename, "wb")) == NULL) { 79 fprintf(stderr, "Could not write tables to file %s" 80 ", will be regenerated next time.\n", filename); 81 } else { 82 fwrite(buf, size, 1, f); 83 fclose(f); 84 fprintf(stderr, "Table written to %s.\n", filename); 85 } 86 } 87 88 static int64_t 89 generatetable(const char *solver, const char *options, char **buf) 90 { 91 int64_t size, gensize; 92 93 size = nissy_datasize(solver, options); 94 if (size == -1) { 95 printf("Error getting table size.\n"); 96 return -1; 97 } 98 99 *buf = malloc(size); 100 gensize = nissy_gendata(solver, options, *buf); 101 102 if (gensize != size) { 103 fprintf(stderr, "Error generating table"); 104 if (gensize != -1) 105 fprintf(stderr, " (got %" PRId64 " bytes)", gensize); 106 fprintf(stderr, "\n"); 107 return -2; 108 } 109 110 return gensize; 111 } 112 113 static int 114 getdata( 115 const char *solver, 116 const char *options, 117 char **buf, 118 const char *filename 119 ) { 120 int64_t size, sizeread; 121 FILE *f; 122 123 if ((f = fopen(filename, "rb")) == NULL) { 124 fprintf(stderr, "Table file not found, generating it.\n"); 125 size = generatetable(solver, options, buf); 126 switch (size) { 127 case -1: 128 goto getdata_error_nofree; 129 case -2: 130 goto getdata_error; 131 default: 132 writetable(filename, size, *buf); 133 break; 134 } 135 } else { 136 fprintf(stderr, "Reading tables from file %s\n", filename); 137 size = nissy_datasize(solver, options); 138 *buf = malloc(size); 139 sizeread = fread(*buf, size, 1, f); 140 fclose(f); 141 if (sizeread != 1) { 142 fprintf(stderr, "Error reading table, stopping\n"); 143 goto getdata_error; 144 } 145 } 146 147 return 0; 148 149 getdata_error: 150 free(*buf); 151 getdata_error_nofree: 152 return 1; 153 } 154 155 static void 156 gendata_run( 157 const char *solver, 158 const char *options, 159 const char *filename, /* TODO: remove filename, use solver name */ 160 uint64_t expected[static 21] 161 ) { 162 int64_t size; 163 char *buf; 164 165 166 size = generatetable(solver, options, &buf); 167 switch (size) { 168 case -1: 169 return; 170 case -2: 171 goto gendata_run_finish; 172 default: 173 nissy_datainfo(buf, write_stdout); 174 printf("\n"); 175 printf("Succesfully generated %" PRId64 " bytes. " 176 "See above for details on the tables.\n", size); 177 178 /* TODO: check that the table is correct */ 179 writetable(buf, size, filename); 180 break; 181 } 182 183 gendata_run_finish: 184 free(buf); 185 }