Alexandre Julliard : server: Update shared user data timestamps on every request.
Alexandre Julliard
julliard at winehq.org
Mon May 25 15:44:23 CDT 2020
Module: wine
Branch: master
Commit: 1ae10889647c1c84c36660749508a42e99e64a5e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=1ae10889647c1c84c36660749508a42e99e64a5e
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon May 25 20:25:50 2020 +0200
server: Update shared user data timestamps on every request.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
server/fd.c | 50 +++++++++++++++++++++++++++++++++++++++++++----
server/file.h | 1 +
server/mapping.c | 59 ++++----------------------------------------------------
3 files changed, 51 insertions(+), 59 deletions(-)
diff --git a/server/fd.c b/server/fd.c
index 39fb419f25..06d1d81bdb 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -104,6 +104,7 @@
#include "winternl.h"
#include "winioctl.h"
+#include "ddk/wdm.h"
#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL_CREATE)
# include <sys/epoll.h>
@@ -374,6 +375,46 @@ static struct list rel_timeout_list = LIST_INIT(rel_timeout_list); /* sorted rel
timeout_t current_time;
timeout_t monotonic_time;
+struct _KUSER_SHARED_DATA *user_shared_data = NULL;
+static const int user_shared_data_timeout = 16;
+
+static void set_user_shared_data_time(void)
+{
+ timeout_t tick_count = monotonic_time / 10000;
+
+ /* on X86 there should be total store order guarantees, so volatile is enough
+ * to ensure the stores aren't reordered by the compiler, and then they will
+ * always be seen in-order from other CPUs. On other archs, we need atomic
+ * intrinsics to guarantee that. */
+#if defined(__i386__) || defined(__x86_64__)
+ user_shared_data->SystemTime.High2Time = current_time >> 32;
+ user_shared_data->SystemTime.LowPart = current_time;
+ user_shared_data->SystemTime.High1Time = current_time >> 32;
+
+ user_shared_data->InterruptTime.High2Time = monotonic_time >> 32;
+ user_shared_data->InterruptTime.LowPart = monotonic_time;
+ user_shared_data->InterruptTime.High1Time = monotonic_time >> 32;
+
+ user_shared_data->TickCount.High2Time = tick_count >> 32;
+ user_shared_data->TickCount.LowPart = tick_count;
+ user_shared_data->TickCount.High1Time = tick_count >> 32;
+ *(volatile ULONG *)&user_shared_data->TickCountLowDeprecated = tick_count;
+#else
+ __atomic_store_n(&user_shared_data->SystemTime.High2Time, current_time >> 32, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&user_shared_data->SystemTime.LowPart, current_time, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&user_shared_data->SystemTime.High1Time, current_time >> 32, __ATOMIC_SEQ_CST);
+
+ __atomic_store_n(&user_shared_data->InterruptTime.High2Time, monotonic_time >> 32, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&user_shared_data->InterruptTime.LowPart, monotonic_time, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&user_shared_data->InterruptTime.High1Time, monotonic_time >> 32, __ATOMIC_SEQ_CST);
+
+ __atomic_store_n(&user_shared_data->TickCount.High2Time, tick_count >> 32, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&user_shared_data->TickCount.LowPart, tick_count, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&user_shared_data->TickCount.High1Time, tick_count >> 32, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&user_shared_data->TickCountLowDeprecated, tick_count, __ATOMIC_SEQ_CST);
+#endif
+}
+
void set_current_time(void)
{
static const timeout_t ticks_1601_to_1970 = (timeout_t)86400 * (369 * 365 + 89) * TICKS_PER_SEC;
@@ -381,6 +422,7 @@ void set_current_time(void)
gettimeofday( &now, NULL );
current_time = (timeout_t)now.tv_sec * TICKS_PER_SEC + now.tv_usec * 10 + ticks_1601_to_1970;
monotonic_time = monotonic_counter();
+ if (user_shared_data) set_user_shared_data_time();
}
/* add a timeout user */
@@ -865,10 +907,11 @@ static void remove_poll_user( struct fd *fd, int user )
/* process pending timeouts and return the time until the next timeout, in milliseconds */
static int get_next_timeout(void)
{
+ int ret = user_shared_data ? user_shared_data_timeout : -1;
+
if (!list_empty( &abs_timeout_list ) || !list_empty( &rel_timeout_list ))
{
struct list expired_list, *ptr;
- int ret = -1;
/* first remove all expired timers from the list */
@@ -911,7 +954,7 @@ static int get_next_timeout(void)
struct timeout_user *timeout = LIST_ENTRY( ptr, struct timeout_user, entry );
int diff = (timeout->when - current_time + 9999) / 10000;
if (diff < 0) diff = 0;
- ret = diff;
+ if (ret == -1 || diff < ret) ret = diff;
}
if ((ptr = list_head( &rel_timeout_list )) != NULL)
@@ -921,9 +964,8 @@ static int get_next_timeout(void)
if (diff < 0) diff = 0;
if (ret == -1 || diff < ret) ret = diff;
}
- return ret;
}
- return -1; /* no pending timeouts */
+ return ret;
}
/* server main poll() loop */
diff --git a/server/file.h b/server/file.h
index 4c454de4d4..aa5f6216c2 100644
--- a/server/file.h
+++ b/server/file.h
@@ -130,6 +130,7 @@ static inline struct fd *get_obj_fd( struct object *obj ) { return obj->ops->get
struct timeout_user;
extern timeout_t current_time;
extern timeout_t monotonic_time;
+extern struct _KUSER_SHARED_DATA *user_shared_data;
#define TICKS_PER_SEC 10000000
diff --git a/server/mapping.c b/server/mapping.c
index ffd20450df..0fcada7f8f 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -945,66 +945,15 @@ int get_page_size(void)
return page_mask + 1;
}
-static KSHARED_USER_DATA *kusd = MAP_FAILED;
-static const timeout_t kusd_timeout = 16 * -TICKS_PER_SEC / 1000;
-
-static void kusd_set_current_time( void *private )
-{
- ULONG system_time_high = current_time >> 32;
- ULONG system_time_low = current_time & 0xffffffff;
- ULONG interrupt_time_high = monotonic_time >> 32;
- ULONG interrupt_time_low = monotonic_time & 0xffffffff;
- ULONG tick_count_high = (monotonic_time * 1000 / TICKS_PER_SEC) >> 32;
- ULONG tick_count_low = (monotonic_time * 1000 / TICKS_PER_SEC) & 0xffffffff;
- KSHARED_USER_DATA *ptr = kusd;
-
- add_timeout_user( kusd_timeout, kusd_set_current_time, NULL );
-
- /* on X86 there should be total store order guarantees, so volatile is enough
- * to ensure the stores aren't reordered by the compiler, and then they will
- * always be seen in-order from other CPUs. On other archs, we need atomic
- * intrinsics to guarantee that. */
-#if defined(__i386__) || defined(__x86_64__)
- ptr->SystemTime.High2Time = system_time_high;
- ptr->SystemTime.LowPart = system_time_low;
- ptr->SystemTime.High1Time = system_time_high;
-
- ptr->InterruptTime.High2Time = interrupt_time_high;
- ptr->InterruptTime.LowPart = interrupt_time_low;
- ptr->InterruptTime.High1Time = interrupt_time_high;
-
- ptr->TickCount.High2Time = tick_count_high;
- ptr->TickCount.LowPart = tick_count_low;
- ptr->TickCount.High1Time = tick_count_high;
- *(volatile ULONG *)&ptr->TickCountLowDeprecated = tick_count_low;
-#else
- __atomic_store_n(&ptr->SystemTime.High2Time, system_time_high, __ATOMIC_SEQ_CST);
- __atomic_store_n(&ptr->SystemTime.LowPart, system_time_low, __ATOMIC_SEQ_CST);
- __atomic_store_n(&ptr->SystemTime.High1Time, system_time_high, __ATOMIC_SEQ_CST);
-
- __atomic_store_n(&ptr->InterruptTime.High2Time, interrupt_time_high, __ATOMIC_SEQ_CST);
- __atomic_store_n(&ptr->InterruptTime.LowPart, interrupt_time_low, __ATOMIC_SEQ_CST);
- __atomic_store_n(&ptr->InterruptTime.High1Time, interrupt_time_high, __ATOMIC_SEQ_CST);
-
- __atomic_store_n(&ptr->TickCount.High2Time, tick_count_high, __ATOMIC_SEQ_CST);
- __atomic_store_n(&ptr->TickCount.LowPart, tick_count_low, __ATOMIC_SEQ_CST);
- __atomic_store_n(&ptr->TickCount.High1Time, tick_count_high, __ATOMIC_SEQ_CST);
- __atomic_store_n(&ptr->TickCountLowDeprecated, tick_count_low, __ATOMIC_SEQ_CST);
-#endif
-}
-
void init_kusd_mapping( struct mapping *mapping )
{
- if (kusd != MAP_FAILED) return;
+ void *ptr;
+ if (user_shared_data) return;
grab_object( mapping );
make_object_static( &mapping->obj );
-
- if ((kusd = mmap( NULL, mapping->size, PROT_WRITE, MAP_SHARED,
- get_unix_fd( mapping->fd ), 0 )) == MAP_FAILED)
- set_error( STATUS_NO_MEMORY );
- else
- kusd_set_current_time( NULL );
+ ptr = mmap( NULL, mapping->size, PROT_WRITE, MAP_SHARED, get_unix_fd( mapping->fd ), 0 );
+ if (ptr != MAP_FAILED) user_shared_data = ptr;
}
/* create a file mapping */
More information about the wine-cvs
mailing list