sleep.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <openssl/crypto.h>
  10. #include "internal/e_os.h"
  11. /* system-specific variants defining OSSL_sleep() */
  12. #if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
  13. #include <unistd.h>
  14. void OSSL_sleep(uint64_t millis)
  15. {
  16. # ifdef OPENSSL_SYS_VXWORKS
  17. struct timespec ts;
  18. ts.tv_sec = (long int) (millis / 1000);
  19. ts.tv_nsec = (long int) (millis % 1000) * 1000000ul;
  20. nanosleep(&ts, NULL);
  21. # elif defined(__TANDEM) && !defined(_REENTRANT)
  22. # include <cextdecs.h(PROCESS_DELAY_)>
  23. /* HPNS does not support usleep for non threaded apps */
  24. PROCESS_DELAY_(millis * 1000);
  25. # else
  26. unsigned int s = (unsigned int)(millis / 1000);
  27. unsigned int us = (unsigned int)((millis % 1000) * 1000);
  28. sleep(s);
  29. usleep(us);
  30. # endif
  31. }
  32. #elif defined(_WIN32) && !defined(OPENSSL_SYS_UEFI)
  33. # include <windows.h>
  34. void OSSL_sleep(uint64_t millis)
  35. {
  36. /*
  37. * Windows' Sleep() takes a DWORD argument, which is smaller than
  38. * a uint64_t, so we need to limit it to 49 days, which should be enough.
  39. */
  40. DWORD limited_millis = (DWORD)-1;
  41. if (millis < limited_millis)
  42. limited_millis = (DWORD)millis;
  43. Sleep(limited_millis);
  44. }
  45. #else
  46. /* Fallback to a busy wait */
  47. # include "internal/time.h"
  48. static void ossl_sleep_secs(uint64_t secs)
  49. {
  50. /*
  51. * sleep() takes an unsigned int argument, which is smaller than
  52. * a uint64_t, so it needs to be limited to 136 years which
  53. * should be enough even for Sleeping Beauty.
  54. */
  55. unsigned int limited_secs = UINT_MAX;
  56. if (secs < limited_secs)
  57. limited_secs = (unsigned int)secs;
  58. sleep(limited_secs);
  59. }
  60. static void ossl_sleep_millis(uint64_t millis)
  61. {
  62. const OSSL_TIME finish
  63. = ossl_time_add(ossl_time_now(), ossl_ms2time(millis));
  64. while (ossl_time_compare(ossl_time_now(), finish) < 0)
  65. /* busy wait */ ;
  66. }
  67. void OSSL_sleep(uint64_t millis)
  68. {
  69. ossl_sleep_secs(millis / 1000);
  70. ossl_sleep_millis(millis % 1000);
  71. }
  72. #endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */