1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-12 19:31:53 +00:00
srs/trunk/3rdparty
Jacob Su e7d78462fe
ST: Use clock_gettime to prevent time jumping backwards. v7.0.17 (#3979)
try to fix #3978 

**Background**
check #3978 

**Research**

I referred the Android platform's solution, because I have android
background, and there is a loop to handle message inside android.


ff007a03c0/core/java/android/os/Handler.java (L701-L706C6)

```
    public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
```


59d9dc1f50/libutils/SystemClock.cpp (L37-L51)

```
/*
 * native public static long uptimeMillis();
 */
int64_t uptimeMillis()
{
    return nanoseconds_to_milliseconds(uptimeNanos());
}


/*
 * public static native long uptimeNanos();
 */
int64_t uptimeNanos()
{
    return systemTime(SYSTEM_TIME_MONOTONIC);
}
```


59d9dc1f50/libutils/Timers.cpp (L32-L55)
```
#if defined(__linux__)
nsecs_t systemTime(int clock) {
    checkClockId(clock);
    static constexpr clockid_t clocks[] = {CLOCK_REALTIME, CLOCK_MONOTONIC,
                                           CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID,
                                           CLOCK_BOOTTIME};
    static_assert(clock_id_max == arraysize(clocks));
    timespec t = {};
    clock_gettime(clocks[clock], &t);
    return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
}
#else
nsecs_t systemTime(int clock) {
    // TODO: is this ever called with anything but REALTIME on mac/windows?
    checkClockId(clock);


    // Clock support varies widely across hosts. Mac OS doesn't support
    // CLOCK_BOOTTIME (and doesn't even have clock_gettime until 10.12).
    // Windows is windows.
    timeval t = {};
    gettimeofday(&t, nullptr);
    return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
}
#endif
```
For Linux system, we can use `clock_gettime` api, but it's first
appeared in Mac OSX 10.12.

`man clock_gettime`

The requirement is to find an alternative way to get the timestamp in
microsecond unit, but the `clock_gettime` get nanoseconds, the math
formula is the nanoseconds / 1000 = microsecond. Then I check the
performance of this api + math division.

I used those code to check the `clock_gettime` performance.

```
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>

int main() {
	struct timeval tv;
	struct timespec ts;
	clock_t start;
	clock_t end;
	long t;

	while (1) {
		start = clock();
		gettimeofday(&tv, NULL);
		end = clock();
		printf("gettimeofday clock is %lu\n", end - start);
		printf("gettimeofday is %lld\n", (tv.tv_sec * 1000000LL + tv.tv_usec));

		start = clock();
		clock_gettime(CLOCK_MONOTONIC, &ts);
		t = ts.tv_sec * 1000000L + ts.tv_nsec / 1000L;
		end = clock();
		printf("clock_monotonic clock is %lu\n", end - start);
		printf("clock_monotonic: seconds is %ld, nanoseconds is %ld, sum is %ld\n", ts.tv_sec, ts.tv_nsec, t);

		start = clock();
		clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
		t = ts.tv_sec * 1000000L + ts.tv_nsec / 1000L;
		end = clock();
		printf("clock_monotonic_raw clock is %lu\n", end - start);
		printf("clock_monotonic_raw: nanoseconds is %ld, sum is %ld\n", ts.tv_nsec, t);

		sleep(3);
	}
	
	return 0;
}

```

Here is output:

env: Mac OS M2 chip.

```
gettimeofday clock is 11
gettimeofday is 1709775727153949
clock_monotonic clock is 2
clock_monotonic: seconds is 1525204, nanoseconds is 409453000, sum is 1525204409453
clock_monotonic_raw clock is 2
clock_monotonic_raw: nanoseconds is 770493000, sum is 1525222770493
```
We can see the `clock_gettime` is faster than `gettimeofday`, so there
are no performance risks.

**MacOS solution**

`clock_gettime` api only available until mac os 10.12, for the mac os
older than 10.12, just keep the `gettimeofday`.
check osx version in `auto/options.sh`, then add MACRO in
`auto/depends.sh`, the MACRO is `MD_OSX_HAS_NO_CLOCK_GETTIME`.


**CYGWIN**
According to google search, it seems the
`clock_gettime(CLOCK_MONOTONIC)` is not support well at least 10 years
ago, but I didn't own an windows machine, so can't verify it. so keep
win's solution.

---------

Co-authored-by: winlin <winlinvip@gmail.com>
2024-10-15 17:52:17 +08:00
..
ffmpeg-4-fit SRS5: MP3: Support decode mp3 by FFmpeg natively. (#296) (#3340) 2022-12-26 18:06:38 +08:00
gperftools-2-fit Squash: Fix bugs 2021-12-26 17:30:51 +08:00
gprof Compress repository, remove gprof files. 2019-12-25 18:30:55 +08:00
gtest-fit UTest: Upgrade gtest to 1.11 and support clion. (#2970) 2022-03-17 16:56:52 +08:00
httpx-static Support SRS Stack token for authentication. v6.0.74 (#3794) 2023-09-08 08:22:45 +08:00
libsrtp-2-fit RISCV: Patch ST and libsrtp. #3115 2022-07-20 21:53:39 +08:00
openssl-1.1-fit AppleM1: Update openssl to v1.1.1l 2022-08-14 22:46:51 +08:00
patches SRT: Log level to debug when no socket to accept. v5.0.180 v6.0.78 (#3696) 2023-09-21 15:10:23 +08:00
signaling Upgrade jquery from 1.10.2 to 1.12.2 (#3571) 2023-06-30 06:28:10 +08:00
srs-bench SmartPtr: Fix SRT source memory leaking. v6.0.134 (#4106) 2024-07-04 16:08:42 +08:00
srt-1-fit Upgrade libsrt to v1.5.3. v5.0.183 v6.0.81 (#3808) 2023-09-21 22:23:56 +08:00
st-srs ST: Use clock_gettime to prevent time jumping backwards. v7.0.17 (#3979) 2024-10-15 17:52:17 +08:00
openssl-OpenSSL_1_0_2u.tar.gz Revert part of 01d5e4da, to keep both openssl 1.0 and 1.1, because SRTP depends on 1.0 2020-04-03 14:03:57 +08:00
opus-1.3.1.tar.gz For #1659, #307, add opus codec library 2020-03-22 14:03:48 +08:00
README.md Upgrade libsrt to v1.5.3. v5.0.183 v6.0.81 (#3808) 2023-09-21 22:23:56 +08:00

http-parser-2.1.zip

nginx-1.5.7.zip

srt-1-fit srt-1.5.3.tar.gz

openssl-1.1-fit openssl-1.1.1l.tar.gz

openssl-1.1.0e.zip openssl-OpenSSL_1_0_2u.tar.gz

libsrtp-2.3.0.tar.gz

ffmpeg-4.2.tar.gz opus-1.3.1.tar.gz

gtest-fit

gperftools-2-fit

st-srs st-1.9.zip state-threads state-threads-1.9.1.tar.gz

JSON

USRSCTP

links: