Skip to content

Commit eef63cf

Browse files
committed
添加 vdso readtime 更新逻辑
1 parent d4fbebe commit eef63cf

4 files changed

Lines changed: 92 additions & 3 deletions

File tree

components/libc/compilers/common/ctime.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252

5353
#define _WARNING_NO_RTC "Cannot find a RTC device!"
5454

55+
#if defined(RT_USING_SMART) && defined(RT_USING_VDSO)
56+
#include <vdso_kernel.h>
57+
#endif
58+
5559
/* days per month -- nonleap! */
5660
static const short __spm[13] =
5761
{
@@ -519,12 +523,26 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz)
519523
{
520524
if (_control_rtc(RT_DEVICE_CTRL_RTC_SET_TIMEVAL, (void *)tv) == RT_EOK)
521525
{
526+
#if defined(RT_USING_SMART) && defined(RT_USING_VDSO)
527+
struct timespec ts = {
528+
.tv_sec = tv->tv_sec,
529+
.tv_nsec = tv->tv_usec * 1000L,
530+
};
531+
rt_vdso_set_realtime(&ts);
532+
#endif
522533
return 0;
523534
}
524535
else
525536
{
526537
if (_control_rtc(RT_DEVICE_CTRL_RTC_SET_TIME, (void *)&tv->tv_sec) == RT_EOK)
527538
{
539+
#if defined(RT_USING_SMART) && defined(RT_USING_VDSO)
540+
struct timespec ts = {
541+
.tv_sec = tv->tv_sec,
542+
.tv_nsec = 0,
543+
};
544+
rt_vdso_set_realtime(&ts);
545+
#endif
528546
return 0;
529547
}
530548
}
@@ -736,7 +754,16 @@ int clock_settime(clockid_t clockid, const struct timespec *tp)
736754
{
737755
#ifdef RT_USING_RTC
738756
case CLOCK_REALTIME:
739-
return _control_rtc(RT_DEVICE_CTRL_RTC_SET_TIMESPEC, (void *)tp);
757+
{
758+
int ret = _control_rtc(RT_DEVICE_CTRL_RTC_SET_TIMESPEC, (void *)tp);
759+
if (ret == RT_EOK)
760+
{
761+
#if defined(RT_USING_SMART) && defined(RT_USING_VDSO)
762+
rt_vdso_set_realtime(tp);
763+
#endif
764+
}
765+
return ret;
766+
}
740767
#endif /* RT_USING_RTC */
741768

742769
case CLOCK_REALTIME_COARSE:

components/lwp/arch/common/vdso_kernel.c

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,18 @@ static void rt_vdso_counter_to_timespec(rt_uint64_t counter_value,
101101
ts->tv_nsec = monotonic_ns % RT_VDSO_NSEC_PER_SEC;
102102
}
103103

104+
static struct timespec rt_vdso_timespec_subtract(const struct timespec *lhs,
105+
const struct timespec *rhs)
106+
{
107+
struct timespec ret;
108+
109+
ret.tv_sec = lhs->tv_sec - rhs->tv_sec;
110+
ret.tv_nsec = lhs->tv_nsec - rhs->tv_nsec;
111+
rt_vdso_normalize_timespec(&ret);
112+
113+
return ret;
114+
}
115+
104116
static struct timespec rt_vdso_add_timespec(const struct timespec *lhs,
105117
const struct timespec *rhs)
106118
{
@@ -129,15 +141,58 @@ static int rt_vdso_read_monotonic_snapshot(struct timespec *monotonic_time,
129141
return RT_EOK;
130142
}
131143

144+
static void rt_vdso_update_data_page_flags(void)
145+
{
146+
rt_uint32_t flags = 0;
147+
148+
if (rt_vdso_realtime_offset_ready)
149+
{
150+
flags |= RT_VDSO_FLAG_REALTIME_VALID;
151+
}
152+
153+
rt_vdso_kernel_data_page->flags = flags;
154+
}
155+
132156
static void rt_vdso_store_clock_snapshot(const struct timespec *monotonic_time,
133157
rt_uint64_t counter_value,
134158
rt_uint64_t counter_freq)
135159
{
136160
rt_vdso_kernel_data_page->counter_last = counter_value;
137161
rt_vdso_kernel_data_page->counter_freq = counter_freq;
162+
rt_vdso_update_data_page_flags();
138163
rt_vdso_kernel_data_page->base_time[RT_VDSO_CLOCK_MONOTONIC_INDEX] = *monotonic_time;
139-
rt_vdso_kernel_data_page->base_time[RT_VDSO_CLOCK_REALTIME_INDEX] =
140-
rt_vdso_add_timespec(monotonic_time, &rt_vdso_realtime_offset);
164+
if (rt_vdso_realtime_offset_ready)
165+
{
166+
rt_vdso_kernel_data_page->base_time[RT_VDSO_CLOCK_REALTIME_INDEX] =
167+
rt_vdso_add_timespec(monotonic_time, &rt_vdso_realtime_offset);
168+
}
169+
else
170+
{
171+
rt_vdso_kernel_data_page->base_time[RT_VDSO_CLOCK_REALTIME_INDEX] = *monotonic_time;
172+
}
173+
}
174+
175+
void rt_vdso_set_realtime(const struct timespec *realtime)
176+
{
177+
struct timespec monotonic;
178+
rt_uint64_t counter;
179+
rt_uint64_t freq;
180+
181+
if (rt_vdso_runtime_status != RT_EOK || realtime == RT_NULL)
182+
{
183+
return;
184+
}
185+
186+
if (rt_vdso_read_monotonic_snapshot(&monotonic, &counter, &freq) != RT_EOK)
187+
{
188+
return;
189+
}
190+
191+
rt_vdso_data_page_write_begin(rt_vdso_kernel_data_page);
192+
rt_vdso_realtime_offset = rt_vdso_timespec_subtract(realtime, &monotonic);
193+
rt_vdso_realtime_offset_ready = RT_TRUE;
194+
rt_vdso_store_clock_snapshot(&monotonic, counter, freq);
195+
rt_vdso_data_page_write_end(rt_vdso_kernel_data_page);
141196
}
142197

143198
static void *rt_vdso_map_physical_pages(struct rt_lwp *lwp, void *user_va,
@@ -266,6 +321,7 @@ static int rt_vdso_validate_image(void)
266321

267322
rt_memset(rt_vdso_data_page_store.raw, 0, sizeof(rt_vdso_data_page_store.raw));
268323
rt_vdso_realtime_offset_ready = RT_FALSE;
324+
rt_memset(&rt_vdso_realtime_offset, 0, sizeof(rt_vdso_realtime_offset));
269325

270326
if (rt_memcmp(rt_vdso_binaries[RT_VDSO_BINARY_COMMON].image_start,
271327
RT_VDSO_IMAGE_ELF_MAGIC, RT_VDSO_IMAGE_ELF_MAGIC_LEN))

components/lwp/vdso/user/common/vdso_clock_gettime.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ int rt_vdso_clock_gettime_impl(clockid_t clock, struct timespec *ts)
5555
do
5656
{
5757
seq = rt_vdso_data_read_begin(data_page);
58+
if (index == RT_VDSO_CLOCK_REALTIME_INDEX &&
59+
!(data_page->flags & RT_VDSO_FLAG_REALTIME_VALID))
60+
{
61+
return -ENOSYS;
62+
}
5863
base_time = data_page->base_time[index];
5964
last = data_page->counter_last;
6065
freq = data_page->counter_freq;

components/lwp/vdso/vdso_data_page.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern "C" {
2222

2323
#define RT_VDSO_CLOCK_ID_MAX 16
2424
#define RT_VDSO_NSEC_PER_SEC 1000000000ULL
25+
#define RT_VDSO_FLAG_REALTIME_VALID (1U << 0)
2526

2627
enum rt_vdso_clock_data_index
2728
{

0 commit comments

Comments
 (0)