sleep.c 2.5 KB

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