Hi,
I think we need to restart the time API discussion and specify it only wall time in mind. CPU cycle count APIs can be tuned as a next step. CPU cycle counters are affected by frequency scaling, which makes those difficult to use for counting linear, real time. The time API should specify an easy way to check and use the real, wall clock time. We need at least one time source that will not wrap in years - here it's the "global" time (e.g. in POSIX it's CLOCK_MONOTONIC). Global time can be also compared between threads. Local time is defined for optimizing short interval time checks. It's thread local, may wrap sooner than global time, but may be lower overhead to use. There could be actually four time bases defined in the API, if we'd want to optimize for each use case (global.hi_res, global.low_res, local.hi_res and local.low_res). I'd propose to have only two and give system specific way to configure those (rate and duration). Typical config would be global.low_res and local.hi_res. User can check hz and max time value (wrap around time) with odp_time_info() and adapt (fall back to use global time) if e.g. local time wraps too quickly (e.g. in 4 sec). See the proposal under. -Petri // // Use cases // // high resolution low resolution // short interval long interval // low overhead high overhead // // // global timestamp packets or | timestamp log entries or // other global resources | other global resources // at high rate | at low rate // | // ---------------------------+------------------------------ // | // local timestamp and sort items | measure execution time over // in thread local work queue,| many iterations or over // measure execution time | a "long" function // of a "short" function, | // spin and wait for a short | // while // // // time in nsec // renamed to leave room for sec or other units in the future #define ODP_TIME_NS_USEC 1000ULL /**< Microsecond in nsec */ #define ODP_TIME_NS_MSEC 1000000ULL /**< Millisecond in nsec */ #define ODP_TIME_NS_SEC 1000000000ULL /**< Second in nsec */ #define ODP_TIME_NS_DAY ((24*60*60)*ODP_TIME_NS_SEC) /**< Day in nsec */ // Abstract time type // Implementation specific type, includes e.g. // - counter value // - potentially other information: global vs. local time, ... typedef odp_time_t // Get global time // Global time is common over all threads. Global timestamps can be compared // between threads. odp_time_t odp_time(void); // Get thread local time // Thread local time is only meaningful for the calling thread. It cannot be // compare with other timestamps (global or local from other threads). // May run from different clock source and different rate than global time. // User must take care not to mix local and global time values in API calls. odp_time_t odp_time_local(void); // Compare time values // // Check if t1 is before t2 in absolute time, or if interval t1 is shorter // than interval t2 // // -1: t2 < t1 // 0: t2 == t1 // 1: t2 > t1 int odp_time_cmp(odp_time_t t1, odp_time_t t2); // Sum of t1 and t2 // // User can sum timestamps or accumulate multiple intervals before // comparing or converting to nsec odp_time_t odp_time_sum(odp_time_t t1, odp_time_t t2); // Time difference between t1 and t2 // // Calculate interval from timestamp t1 to t2, or difference of two intervals. // T2 must be the latter timestamp, or the longer interval (t2 >= t1). // Use cmp() first, if don't know which timestamp is the latter/longer. odp_time_t odp_time_diff(odp_time_t t1, odp_time_t t2); // Convert ODP time to wall clock time in nsec // // Wall clock time advances linearly in realtime and starts from 0 in ODP init. // // Global time must not wrap in several years (max time value is defined by // info.global_nsec_max). Local time may have shorter wrap around time // (info.local_nsec_max) than global, but it's also recommended to be years. // // Global and local time may run from different time base and thus result // different nsec values. uint64_t odp_time_to_ns(odp_time_t time); // convert nsec value to global time odp_time_t odp_time_from_ns(uint64_t ns); // convert nsec value to local time odp_time_t odp_time_local_from_ns(uint64_t ns); // Time info structure typedef struct { // Global timestamp resolution in hz uint64_t global_hz; // Max global time value in nsec. Global time values (timestamps or // intervals) larger than this are not handled correctly. // Global wall clock time wraps back to zero after this value. uint64_t global_nsec_max; // Local timestamp resolution in hz uint64_t local_hz; // Max local time value in nsec. Local time values (timestamps or // intervals) larger than this are not handled correctly. // Local wall clock time wraps back to zero after this value. uint64_t local_nsec_max; } odp_time_info_t; // Time info request // // Fill in time info struct. User can check resolutions and max time values¨ // in nsec. // // 0 on success // <0 on failure int odp_time_info(odp_time_info_t *info); _______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp