sleep.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * Copyright 2022-2024 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. if (s > 0)
  29. sleep(s);
  30. usleep(us);
  31. # endif
  32. }
  33. #elif defined(_WIN32) && !defined(OPENSSL_SYS_UEFI)
  34. # include <windows.h>
  35. void OSSL_sleep(uint64_t millis)
  36. {
  37. /*
  38. * Windows' Sleep() takes a DWORD argument, which is smaller than
  39. * a uint64_t, so we need to limit it to 49 days, which should be enough.
  40. */
  41. DWORD limited_millis = (DWORD)-1;
  42. if (millis < limited_millis)
  43. limited_millis = (DWORD)millis;
  44. Sleep(limited_millis);
  45. }
  46. #else
  47. /* Fallback to a busy wait */
  48. # include "internal/time.h"
  49. static void ossl_sleep_secs(uint64_t secs)
  50. {
  51. /*
  52. * sleep() takes an unsigned int argument, which is smaller than
  53. * a uint64_t, so it needs to be limited to 136 years which
  54. * should be enough even for Sleeping Beauty.
  55. */
  56. unsigned int limited_secs = UINT_MAX;
  57. if (secs < limited_secs)
  58. limited_secs = (unsigned int)secs;
  59. sleep(limited_secs);
  60. }
  61. static void ossl_sleep_millis(uint64_t millis)
  62. {
  63. const OSSL_TIME finish
  64. = ossl_time_add(ossl_time_now(), ossl_ms2time(millis));
  65. while (ossl_time_compare(ossl_time_now(), finish) < 0)
  66. /* busy wait */ ;
  67. }
  68. void OSSL_sleep(uint64_t millis)
  69. {
  70. ossl_sleep_secs(millis / 1000);
  71. ossl_sleep_millis(millis % 1000);
  72. }
  73. #endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */