Skip to content

Commit

Permalink
[core] Added SRT_SYNC_CLOCK_TYPE preprocessor definition (#1885)
Browse files Browse the repository at this point in the history
  • Loading branch information
maxsharabayko committed Mar 24, 2021
1 parent 93de9c8 commit 1d4338a
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 29 deletions.
14 changes: 9 additions & 5 deletions docs/API-functions.md
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
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
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
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

0 comments on commit 1d4338a

Please sign in to comment.