diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nissy.c | 24 | ||||
| -rw-r--r-- | src/nissy.h | 53 | ||||
| -rw-r--r-- | src/solvers/coord/solve.h | 14 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 69 | ||||
| -rw-r--r-- | src/utils/sleep.h | 48 | ||||
| -rw-r--r-- | src/utils/utils.h | 1 |
6 files changed, 174 insertions, 35 deletions
diff --git a/src/nissy.c b/src/nissy.c index 2dd5a41..acf6ebe 100644 --- a/src/nissy.c +++ b/src/nissy.c | |||
| @@ -460,7 +460,9 @@ nissy_solve( | |||
| 460 | const unsigned char data[data_size], | 460 | const unsigned char data[data_size], |
| 461 | unsigned sols_size, | 461 | unsigned sols_size, |
| 462 | char sols[sols_size], | 462 | char sols[sols_size], |
| 463 | long long stats[static NISSY_SIZE_SOLVE_STATS] | 463 | long long stats[static NISSY_SIZE_SOLVE_STATS], |
| 464 | int (*poll_status)(void *), | ||
| 465 | void *poll_status_data | ||
| 464 | ) | 466 | ) |
| 465 | { | 467 | { |
| 466 | oriented_cube_t oc; | 468 | oriented_cube_t oc; |
| @@ -475,14 +477,23 @@ nissy_solve( | |||
| 475 | 477 | ||
| 476 | oc = readcube(cube); | 478 | oc = readcube(cube); |
| 477 | 479 | ||
| 478 | /* TODO: solve should handle oriented cubes */ | ||
| 479 | |||
| 480 | if (!isconsistent(oc)) { | 480 | if (!isconsistent(oc)) { |
| 481 | LOG("[solve] Error: cube is invalid\n"); | 481 | LOG("[solve] Error: cube is invalid\n"); |
| 482 | return NISSY_ERROR_INVALID_CUBE; | 482 | return NISSY_ERROR_INVALID_CUBE; |
| 483 | } | 483 | } |
| 484 | 484 | ||
| 485 | /* TODO: checks for minmoves, maxmoves, nissflag */ | 485 | if (maxmoves > 20) { |
| 486 | LOG("[solve] 'maxmoves' larger than 20 not supported yet, " | ||
| 487 | "setting it to 20\n"); | ||
| 488 | maxmoves = 20; | ||
| 489 | } | ||
| 490 | |||
| 491 | if (minmoves > maxmoves) { | ||
| 492 | LOG("[solve] value provided for 'minmoves' (%u) is larger " | ||
| 493 | "than that provided for 'maxmoves' (%u), setting " | ||
| 494 | "'minmoves' to %u\n", minmoves, maxmoves, maxmoves); | ||
| 495 | minmoves = maxmoves; | ||
| 496 | } | ||
| 486 | 497 | ||
| 487 | if (maxsols == 0) { | 498 | if (maxsols == 0) { |
| 488 | LOG("[solve] 'maxsols' is 0, returning no solution\n"); | 499 | LOG("[solve] 'maxsols' is 0, returning no solution\n"); |
| @@ -505,11 +516,12 @@ nissy_solve( | |||
| 505 | if (parse_ret != NISSY_OK) | 516 | if (parse_ret != NISSY_OK) |
| 506 | return parse_ret; | 517 | return parse_ret; |
| 507 | return solve_h48(oc, minmoves, maxmoves, maxsols, | 518 | return solve_h48(oc, minmoves, maxmoves, maxsols, |
| 508 | optimal, t, data_size, data, sols_size, sols, stats); | 519 | optimal, t, data_size, data, sols_size, sols, stats, |
| 520 | poll_status, poll_status_data); | ||
| 509 | } else if (!strncmp(solver, "coord_", 6)) { | 521 | } else if (!strncmp(solver, "coord_", 6)) { |
| 510 | return solve_coord_dispatch(oc, solver + 6, nissflag, | 522 | return solve_coord_dispatch(oc, solver + 6, nissflag, |
| 511 | minmoves, maxmoves, maxsols, optimal, t, data_size, data, | 523 | minmoves, maxmoves, maxsols, optimal, t, data_size, data, |
| 512 | sols_size, sols); | 524 | sols_size, sols, poll_status, poll_status_data); |
| 513 | } else { | 525 | } else { |
| 514 | LOG("[solve] Error: unknown solver '%s'\n", solver); | 526 | LOG("[solve] Error: unknown solver '%s'\n", solver); |
| 515 | return NISSY_ERROR_INVALID_SOLVER; | 527 | return NISSY_ERROR_INVALID_SOLVER; |
diff --git a/src/nissy.h b/src/nissy.h index 5800490..2fa4a75 100644 --- a/src/nissy.h +++ b/src/nissy.h | |||
| @@ -37,6 +37,11 @@ for example 'rotation UF' or 'mirrored BL'. | |||
| 37 | #define NISSY_NISSFLAG_ALL \ | 37 | #define NISSY_NISSFLAG_ALL \ |
| 38 | (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED) | 38 | (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED) |
| 39 | 39 | ||
| 40 | /* Status for stopping / pausing / resuming a solver */ | ||
| 41 | #define NISSY_STATUS_RUN 0 | ||
| 42 | #define NISSY_STATUS_STOP 1 | ||
| 43 | #define NISSY_STATUS_PAUSE 2 | ||
| 44 | |||
| 40 | /* The solved cube */ | 45 | /* The solved cube */ |
| 41 | #define NISSY_SOLVED_CUBE "ABCDEFGH=ABCDEFGHIJKL=A" | 46 | #define NISSY_SOLVED_CUBE "ABCDEFGH=ABCDEFGHIJKL=A" |
| 42 | 47 | ||
| @@ -296,24 +301,32 @@ nissy_checkdata( | |||
| 296 | Solve the given cube using the given solver and options. | 301 | Solve the given cube using the given solver and options. |
| 297 | 302 | ||
| 298 | Parameters: | 303 | Parameters: |
| 299 | cube - The cube to solver. | 304 | cube - The cube to solver. |
| 300 | solver - The name of the solver. | 305 | solver - The name of the solver. |
| 301 | nissflag - The flags for NISS (linear, inverse, mixed, or combinations). | 306 | nissflag - The flags for NISS (linear, inverse, mixed, or |
| 302 | minmoves - The minimum number of moves for a solution. | 307 | combinations; see the constants at the top of this file). |
| 303 | maxmoves - The maximum number of moves for a solution. | 308 | minmoves - The minimum number of moves for a solution. |
| 304 | maxsols - The maximum number of solutions. | 309 | maxmoves - The maximum number of moves for a solution. |
| 305 | optimal - The maximum number of moves above the optimal solution length. | 310 | maxsols - The maximum number of solutions. |
| 306 | threads - The number of threads to use. Must be less than or equalt to | 311 | optimal - The maximum number of moves above the optimal solution. |
| 307 | the value of the compile-time constant THREADS. If set to 0, | 312 | threads - The number of threads to use. Must be less than or equal |
| 308 | the default value THREADS will be used. | 313 | to the value of the compile-time constant THREADS. If set |
| 309 | data_size - The size of the data buffer. | 314 | to 0, the default value THREADS will be used. |
| 310 | data - The data for the solver. Can be computed with gendata. | 315 | data_size - The size of the data buffer. |
| 311 | This buffer must have 8-byte alignment. | 316 | data - The data for the solver. Can be computed with gendata. |
| 312 | sols_size - The size of the solutions buffer. | 317 | This buffer must have 8-byte alignment. |
| 313 | sols - The return parameter for the solutions. The solutions are | 318 | sols_size - The size of the solutions buffer. |
| 314 | separated by a '\n' (newline) and a '\0' (NULL character) | 319 | sols - The return parameter for the solutions. The solutions are |
| 315 | terminates the list. | 320 | separated by a '\n' (newline) and a '\0' (NULL character) |
| 316 | stats - An array to store some statistics about the solve. | 321 | terminates the list. |
| 322 | stats - An array to store some statistics about the solve. | ||
| 323 | poll_status - A callback function that should return the current | ||
| 324 | requested status for the solver (e.g. run, stop, pause, | ||
| 325 | resume; see the constants at the top of this file). The | ||
| 326 | way this status is polled and honored is solver-specific. | ||
| 327 | If this parameter is NULL, the status will always assumed | ||
| 328 | to be "run". | ||
| 329 | poll_status_data - Auxiliary data for the poll_status callback function. | ||
| 317 | 330 | ||
| 318 | Return values: | 331 | Return values: |
| 319 | NISSY_OK - Cube solved succesfully. | 332 | NISSY_OK - Cube solved succesfully. |
| @@ -340,7 +353,9 @@ nissy_solve( | |||
| 340 | const unsigned char data[data_size], | 353 | const unsigned char data[data_size], |
| 341 | unsigned sols_size, | 354 | unsigned sols_size, |
| 342 | char sols[sols_size], | 355 | char sols[sols_size], |
| 343 | long long stats[static NISSY_SIZE_SOLVE_STATS] | 356 | long long stats[static NISSY_SIZE_SOLVE_STATS], |
| 357 | int (*poll_status)(void *), | ||
| 358 | void *poll_status_data | ||
| 344 | ); | 359 | ); |
| 345 | 360 | ||
| 346 | /* | 361 | /* |
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h index 48cc704..8eb3e9d 100644 --- a/src/solvers/coord/solve.h +++ b/src/solvers/coord/solve.h | |||
| @@ -14,10 +14,10 @@ typedef struct { | |||
| 14 | 14 | ||
| 15 | STATIC int64_t solve_coord(oriented_cube_t, coord_t [static 1], uint8_t, | 15 | STATIC int64_t solve_coord(oriented_cube_t, coord_t [static 1], uint8_t, |
| 16 | uint8_t, uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t, | 16 | uint8_t, uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t, |
| 17 | const unsigned char *, size_t n, char [n]); | 17 | const unsigned char *, size_t n, char [n], int (*)(void *), void *); |
| 18 | STATIC int64_t solve_coord_dispatch(oriented_cube_t, const char *, uint8_t, | 18 | STATIC int64_t solve_coord_dispatch(oriented_cube_t, const char *, uint8_t, |
| 19 | uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t, | 19 | uint8_t, uint8_t, uint64_t, uint8_t, uint8_t, uint64_t, |
| 20 | const unsigned char *, size_t n, char [n]); | 20 | const unsigned char *, size_t n, char [n], int (*)(void *), void *); |
| 21 | STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]); | 21 | STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]); |
| 22 | STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]); | 22 | STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]); |
| 23 | STATIC bool coord_continue_onnormal(const dfsarg_solve_coord_t [static 1]); | 23 | STATIC bool coord_continue_onnormal(const dfsarg_solve_coord_t [static 1]); |
| @@ -211,7 +211,9 @@ solve_coord_dispatch( | |||
| 211 | uint64_t data_size, | 211 | uint64_t data_size, |
| 212 | const unsigned char *data, | 212 | const unsigned char *data, |
| 213 | size_t solutions_size, | 213 | size_t solutions_size, |
| 214 | char sols[solutions_size] | 214 | char sols[solutions_size], |
| 215 | int (*poll_status)(void *), | ||
| 216 | void *poll_status_data | ||
| 215 | ) | 217 | ) |
| 216 | { | 218 | { |
| 217 | coord_t *coord; | 219 | coord_t *coord; |
| @@ -233,7 +235,7 @@ solve_coord_dispatch( | |||
| 233 | 235 | ||
| 234 | return solve_coord(oc, coord, axis, nissflag, minmoves, maxmoves, | 236 | return solve_coord(oc, coord, axis, nissflag, minmoves, maxmoves, |
| 235 | maxsolutions, optimal, threads, data_size, data, | 237 | maxsolutions, optimal, threads, data_size, data, |
| 236 | solutions_size, sols); | 238 | solutions_size, sols, poll_status, poll_status_data); |
| 237 | } | 239 | } |
| 238 | 240 | ||
| 239 | STATIC int64_t | 241 | STATIC int64_t |
| @@ -250,7 +252,9 @@ solve_coord( | |||
| 250 | uint64_t data_size, | 252 | uint64_t data_size, |
| 251 | const unsigned char *data, | 253 | const unsigned char *data, |
| 252 | size_t solutions_size, | 254 | size_t solutions_size, |
| 253 | char sols[solutions_size] | 255 | char sols[solutions_size], |
| 256 | int (*poll_status)(void *), | ||
| 257 | void *poll_status_data | ||
| 254 | ) | 258 | ) |
| 255 | { | 259 | { |
| 256 | int8_t d; | 260 | int8_t d; |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index e3ef9b9..f2967ed 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -35,6 +35,10 @@ typedef struct { | |||
| 35 | solve_h48_task_t *tasks; | 35 | solve_h48_task_t *tasks; |
| 36 | int thread_id; | 36 | int thread_id; |
| 37 | pthread_mutex_t *solutions_mutex; | 37 | pthread_mutex_t *solutions_mutex; |
| 38 | int (*poll_status)(void *); | ||
| 39 | void *poll_status_data; | ||
| 40 | _Atomic bool cancelled; | ||
| 41 | _Atomic bool cantsleep; | ||
| 38 | } dfsarg_solve_h48_t; | 42 | } dfsarg_solve_h48_t; |
| 39 | 43 | ||
| 40 | typedef struct { | 44 | typedef struct { |
| @@ -50,11 +54,12 @@ STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t [static 1]); | |||
| 50 | STATIC int64_t solve_h48_maketasks( | 54 | STATIC int64_t solve_h48_maketasks( |
| 51 | dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1], | 55 | dfsarg_solve_h48_t [static 1], dfsarg_solve_h48_maketasks_t [static 1], |
| 52 | solve_h48_task_t [static STARTING_CUBES], int [static 1]); | 56 | solve_h48_task_t [static STARTING_CUBES], int [static 1]); |
| 57 | STATIC bool solve_h48_runthread_continue(dfsarg_solve_h48_t *); | ||
| 53 | STATIC void *solve_h48_runthread(void *); | 58 | STATIC void *solve_h48_runthread(void *); |
| 54 | STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); | 59 | STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); |
| 55 | STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, | 60 | STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, |
| 56 | uint8_t, uint64_t, const unsigned char *, size_t n, char [n], | 61 | uint8_t, uint64_t, const unsigned char *, size_t n, char [n], |
| 57 | long long [static NISSY_SIZE_SOLVE_STATS]); | 62 | long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); |
| 58 | 63 | ||
| 59 | STATIC_INLINE bool | 64 | STATIC_INLINE bool |
| 60 | solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) | 65 | solve_h48_stop(dfsarg_solve_h48_t arg[static 1]) |
| @@ -232,16 +237,42 @@ solve_h48_dfs(dfsarg_solve_h48_t arg[static 1]) | |||
| 232 | return ret; | 237 | return ret; |
| 233 | } | 238 | } |
| 234 | 239 | ||
| 240 | STATIC bool | ||
| 241 | solve_h48_runthread_continue(dfsarg_solve_h48_t *arg) | ||
| 242 | { | ||
| 243 | int status; | ||
| 244 | |||
| 245 | for (status = NISSY_STATUS_PAUSE; status == NISSY_STATUS_PAUSE; ) { | ||
| 246 | status = arg->poll_status == NULL ? NISSY_STATUS_RUN : | ||
| 247 | arg->poll_status(arg->poll_status_data); | ||
| 248 | msleep(500); | ||
| 249 | } | ||
| 250 | |||
| 251 | return status == NISSY_STATUS_RUN; | ||
| 252 | } | ||
| 253 | |||
| 235 | STATIC void * | 254 | STATIC void * |
| 236 | solve_h48_runthread(void *arg) | 255 | solve_h48_runthread(void *arg) |
| 237 | { | 256 | { |
| 238 | int i, j; | 257 | int i, j, status; |
| 239 | solve_h48_task_t task; | 258 | solve_h48_task_t task; |
| 240 | dfsarg_solve_h48_t *dfsarg; | 259 | dfsarg_solve_h48_t *dfsarg; |
| 241 | 260 | ||
| 242 | dfsarg = (dfsarg_solve_h48_t *)arg; | 261 | dfsarg = (dfsarg_solve_h48_t *)arg; |
| 243 | 262 | ||
| 244 | for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) { | 263 | for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) { |
| 264 | status = dfsarg->poll_status == NULL ? NISSY_STATUS_RUN : | ||
| 265 | dfsarg->poll_status(dfsarg->poll_status_data); | ||
| 266 | switch (status) { | ||
| 267 | case NISSY_STATUS_STOP: | ||
| 268 | goto solve_h48_runthread_cancel; | ||
| 269 | case NISSY_STATUS_PAUSE: | ||
| 270 | if (!NISSY_CANSLEEP) | ||
| 271 | goto solve_h48_runthread_cantsleep; | ||
| 272 | if (!solve_h48_runthread_continue(dfsarg)) | ||
| 273 | goto solve_h48_runthread_cancel; | ||
| 274 | } | ||
| 275 | |||
| 245 | task = dfsarg->tasks[i]; | 276 | task = dfsarg->tasks[i]; |
| 246 | 277 | ||
| 247 | solution_moves_reset(dfsarg->solution_moves); | 278 | solution_moves_reset(dfsarg->solution_moves); |
| @@ -265,6 +296,12 @@ solve_h48_runthread(void *arg) | |||
| 265 | } | 296 | } |
| 266 | 297 | ||
| 267 | return NULL; | 298 | return NULL; |
| 299 | |||
| 300 | solve_h48_runthread_cantsleep: | ||
| 301 | dfsarg->cantsleep = true; | ||
| 302 | solve_h48_runthread_cancel: | ||
| 303 | dfsarg->cancelled = true; | ||
| 304 | return NULL; | ||
| 268 | } | 305 | } |
| 269 | 306 | ||
| 270 | STATIC int64_t | 307 | STATIC int64_t |
| @@ -351,9 +388,12 @@ solve_h48( | |||
| 351 | const unsigned char *data, | 388 | const unsigned char *data, |
| 352 | size_t solutions_size, | 389 | size_t solutions_size, |
| 353 | char solutions[solutions_size], | 390 | char solutions[solutions_size], |
| 354 | long long stats[static NISSY_SIZE_SOLVE_STATS] | 391 | long long stats[static NISSY_SIZE_SOLVE_STATS], |
| 392 | int (*poll_status)(void *), | ||
| 393 | void *poll_status_data | ||
| 355 | ) | 394 | ) |
| 356 | { | 395 | { |
| 396 | bool anycancelled, anycantsleep; | ||
| 357 | int i, ntasks, eoesep_table_index; | 397 | int i, ntasks, eoesep_table_index; |
| 358 | int8_t d; | 398 | int8_t d; |
| 359 | dfsarg_solve_h48_t arg[THREADS]; | 399 | dfsarg_solve_h48_t arg[THREADS]; |
| @@ -434,6 +474,10 @@ solve_h48( | |||
| 434 | .threads = threads, | 474 | .threads = threads, |
| 435 | .thread_id = i, | 475 | .thread_id = i, |
| 436 | .solutions_mutex = &solutions_mutex, | 476 | .solutions_mutex = &solutions_mutex, |
| 477 | .poll_status = poll_status, | ||
| 478 | .poll_status_data = poll_status_data, | ||
| 479 | .cancelled = false, | ||
| 480 | .cantsleep = false, | ||
| 437 | }; | 481 | }; |
| 438 | 482 | ||
| 439 | } | 483 | } |
| @@ -460,9 +504,10 @@ solve_h48( | |||
| 460 | 504 | ||
| 461 | LOG("[H48 solve] Prepared %d tasks\n", ntasks); | 505 | LOG("[H48 solve] Prepared %d tasks\n", ntasks); |
| 462 | 506 | ||
| 507 | anycancelled = anycantsleep = false; | ||
| 463 | for ( | 508 | for ( |
| 464 | d = MAX(minmoves, STARTING_MOVES + 1); | 509 | d = MAX(minmoves, STARTING_MOVES + 1); |
| 465 | !solutions_done(&sollist, &settings, d); | 510 | !(solutions_done(&sollist, &settings, d) || anycancelled); |
| 466 | d++ | 511 | d++ |
| 467 | ) { | 512 | ) { |
| 468 | if (d >= 15) | 513 | if (d >= 15) |
| @@ -474,8 +519,22 @@ solve_h48( | |||
| 474 | pthread_create( | 519 | pthread_create( |
| 475 | &thread[i], NULL, solve_h48_runthread, &arg[i]); | 520 | &thread[i], NULL, solve_h48_runthread, &arg[i]); |
| 476 | } | 521 | } |
| 477 | for (i = 0; i < threads; i++) | 522 | for (i = 0; i < threads; i++) { |
| 478 | pthread_join(thread[i], NULL); | 523 | pthread_join(thread[i], NULL); |
| 524 | anycancelled = anycancelled || arg[i].cancelled; | ||
| 525 | anycantsleep = anycantsleep || arg[i].cantsleep; | ||
| 526 | } | ||
| 527 | } | ||
| 528 | |||
| 529 | if (anycantsleep) { | ||
| 530 | LOG("[H48 solve] Received pause request, but this feature is " | ||
| 531 | "not available on this system. " | ||
| 532 | "Taking it as a stop request.\n"); | ||
| 533 | } | ||
| 534 | |||
| 535 | if (anycancelled) { | ||
| 536 | LOG("[H48 solve] Received stop request, ending solution " | ||
| 537 | "search early.\n"); | ||
| 479 | } | 538 | } |
| 480 | 539 | ||
| 481 | solve_h48_done: | 540 | solve_h48_done: |
diff --git a/src/utils/sleep.h b/src/utils/sleep.h new file mode 100644 index 0000000..d618e9b --- /dev/null +++ b/src/utils/sleep.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | STATIC void msleep(int); | ||
| 2 | |||
| 3 | #if defined(WIN32) | ||
| 4 | |||
| 5 | #define NISSY_CANSLEEP true | ||
| 6 | |||
| 7 | STATIC void | ||
| 8 | msleep(int milliseconds) | ||
| 9 | { | ||
| 10 | Sleep(milliseconds); | ||
| 11 | } | ||
| 12 | |||
| 13 | #elif defined(__wasm__) | ||
| 14 | |||
| 15 | #include <emscripten.h> | ||
| 16 | |||
| 17 | #define NISSY_CANSLEEP true | ||
| 18 | |||
| 19 | STATIC void | ||
| 20 | msleep(int milliseconds) | ||
| 21 | { | ||
| 22 | emscripten_sleep(milliseconds); | ||
| 23 | } | ||
| 24 | |||
| 25 | #elif defined(__unix__) | ||
| 26 | |||
| 27 | #include <time.h> | ||
| 28 | |||
| 29 | #define NISSY_CANSLEEP true | ||
| 30 | |||
| 31 | STATIC void | ||
| 32 | msleep(int milliseconds) | ||
| 33 | { | ||
| 34 | struct timespec t; | ||
| 35 | t.tv_sec = milliseconds / 1000; | ||
| 36 | t.tv_nsec = (milliseconds % 1000) * 1000000; | ||
| 37 | nanosleep(&t, NULL); | ||
| 38 | } | ||
| 39 | |||
| 40 | #else | ||
| 41 | |||
| 42 | #define NISSY_CANSLEEP false | ||
| 43 | STATIC void | ||
| 44 | msleep(int milliseconds) | ||
| 45 | { | ||
| 46 | } | ||
| 47 | |||
| 48 | #endif | ||
diff --git a/src/utils/utils.h b/src/utils/utils.h index ce4355e..d14b285 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | #include "dbg_log.h" | 1 | #include "dbg_log.h" |
| 2 | #include "constants.h" | 2 | #include "constants.h" |
| 3 | #include "math.h" | 3 | #include "math.h" |
| 4 | #include "sleep.h" | ||
