tool.h (5106B)
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 <string.h> 8 9 #include "../src/nissy.h" 10 #include "nissy_extra.h" 11 12 static void log_stderr(const char *, ...); 13 static void log_stdout(const char *, ...); 14 static double timerun(void (*)(void)); 15 static void writetable(const char *, int64_t, const char *); 16 static long long int generatetable(const char *, char **); 17 static long long int derivetable( 18 const char *, const char *, const char *, char **); 19 static int getdata(const char *, char **, const char *); 20 static void gendata_run(const char *, uint64_t[static 21]); 21 static void derivedata_run( 22 const char *, const char *, const char *, const char *); 23 24 static void 25 log_stderr(const char *str, ...) 26 { 27 va_list args; 28 29 va_start(args, str); 30 vfprintf(stderr, str, args); 31 va_end(args); 32 } 33 34 static void 35 write_stdout(const char *str, ...) 36 { 37 va_list args; 38 39 va_start(args, str); 40 vfprintf(stdout, str, args); 41 va_end(args); 42 } 43 44 static double 45 timerun(void (*run)(void)) 46 { 47 struct timespec start, end; 48 double tdiff, tdsec, tdnano; 49 50 fflush(stdout); 51 52 if (run == NULL) { 53 printf("nothing to run!\n"); 54 fflush(stdout); 55 return -1.0; 56 } 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 printf("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 printf("Table written to %s.\n", filename); 85 } 86 } 87 88 static long long int 89 generatetable(const char *solver, char **buf) 90 { 91 long long int size, gensize; 92 93 size = nissy_datasize(solver); 94 if (size < 0) { 95 printf("Error getting table size.\n"); 96 return -1; 97 } 98 99 *buf = malloc(size); 100 gensize = nissy_gendata(solver, size, *buf); 101 102 if (gensize != size) { 103 printf("Error generating table"); 104 if (gensize == NISSY_OK) 105 printf(" (got %lld bytes)", gensize); 106 printf("\n"); 107 return -2; 108 } 109 110 return gensize; 111 } 112 113 static long long int 114 derivetable( 115 const char *solver_large, 116 const char *solver_small, 117 const char *filename_large, 118 char **buf 119 ) 120 { 121 uint8_t h, k; 122 long long int size, gensize; 123 char *fulltable; 124 125 if (getdata(solver_large, &fulltable, filename_large) != 0) { 126 printf("Error reading full table.\n"); 127 gensize = -1; 128 goto derivetable_error_nofree; 129 } 130 131 size = nissy_datasize(solver_small); 132 if (size == -1) { 133 printf("Error getting table size.\n"); 134 gensize = -2; 135 goto derivetable_error; 136 } 137 138 if (parse_h48_solver(solver_small, &h, &k) != 0) { 139 gensize = -3; 140 goto derivetable_error; 141 } 142 143 *buf = malloc(size); 144 gensize = gendata_h48_derive(h, fulltable, *buf); 145 146 if (gensize != size) { 147 printf("Error deriving table\n"); 148 gensize = -4; 149 goto derivetable_error; 150 } 151 152 derivetable_error: 153 free(fulltable); 154 155 derivetable_error_nofree: 156 return gensize; 157 } 158 159 static int 160 getdata( 161 const char *solver, 162 char **buf, 163 const char *filename 164 ) { 165 long long int size, sizeread; 166 FILE *f; 167 168 if ((f = fopen(filename, "rb")) == NULL) { 169 printf("Table file not found, generating it.\n"); 170 size = generatetable(solver, buf); 171 switch (size) { 172 case -1: 173 goto getdata_error_nofree; 174 case -2: 175 goto getdata_error; 176 default: 177 writetable(*buf, size, filename); 178 break; 179 } 180 } else { 181 printf("Reading tables from file %s\n", filename); 182 size = nissy_datasize(solver); 183 *buf = malloc(size); 184 sizeread = fread(*buf, size, 1, f); 185 fclose(f); 186 if (sizeread != 1) { 187 printf("Error reading table, stopping\n"); 188 goto getdata_error; 189 } 190 } 191 192 return 0; 193 194 getdata_error: 195 free(*buf); 196 getdata_error_nofree: 197 return 1; 198 } 199 200 static void 201 gendata_run( 202 const char *solver, 203 uint64_t expected[static 21] 204 ) { 205 long long int size; 206 char *buf, filename[1024]; 207 208 sprintf(filename, "tables/%s", solver); 209 size = generatetable(solver, &buf); 210 switch (size) { 211 case -1: 212 return; 213 case -2: 214 goto gendata_run_finish; 215 default: 216 nissy_datainfo(size, buf, write_stdout); 217 printf("\n"); 218 printf("Succesfully generated %lld bytes. " 219 "See above for details on the tables.\n", size); 220 221 /* TODO: check that the table is correct */ 222 writetable(buf, size, filename); 223 break; 224 } 225 226 gendata_run_finish: 227 free(buf); 228 } 229 230 static void 231 derivedata_run( 232 const char *solver_large, 233 const char *solver_small, 234 const char *filename_large, 235 const char *filename_small 236 ) 237 { 238 long long int size; 239 char *buf; 240 241 buf = NULL; 242 size = derivetable(solver_large, solver_small, filename_large, &buf); 243 switch (size) { 244 case -1: 245 return; 246 case -2: 247 goto derivedata_run_finish; 248 default: 249 nissy_datainfo(size, buf, write_stdout); 250 printf("\n"); 251 printf("Succesfully generated %lld bytes. " 252 "See above for details on the tables.\n", size); 253 254 writetable(buf, size, filename_small); 255 break; 256 } 257 258 derivedata_run_finish: 259 free(buf); 260 }