Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core] Added SRT_SYNC_CLOCK_TYPE preprocessor definition #1885

Merged
merged 5 commits into from
Mar 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions docs/API-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2492,7 +2492,7 @@ the sending to a stream with a handler function that will receive them.

[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions)

---
---

### srt_setlogflags

Expand All @@ -2513,6 +2513,9 @@ The following flags are available, as collected in the `logging_api.h` public he
- `SRT_LOGF_DISABLE_SEVERITY`: Do not provide severity information in the header
- `SRT_LOGF_DISABLE_EOL`: Do not add the end-of-line character to the log line

[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions)

---


## Time Access
Expand Down Expand Up @@ -2578,7 +2581,6 @@ although it's highly recommended to use one of the above monotonic clocks,
as system clock is vulnerable to time modifications during transmission.



[:arrow_up:   Back to List of Functions & Structures](#srt-api-functions)


Expand Down Expand Up @@ -2624,9 +2626,11 @@ and `msTimeStamp` value of the `SRT_TRACEBSTATS` (see [statistics.md](statistics
| <img width=240px height=1px/> | <img width=710px height=1px/> |


---
[:arrow_up: &nbsp; Back to List of Functions & Structures](#srt-api-functions)

---

## Diagnostics
## Diagnostics

General notes concerning the `getlasterror` diagnostic functions: when an API
function ends up with error, this error information is stored in a thread-local
Expand Down Expand Up @@ -3221,7 +3225,7 @@ The operation timed out. This can happen if you have a timeout set by an option
extra argument ([`srt_epoll_wait`](#srt_epoll_wait) or [`srt_accept_bond`](#srt_accept_bond))
and the function call was blocking, but the required timeout time has passed.


#### `SRT_ECONGEST`

**NOTE**: This error is used only in an experimental version that requires
Expand Down
2 changes: 2 additions & 0 deletions srtcore/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ int CUDTUnited::startup()

m_bGCStatus = true;

HLOGC(inlog.Debug, log << "SRT Clock Type: " << SRT_SYNC_CLOCK_STR);

return 0;
}

Expand Down
41 changes: 38 additions & 3 deletions srtcore/sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@
#ifndef INC_SRT_SYNC_H
#define INC_SRT_SYNC_H

//#define ENABLE_STDCXX_SYNC
//#define ENABLE_CXX17
// Possible internal clock types
#define SRT_SYNC_CLOCK_STDCXX_STEADY 0 // C++11 std::chrono::steady_clock
#define SRT_SYNC_CLOCK_GETTIME_MONOTONIC 1 // clock_gettime with CLOCK_MONOTONIC
#define SRT_SYNC_CLOCK_WINQPC 2
#define SRT_SYNC_CLOCK_MACH_ABSTIME 3
#define SRT_SYNC_CLOCK_POSIX_GETTIMEOFDAY 4
#define SRT_SYNC_CLOCK_AMD64_RDTSC 5
#define SRT_SYNC_CLOCK_IA32_RDTSC 6
#define SRT_SYNC_CLOCK_IA64_ITC 7

#include <cstdlib>
#include <limits>
Expand All @@ -21,9 +28,37 @@
#include <thread>
#include <mutex>
#include <condition_variable>
#define SRT_SYNC_CLOCK SRT_SYNC_CLOCK_STDCXX_STEADY
#define SRT_SYNC_CLOCK_STR "STDCXX_STEADY"
#else
#include <pthread.h>

// Defile clock type to use
#ifdef IA32
#define SRT_SYNC_CLOCK SRT_SYNC_CLOCK_IA32_RDTSC
#define SRT_SYNC_CLOCK_STR "IA32_RDTSC"
#elif defined(IA64)
#define SRT_SYNC_CLOCK SRT_SYNC_CLOCK_IA64_ITC
#define SRT_SYNC_CLOCK_STR "IA64_ITC"
#elif defined(AMD64)
#define SRT_SYNC_CLOCK SRT_SYNC_CLOCK_AMD64_RDTSC
#define SRT_SYNC_CLOCK_STR "AMD64_RDTSC"
#elif defined(_WIN32)
#define SRT_SYNC_CLOCK SRT_SYNC_CLOCK_WINQPC
#define SRT_SYNC_CLOCK_STR "WINQPC"
#elif TARGET_OS_MAC
#define SRT_SYNC_CLOCK SRT_SYNC_CLOCK_MACH_ABSTIME
#define SRT_SYNC_CLOCK_STR "MACH_ABSTIME"
#elif defined(ENABLE_MONOTONIC_CLOCK)
#define SRT_SYNC_CLOCK SRT_SYNC_CLOCK_GETTIME_MONOTONIC
#define SRT_SYNC_CLOCK_STR "GETTIME_MONOTONIC"
#else
#define SRT_SYNC_CLOCK SRT_SYNC_CLOCK_POSIX_GETTIMEOFDAY
#define SRT_SYNC_CLOCK_STR "POSIX_GETTIMEOFDAY"
#endif

#endif // ENABLE_STDCXX_SYNC

#include "utilities.h"

class CUDTException; // defined in common.h
Expand Down Expand Up @@ -773,7 +808,7 @@ namespace this_thread
#if !defined(_WIN32)
usleep(count_microseconds(t)); // microseconds
#else
Sleep(count_milliseconds(t));
Sleep((DWORD) count_milliseconds(t));
#endif
}
}
Expand Down
44 changes: 23 additions & 21 deletions srtcore/sync_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,10 @@
#include "common.h"

#if defined(_WIN32)
#define TIMING_USE_QPC
#include "win/wintime.h"
#include <sys/timeb.h>
#elif TARGET_OS_MAC
#define TIMING_USE_MACH_ABS_TIME
#include <mach/mach_time.h>
#elif defined(ENABLE_MONOTONIC_CLOCK)
#define TIMING_USE_CLOCK_GETTIME
#endif

namespace srt_logging
Expand All @@ -44,60 +40,66 @@ namespace sync

void rdtsc(uint64_t& x)
{
#ifdef IA32
#if SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_IA32_RDTSC
uint32_t lval, hval;
// asm volatile ("push %eax; push %ebx; push %ecx; push %edx");
// asm volatile ("xor %eax, %eax; cpuid");
asm volatile("rdtsc" : "=a"(lval), "=d"(hval));
// asm volatile ("pop %edx; pop %ecx; pop %ebx; pop %eax");
x = hval;
x = (x << 32) | lval;
#elif defined(IA64)
#elif SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_IA64_ITC
asm("mov %0=ar.itc" : "=r"(x)::"memory");
#elif defined(AMD64)
#elif SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_AMD64_RDTSC
uint32_t lval, hval;
asm("rdtsc" : "=a"(lval), "=d"(hval));
x = hval;
x = (x << 32) | lval;
#elif defined(TIMING_USE_QPC)
#elif SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_WINQPC
// This function should not fail, because we checked the QPC
// when calling to QueryPerformanceFrequency. If it failed,
// the m_bUseMicroSecond was set to true.
QueryPerformanceCounter((LARGE_INTEGER*)&x);
#elif defined(TIMING_USE_MACH_ABS_TIME)
#elif SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_MACH_ABSTIME
x = mach_absolute_time();
#elif defined(TIMING_USE_CLOCK_GETTIME)
#elif SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_GETTIME_MONOTONIC
// get_cpu_frequency() returns 1 us accuracy in this case
timespec tm;
clock_gettime(CLOCK_MONOTONIC, &tm);
x = tm.tv_sec * uint64_t(1000000) + (tm.tv_nsec / 1000);
#else
#elif SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_POSIX_GETTIMEOFDAY
// use system call to read time clock for other archs
timeval t;
gettimeofday(&t, 0);
x = t.tv_sec * uint64_t(1000000) + t.tv_usec;
#else
#error Wrong SRT_SYNC_CLOCK
#endif
}

int64_t get_cpu_frequency()
{
int64_t frequency = 1; // 1 tick per microsecond.

#if defined(TIMING_USE_QPC)
#if SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_WINQPC
LARGE_INTEGER ccf; // in counts per second
if (QueryPerformanceFrequency(&ccf))
{
frequency = ccf.QuadPart / 1000000; // counts per microsecond
}
else
{
// Can't throw an exception, it won't be handled.
LOGC(inlog.Error, log << "IPE: QueryPerformanceFrequency failed with " << GetLastError());
}

#elif defined(TIMING_USE_CLOCK_GETTIME)
frequency = 1;

#elif defined(TIMING_USE_MACH_ABS_TIME)

#elif SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_MACH_ABSTIME
mach_timebase_info_data_t info;
mach_timebase_info(&info);
frequency = info.denom * int64_t(1000) / info.numer;

#elif defined(IA32) || defined(IA64) || defined(AMD64)
#elif SRT_SYNC_CLOCK >= SRT_SYNC_CLOCK_AMD64_RDTSC && SRT_SYNC_CLOCK <= SRT_SYNC_CLOCK_IA64_ITC
// SRT_SYNC_CLOCK_AMD64_RDTSC or SRT_SYNC_CLOCK_IA32_RDTSC or SRT_SYNC_CLOCK_IA64_ITC
uint64_t t1, t2;

rdtsc(t1);
Expand Down Expand Up @@ -287,7 +289,7 @@ Condition::~Condition() {}
void Condition::init()
{
pthread_condattr_t* attr = NULL;
#if ENABLE_MONOTONIC_CLOCK
#if SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_GETTIME_MONOTONIC
pthread_condattr_t CondAttribs;
pthread_condattr_init(&CondAttribs);
pthread_condattr_setclock(&CondAttribs, CLOCK_MONOTONIC);
Expand All @@ -311,7 +313,7 @@ void Condition::wait(UniqueLock& lock)
bool Condition::wait_for(UniqueLock& lock, const steady_clock::duration& rel_time)
{
timespec timeout;
#if ENABLE_MONOTONIC_CLOCK
#if SRT_SYNC_CLOCK == SRT_SYNC_CLOCK_GETTIME_MONOTONIC
clock_gettime(CLOCK_MONOTONIC, &timeout);
const uint64_t now_us = timeout.tv_sec * uint64_t(1000000) + (timeout.tv_nsec / 1000);
#else
Expand Down Expand Up @@ -422,7 +424,7 @@ void srt::sync::CThread::join()
#ifdef HEAVY_LOGGING
else
{
LOGC(inlog.Debug, log << "pthread_join SUCCEEDED");
HLOGC(inlog.Debug, log << "pthread_join SUCCEEDED");
}
#endif
// After joining, joinable should be false
Expand Down