Skip to content

Commit 1300b19

Browse files
authoredFeb 4, 2025··
Merge pull request #92 from Lind-Project/clock_gettime
implement clock_gettime
2 parents f000736 + 3b8e908 commit 1300b19

File tree

5 files changed

+85
-73
lines changed

5 files changed

+85
-73
lines changed
 

‎src/RawPOSIX/src/safeposix/dispatcher.rs

+9
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ const WAIT_SYSCALL: i32 = 172;
118118
const WAITPID_SYSCALL: i32 = 173;
119119

120120
const NANOSLEEP_TIME64_SYSCALL : i32 = 181;
121+
const CLOCK_GETTIME_SYSCALL : i32 = 191;
121122

122123
use std::ffi::CString;
123124
use std::ffi::CStr;
@@ -1034,6 +1035,14 @@ pub fn lind_syscall_api(
10341035
.nanosleep_time64_syscall(clockid, flags, req, rem)
10351036
}
10361037

1038+
CLOCK_GETTIME_SYSCALL => {
1039+
let clockid = arg1 as u32;
1040+
let tp = (start_address + arg2) as usize;
1041+
1042+
interface::cagetable_getref(cageid)
1043+
.clock_gettime_syscall(clockid, tp)
1044+
}
1045+
10371046
WAIT_SYSCALL => {
10381047
let mut status = interface::get_i32_ref(start_address + arg1).unwrap();
10391048

‎src/RawPOSIX/src/safeposix/syscalls/fs_calls.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,15 @@ impl Cage {
19011901
}
19021902
ret
19031903
}
1904+
1905+
pub fn clock_gettime_syscall(&self, clockid: u32, tp: usize) -> i32 {
1906+
let ret = unsafe { syscall(SYS_clock_gettime, clockid, tp) as i32 };
1907+
if ret < 0 {
1908+
let errno = get_errno();
1909+
return handle_errno(errno, "clock_gettime");
1910+
}
1911+
ret
1912+
}
19041913
}
19051914

19061915
/// Lind-WASM is running as same Linux-Process from host kernel perspective, so standard fds shouldn't

‎src/glibc/sysdeps/unix/sysv/linux/clock_gettime.c

+9-73
Original file line numberDiff line numberDiff line change
@@ -23,66 +23,17 @@
2323
#include "kernel-posix-cpu-timers.h"
2424
#include <sysdep-vdso.h>
2525
#include <shlib-compat.h>
26+
#include <syscall-template.h>
2627

2728
/* Get current value of CLOCK and store it in TP. */
29+
30+
// Now after clang compile it will call gettime64 first(but in real case we have only 32 bit)
31+
// In this case, we need “#if __TIMESIZE != 64” and this is always true. And always call __clock_gettime at last.
32+
2833
int
2934
__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
3035
{
31-
int r;
32-
33-
#ifndef __NR_clock_gettime64
34-
# define __NR_clock_gettime64 __NR_clock_gettime
35-
#endif
36-
37-
#ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
38-
int (*vdso_time64) (clockid_t clock_id, struct __timespec64 *tp)
39-
= GLRO(dl_vdso_clock_gettime64);
40-
if (vdso_time64 != NULL)
41-
{
42-
r = INTERNAL_VSYSCALL_CALL (vdso_time64, 2, clock_id, tp);
43-
if (r == 0)
44-
return 0;
45-
return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
46-
}
47-
#endif
48-
49-
#ifdef HAVE_CLOCK_GETTIME_VSYSCALL
50-
int (*vdso_time) (clockid_t clock_id, struct timespec *tp)
51-
= GLRO(dl_vdso_clock_gettime);
52-
if (vdso_time != NULL)
53-
{
54-
struct timespec tp32;
55-
r = INTERNAL_VSYSCALL_CALL (vdso_time, 2, clock_id, &tp32);
56-
if (r == 0 && tp32.tv_sec >= 0)
57-
{
58-
*tp = valid_timespec_to_timespec64 (tp32);
59-
return 0;
60-
}
61-
else if (r != 0)
62-
return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
63-
64-
/* Fallback to syscall if the 32-bit time_t vDSO returns overflows. */
65-
}
66-
#endif
67-
68-
r = INTERNAL_SYSCALL_CALL (clock_gettime64, clock_id, tp);
69-
if (r == 0)
70-
return 0;
71-
if (r != -ENOSYS)
72-
return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
73-
74-
#ifndef __ASSUME_TIME64_SYSCALLS
75-
/* Fallback code that uses 32-bit support. */
76-
struct timespec tp32;
77-
r = INTERNAL_SYSCALL_CALL (clock_gettime, clock_id, &tp32);
78-
if (r == 0)
79-
{
80-
*tp = valid_timespec_to_timespec64 (tp32);
81-
return 0;
82-
}
83-
#endif
84-
85-
return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
36+
return MAKE_SYSCALL(191, "syscall|clock_gettime", (uint64_t) clock_id, (uint64_t) tp, NOTUSED, NOTUSED, NOTUSED, NOTUSED);
8637
}
8738

8839
#if __TIMESIZE != 64
@@ -91,26 +42,11 @@ libc_hidden_def (__clock_gettime64)
9142
int
9243
__clock_gettime (clockid_t clock_id, struct timespec *tp)
9344
{
94-
int ret;
95-
struct __timespec64 tp64;
96-
97-
ret = __clock_gettime64 (clock_id, &tp64);
98-
99-
if (ret == 0)
100-
{
101-
if (! in_time_t_range (tp64.tv_sec))
102-
{
103-
__set_errno (EOVERFLOW);
104-
return -1;
105-
}
106-
107-
*tp = valid_timespec64_to_timespec (tp64);
108-
}
109-
110-
return ret;
45+
return MAKE_SYSCALL(191, "syscall|clock_gettime", (uint64_t) clock_id, (uint64_t) tp, NOTUSED, NOTUSED, NOTUSED, NOTUSED);
11146
}
47+
11248
#endif
113-
libc_hidden_def (__clock_gettime)
49+
libc_hidden_def (__clock_gettime);
11450

11551
versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17);
11652
/* clock_gettime moved to libc in version 2.17;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <stdio.h>
2+
#include <time.h>
3+
4+
/*
5+
This test indirectly calls the clock_gettime syscall through the clock() function.
6+
The clock() function in glibc internally uses clock_gettime to measure CPU time
7+
consumed by the process.
8+
9+
The program measures the CPU time taken to run 1,000,000 iterations of a simple loop.
10+
It records the start time using clock(), performs the computation, then records the
11+
end time and calculates the elapsed CPU time.
12+
*/
13+
14+
int main() {
15+
// Get the start time using clock()
16+
clock_t begin = clock();
17+
18+
printf("Running 1,000,000 iterations...\n");
19+
20+
volatile long long sum = 0;
21+
for (long long i = 0; i < 1000000; i++) {
22+
sum += i;
23+
}
24+
25+
// Get the end time using clock()
26+
clock_t end = clock();
27+
28+
// Calculate elapsed time in seconds
29+
double elapsed_time = (double)(end - begin) / CLOCKS_PER_SEC;
30+
31+
// Display results
32+
printf("\nStart time: %lld clock ticks\n", begin);
33+
printf("End time: %lld clock ticks\n", end);
34+
printf("Elapsed CPU time: %.9f seconds\n", elapsed_time);
35+
36+
return 0;
37+
}
38+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <time.h>
2+
#include <stdio.h>
3+
4+
int main() {
5+
struct timespec tp;
6+
7+
// get CLOCK_REALTIME's time
8+
if (clock_gettime(CLOCK_REALTIME, &tp) == -1) {
9+
perror("clock_gettime failed");
10+
return 1;
11+
}
12+
13+
//print the result
14+
printf("Current time: %lld seconds and %ld nanoseconds\n", tp.tv_sec, tp.tv_nsec);
15+
16+
return 0;
17+
}
18+
19+
20+

0 commit comments

Comments
 (0)
Please sign in to comment.