1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 12 /**************************************************************************/ 13 /**************************************************************************/ 14 /** */ 15 /** POSIX wrapper for THREADX */ 16 /** */ 17 /** */ 18 /** */ 19 /**************************************************************************/ 20 /**************************************************************************/ 21 22 /* Include necessary system files. */ 23 24 #include "tx_api.h" /* Threadx API */ 25 #include "pthread.h" /* Posix API */ 26 #include "px_int.h" /* Posix helper functions */ 27 #include "time.h" 28 #include <limits.h> 29 30 /**************************************************************************/ 31 /* */ 32 /* FUNCTION RELEASE */ 33 /* */ 34 /* posix_abs_time_to_rel_ticks PORTABLE C */ 35 /* 6.1.7 */ 36 /* AUTHOR */ 37 /* */ 38 /* William E. Lamie, Microsoft Corporation */ 39 /* */ 40 /* DESCRIPTION */ 41 /* */ 42 /* This function converts the absolute time specified in a POSIX */ 43 /* timespec structure into the relative number of timer ticks until */ 44 /* that time will occur. */ 45 /* */ 46 /* RELEASE HISTORY */ 47 /* */ 48 /* DATE NAME DESCRIPTION */ 49 /* */ 50 /* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ 51 /* */ 52 /**************************************************************************/ posix_abs_time_to_rel_ticks(struct timespec * abs_timeout)53ULONG posix_abs_time_to_rel_ticks(struct timespec *abs_timeout) 54 { 55 ULONG current_ticks, ticks_ns, ticks_sec, timeout_ticks; 56 57 current_ticks = tx_time_get(); 58 /* convert ns to ticks (will lose any ns < 1 tick) */ 59 ticks_ns = abs_timeout->tv_nsec / NANOSECONDS_IN_CPU_TICK; 60 /* 61 * if ns < 1 tick were lost, bump up to next tick so the delay is never 62 * less than what was specified. 63 */ 64 if (ticks_ns * NANOSECONDS_IN_CPU_TICK != abs_timeout->tv_nsec) 65 { 66 ++ticks_ns; 67 } 68 ticks_sec = (ULONG) (abs_timeout->tv_sec * CPU_TICKS_PER_SECOND); 69 /* add in sec. ticks, subtract current ticks to get relative value. */ 70 timeout_ticks = ticks_sec + ticks_ns - current_ticks; 71 /* 72 * Unless a relative timeout of zero was specified, bump up 1 tick to 73 * compensate for the fact that there is an unknown time between 0 and 74 * < 1 tick until the next tick. We never want the delay to be less than 75 * what was requested. 76 */ 77 if (timeout_ticks != 0) 78 { 79 ++timeout_ticks; 80 } 81 /* 82 * If the absolute time was in the past, then we need to set the 83 * relative time to zero; otherwise, we get an essentially infinite timeout. 84 */ 85 if (timeout_ticks > LONG_MAX) 86 { 87 timeout_ticks = 0; 88 } 89 90 return timeout_ticks; 91 } 92