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