Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
a9160283
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
a9160283
编写于
1月 28, 2021
作者:
M
Minglei Jin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rmonotonic: a monotonic clock source
上级
b4aff484
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
229 addition
and
0 deletion
+229
-0
deps/CMakeLists.txt
deps/CMakeLists.txt
+1
-0
deps/rmonotonic/CMakeLists.txt
deps/rmonotonic/CMakeLists.txt
+6
-0
deps/rmonotonic/inc/monotonic.h
deps/rmonotonic/inc/monotonic.h
+52
-0
deps/rmonotonic/src/monotonic.c
deps/rmonotonic/src/monotonic.c
+170
-0
未找到文件。
deps/CMakeLists.txt
浏览文件 @
a9160283
...
...
@@ -9,6 +9,7 @@ ADD_SUBDIRECTORY(lz4)
ADD_SUBDIRECTORY
(
cJson
)
ADD_SUBDIRECTORY
(
wepoll
)
ADD_SUBDIRECTORY
(
MsvcLibX
)
ADD_SUBDIRECTORY
(
rmonotonic
)
IF
(
TD_LINUX AND TD_MQTT
)
ADD_SUBDIRECTORY
(
MQTT-C
)
...
...
deps/rmonotonic/CMakeLists.txt
0 → 100644
浏览文件 @
a9160283
AUX_SOURCE_DIRECTORY
(
${
CMAKE_CURRENT_SOURCE_DIR
}
/src SOURCE_LIST
)
add_definitions
(
-DUSE_PROCESSOR_CLOCK
)
ADD_LIBRARY
(
rmonotonic
${
SOURCE_LIST
}
)
TARGET_INCLUDE_DIRECTORIES
(
rmonotonic PUBLIC
${
CMAKE_CURRENT_SOURCE_DIR
}
/inc
)
deps/rmonotonic/inc/monotonic.h
0 → 100644
浏览文件 @
a9160283
#ifndef __MONOTONIC_H
#define __MONOTONIC_H
/* The monotonic clock is an always increasing clock source. It is unrelated to
* the actual time of day and should only be used for relative timings. The
* monotonic clock is also not guaranteed to be chronologically precise; there
* may be slight skew/shift from a precise clock.
*
* Depending on system architecture, the monotonic time may be able to be
* retrieved much faster than a normal clock source by using an instruction
* counter on the CPU. On x86 architectures (for example), the RDTSC
* instruction is a very fast clock source for this purpose.
*/
//#include "fmacros.h"
#include <stdint.h>
//#include <unistd.h>
/* A counter in micro-seconds. The 'monotime' type is provided for variables
* holding a monotonic time. This will help distinguish & document that the
* variable is associated with the monotonic clock and should not be confused
* with other types of time.*/
typedef
uint64_t
monotime
;
/* Retrieve counter of micro-seconds relative to an arbitrary point in time. */
extern
monotime
(
*
getMonotonicUs
)(
void
);
/* Call once at startup to initialize the monotonic clock. Though this only
* needs to be called once, it may be called additional times without impact.
* Returns a printable string indicating the type of clock initialized.
* (The returned string is static and doesn't need to be freed.) */
const
char
*
monotonicInit
();
/* Functions to measure elapsed time. Example:
* monotime myTimer;
* elapsedStart(&myTimer);
* while (elapsedMs(myTimer) < 10) {} // loops for 10ms
*/
static
inline
void
elapsedStart
(
monotime
*
start_time
)
{
*
start_time
=
getMonotonicUs
();
}
static
inline
uint64_t
elapsedUs
(
monotime
start_time
)
{
return
getMonotonicUs
()
-
start_time
;
}
static
inline
uint64_t
elapsedMs
(
monotime
start_time
)
{
return
elapsedUs
(
start_time
)
/
1000
;
}
#endif
deps/rmonotonic/src/monotonic.c
0 → 100644
浏览文件 @
a9160283
#include "monotonic.h"
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#undef NDEBUG
#include <assert.h>
/* The function pointer for clock retrieval. */
monotime
(
*
getMonotonicUs
)(
void
)
=
NULL
;
static
char
monotonic_info_string
[
32
];
/* Using the processor clock (aka TSC on x86) can provide improved performance
* throughout Redis wherever the monotonic clock is used. The processor clock
* is significantly faster than calling 'clock_getting' (POSIX). While this is
* generally safe on modern systems, this link provides additional information
* about use of the x86 TSC: http://oliveryang.net/2015/09/pitfalls-of-TSC-usage
*
* To use the processor clock, either uncomment this line, or build with
* CFLAGS="-DUSE_PROCESSOR_CLOCK"
#define USE_PROCESSOR_CLOCK
*/
#if defined(USE_PROCESSOR_CLOCK) && defined(__x86_64__) && defined(__linux__)
#include <regex.h>
#include <x86intrin.h>
static
long
mono_ticksPerMicrosecond
=
0
;
static
monotime
getMonotonicUs_x86
()
{
return
__rdtsc
()
/
mono_ticksPerMicrosecond
;
}
static
void
monotonicInit_x86linux
()
{
const
int
bufflen
=
256
;
char
buf
[
bufflen
];
regex_t
cpuGhzRegex
,
constTscRegex
;
const
size_t
nmatch
=
2
;
regmatch_t
pmatch
[
nmatch
];
int
constantTsc
=
0
;
int
rc
;
/* Determine the number of TSC ticks in a micro-second. This is
* a constant value matching the standard speed of the processor.
* On modern processors, this speed remains constant even though
* the actual clock speed varies dynamically for each core. */
rc
=
regcomp
(
&
cpuGhzRegex
,
"^model name
\\
s+:.*@ ([0-9.]+)GHz"
,
REG_EXTENDED
);
assert
(
rc
==
0
);
/* Also check that the constant_tsc flag is present. (It should be
* unless this is a really old CPU. */
rc
=
regcomp
(
&
constTscRegex
,
"^flags
\\
s+:.* constant_tsc"
,
REG_EXTENDED
);
assert
(
rc
==
0
);
FILE
*
cpuinfo
=
fopen
(
"/proc/cpuinfo"
,
"r"
);
if
(
cpuinfo
!=
NULL
)
{
while
(
fgets
(
buf
,
bufflen
,
cpuinfo
)
!=
NULL
)
{
if
(
regexec
(
&
cpuGhzRegex
,
buf
,
nmatch
,
pmatch
,
0
)
==
0
)
{
buf
[
pmatch
[
1
].
rm_eo
]
=
'\0'
;
double
ghz
=
atof
(
&
buf
[
pmatch
[
1
].
rm_so
]);
mono_ticksPerMicrosecond
=
(
long
)(
ghz
*
1000
);
break
;
}
}
while
(
fgets
(
buf
,
bufflen
,
cpuinfo
)
!=
NULL
)
{
if
(
regexec
(
&
constTscRegex
,
buf
,
nmatch
,
pmatch
,
0
)
==
0
)
{
constantTsc
=
1
;
break
;
}
}
fclose
(
cpuinfo
);
}
regfree
(
&
cpuGhzRegex
);
regfree
(
&
constTscRegex
);
if
(
mono_ticksPerMicrosecond
==
0
)
{
fprintf
(
stderr
,
"monotonic: x86 linux, unable to determine clock rate"
);
return
;
}
if
(
!
constantTsc
)
{
fprintf
(
stderr
,
"monotonic: x86 linux, 'constant_tsc' flag not present"
);
return
;
}
snprintf
(
monotonic_info_string
,
sizeof
(
monotonic_info_string
),
"X86 TSC @ %ld ticks/us"
,
mono_ticksPerMicrosecond
);
getMonotonicUs
=
getMonotonicUs_x86
;
}
#endif
#if defined(USE_PROCESSOR_CLOCK) && defined(__aarch64__)
static
long
mono_ticksPerMicrosecond
=
0
;
/* Read the clock value. */
static
inline
uint64_t
__cntvct
()
{
uint64_t
virtual_timer_value
;
__asm__
volatile
(
"mrs %0, cntvct_el0"
:
"=r"
(
virtual_timer_value
));
return
virtual_timer_value
;
}
/* Read the Count-timer Frequency. */
static
inline
uint32_t
cntfrq_hz
()
{
uint64_t
virtual_freq_value
;
__asm__
volatile
(
"mrs %0, cntfrq_el0"
:
"=r"
(
virtual_freq_value
));
return
(
uint32_t
)
virtual_freq_value
;
/* top 32 bits are reserved */
}
static
monotime
getMonotonicUs_aarch64
()
{
return
__cntvct
()
/
mono_ticksPerMicrosecond
;
}
static
void
monotonicInit_aarch64
()
{
mono_ticksPerMicrosecond
=
(
long
)
cntfrq_hz
()
/
1000L
/
1000L
;
if
(
mono_ticksPerMicrosecond
==
0
)
{
fprintf
(
stderr
,
"monotonic: aarch64, unable to determine clock rate"
);
return
;
}
snprintf
(
monotonic_info_string
,
sizeof
(
monotonic_info_string
),
"ARM CNTVCT @ %ld ticks/us"
,
mono_ticksPerMicrosecond
);
getMonotonicUs
=
getMonotonicUs_aarch64
;
}
#endif
static
monotime
getMonotonicUs_posix
()
{
/* clock_gettime() is specified in POSIX.1b (1993). Even so, some systems
* did not support this until much later. CLOCK_MONOTONIC is technically
* optional and may not be supported - but it appears to be universal.
* If this is not supported, provide a system-specific alternate version. */
struct
timespec
ts
;
clock_gettime
(
CLOCK_MONOTONIC
,
&
ts
);
return
((
uint64_t
)
ts
.
tv_sec
)
*
1000000
+
ts
.
tv_nsec
/
1000
;
}
static
void
monotonicInit_posix
()
{
/* Ensure that CLOCK_MONOTONIC is supported. This should be supported
* on any reasonably current OS. If the assertion below fails, provide
* an appropriate alternate implementation. */
struct
timespec
ts
;
int
rc
=
clock_gettime
(
CLOCK_MONOTONIC
,
&
ts
);
assert
(
rc
==
0
);
snprintf
(
monotonic_info_string
,
sizeof
(
monotonic_info_string
),
"POSIX clock_gettime"
);
getMonotonicUs
=
getMonotonicUs_posix
;
}
const
char
*
monotonicInit
()
{
#if defined(USE_PROCESSOR_CLOCK) && defined(__x86_64__) && defined(__linux__)
if
(
getMonotonicUs
==
NULL
)
monotonicInit_x86linux
();
#endif
#if defined(USE_PROCESSOR_CLOCK) && defined(__aarch64__)
if
(
getMonotonicUs
==
NULL
)
monotonicInit_aarch64
();
#endif
if
(
getMonotonicUs
==
NULL
)
monotonicInit_posix
();
return
monotonic_info_string
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录