mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
ntdll-FD_Cache: Update patchset with recent changes.
This commit is contained in:
parent
a02130583a
commit
12842d4a5d
@ -0,0 +1,50 @@
|
||||
From 27e4c293824d5e133f2b30e7cda68d96142b8fb5 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 2 May 2015 07:04:17 +0200
|
||||
Subject: libs: Implement interlocked_cmpxchg64 on PowerPC using pthread mutex.
|
||||
|
||||
---
|
||||
libs/port/interlocked.c | 19 ++++++++++++++++---
|
||||
1 file changed, 16 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libs/port/interlocked.c b/libs/port/interlocked.c
|
||||
index f5e405c..80e43cf 100644
|
||||
--- a/libs/port/interlocked.c
|
||||
+++ b/libs/port/interlocked.c
|
||||
@@ -181,6 +181,11 @@ __ASM_GLOBAL_FUNC(interlocked_cmpxchg128,
|
||||
"ret")
|
||||
|
||||
#elif defined(__powerpc__)
|
||||
+
|
||||
+#include <pthread.h>
|
||||
+
|
||||
+static pthread_mutex_t interlocked_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
+
|
||||
void* interlocked_cmpxchg_ptr( void **dest, void* xchg, void* compare)
|
||||
{
|
||||
void *ret = 0;
|
||||
@@ -199,10 +204,18 @@ void* interlocked_cmpxchg_ptr( void **dest, void* xchg, void* compare)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-__int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare)
|
||||
+/* FIXME: replace with assembler implementation */
|
||||
+__int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare )
|
||||
{
|
||||
- /* FIXME: add code */
|
||||
- assert(0);
|
||||
+ pthread_mutex_lock( &interlocked_mutex );
|
||||
+
|
||||
+ if (*dest == compare)
|
||||
+ *dest = xchg;
|
||||
+ else
|
||||
+ compare = *dest;
|
||||
+
|
||||
+ pthread_mutex_unlock( &interlocked_mutex );
|
||||
+ return compare;
|
||||
}
|
||||
|
||||
int interlocked_cmpxchg( int *dest, int xchg, int compare)
|
||||
--
|
||||
2.3.5
|
||||
|
@ -1,163 +0,0 @@
|
||||
From d27bb6018ce273ab2aa29d436a64dc2507992f84 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Wed, 26 Nov 2014 09:03:17 +0100
|
||||
Subject: ntdll: Use lockfree implementation for get_cached_fd. (try 5)
|
||||
|
||||
---
|
||||
dlls/ntdll/server.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 66 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
|
||||
index 69d01be..29cfcb5 100644
|
||||
--- a/dlls/ntdll/server.c
|
||||
+++ b/dlls/ntdll/server.c
|
||||
@@ -75,6 +75,8 @@
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
+#include "windef.h"
|
||||
+#include "winnt.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
@@ -790,6 +792,7 @@ static int receive_fd( obj_handle_t *handle )
|
||||
/***********************************************************************/
|
||||
/* fd cache support */
|
||||
|
||||
+#include "pshpack1.h"
|
||||
struct fd_cache_entry
|
||||
{
|
||||
int fd;
|
||||
@@ -797,6 +800,7 @@ struct fd_cache_entry
|
||||
unsigned int access : 3;
|
||||
unsigned int options : 24;
|
||||
};
|
||||
+#include "poppack.h"
|
||||
|
||||
#define FD_CACHE_BLOCK_SIZE (65536 / sizeof(struct fd_cache_entry))
|
||||
#define FD_CACHE_ENTRIES 128
|
||||
@@ -811,6 +815,36 @@ static inline unsigned int handle_to_index( HANDLE handle, unsigned int *entry )
|
||||
return idx % FD_CACHE_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
+#if !defined(__powerpc__)
|
||||
+
|
||||
+static inline LONG64 interlocked_xchg64( LONG64 *dest, LONG64 val )
|
||||
+{
|
||||
+#ifdef _WIN64
|
||||
+ return (LONG64)interlocked_xchg_ptr( (void **)dest, (void *)val );
|
||||
+#else
|
||||
+ LONG64 cmp = *dest;
|
||||
+ while (interlocked_cmpxchg64( dest, val, cmp ) != cmp) cmp = *dest;
|
||||
+ return cmp;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+C_ASSERT( sizeof(struct fd_cache_entry) == sizeof(LONG64) );
|
||||
+
|
||||
+/* atomically updates a fd cache entry and fetches the old value */
|
||||
+static inline void interlocked_xchg_fd_cache( struct fd_cache_entry *cache,
|
||||
+ struct fd_cache_entry *val )
|
||||
+{
|
||||
+ *(LONG64 *)val = interlocked_xchg64( (LONG64 *)cache, *(LONG64 *)val );
|
||||
+}
|
||||
+
|
||||
+/* atomically reads a fd cache entry */
|
||||
+static inline void interlocked_read_fd_cache( struct fd_cache_entry *cache,
|
||||
+ struct fd_cache_entry *val )
|
||||
+{
|
||||
+ *(LONG64 *)val = interlocked_cmpxchg64( (LONG64 *)cache, 0, 0 );
|
||||
+}
|
||||
+
|
||||
+#endif /* !defined(__powerpc__) */
|
||||
|
||||
/***********************************************************************
|
||||
* add_fd_to_cache
|
||||
@@ -821,6 +855,9 @@ static BOOL add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
|
||||
unsigned int access, unsigned int options )
|
||||
{
|
||||
unsigned int entry, idx = handle_to_index( handle, &entry );
|
||||
+#if !defined(__powerpc__)
|
||||
+ struct fd_cache_entry cache;
|
||||
+#endif
|
||||
|
||||
if (entry >= FD_CACHE_ENTRIES)
|
||||
{
|
||||
@@ -839,12 +876,22 @@ static BOOL add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
|
||||
fd_cache[entry] = ptr;
|
||||
}
|
||||
}
|
||||
+
|
||||
/* store fd+1 so that 0 can be used as the unset value */
|
||||
+#if defined(__powerpc__)
|
||||
fd = interlocked_xchg( &fd_cache[entry][idx].fd, fd + 1 );
|
||||
fd_cache[entry][idx].type = type;
|
||||
fd_cache[entry][idx].access = access;
|
||||
fd_cache[entry][idx].options = options;
|
||||
assert( !fd );
|
||||
+#else
|
||||
+ cache.fd = fd + 1;
|
||||
+ cache.type = type;
|
||||
+ cache.access = access;
|
||||
+ cache.options = options;
|
||||
+ interlocked_xchg_fd_cache( &fd_cache[entry][idx], &cache );
|
||||
+ assert( !cache.fd );
|
||||
+#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -852,7 +899,7 @@ static BOOL add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
|
||||
/***********************************************************************
|
||||
* get_cached_fd
|
||||
*
|
||||
- * Caller must hold fd_cache_section.
|
||||
+ * Caller must hold fd_cache_section on PowerPC processor architecture.
|
||||
*/
|
||||
static inline int get_cached_fd( HANDLE handle, enum server_fd_type *type,
|
||||
unsigned int *access, unsigned int *options )
|
||||
@@ -862,10 +909,19 @@ static inline int get_cached_fd( HANDLE handle, enum server_fd_type *type,
|
||||
|
||||
if (entry < FD_CACHE_ENTRIES && fd_cache[entry])
|
||||
{
|
||||
+ #if defined(__powerpc__)
|
||||
fd = fd_cache[entry][idx].fd - 1;
|
||||
if (type) *type = fd_cache[entry][idx].type;
|
||||
if (access) *access = fd_cache[entry][idx].access;
|
||||
if (options) *options = fd_cache[entry][idx].options;
|
||||
+ #else
|
||||
+ struct fd_cache_entry cache;
|
||||
+ interlocked_read_fd_cache( &fd_cache[entry][idx], &cache );
|
||||
+ fd = cache.fd - 1;
|
||||
+ if (type) *type = cache.type;
|
||||
+ if (access) *access = cache.access;
|
||||
+ if (options) *options = cache.options;
|
||||
+ #endif
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
@@ -903,6 +959,11 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
*needs_close = 0;
|
||||
wanted_access &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA;
|
||||
|
||||
+#if !defined(__powerpc__)
|
||||
+ fd = get_cached_fd( handle, type, &access, options );
|
||||
+ if (fd != -1) goto done_unlocked;
|
||||
+#endif
|
||||
+
|
||||
server_enter_uninterrupted_section( &fd_cache_section, &sigset );
|
||||
|
||||
fd = get_cached_fd( handle, type, &access, options );
|
||||
@@ -930,6 +991,10 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
|
||||
done:
|
||||
server_leave_uninterrupted_section( &fd_cache_section, &sigset );
|
||||
+
|
||||
+#if !defined(__powerpc__)
|
||||
+done_unlocked:
|
||||
+#endif
|
||||
if (!ret && ((access & wanted_access) != wanted_access))
|
||||
{
|
||||
ret = STATUS_ACCESS_DENIED;
|
||||
--
|
||||
2.3.0
|
||||
|
@ -0,0 +1,207 @@
|
||||
From 65cdd8fabe3124792f9dc3c14ae4bdb96b47c481 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Thu, 30 Apr 2015 05:43:16 +0200
|
||||
Subject: ntdll: Use lockfree implementation for get_cached_fd. (try 2)
|
||||
|
||||
v2: Avoid #ifdefs and simplify code a bit. On PowerPC all interlocked operations will use
|
||||
interlocked_cmpxchg64, which means that we can implement it using a pthread lock.
|
||||
---
|
||||
dlls/ntdll/server.c | 105 ++++++++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 68 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
|
||||
index 69d01be..652a1aa 100644
|
||||
--- a/dlls/ntdll/server.c
|
||||
+++ b/dlls/ntdll/server.c
|
||||
@@ -75,6 +75,8 @@
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
+#include "windef.h"
|
||||
+#include "winnt.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
@@ -126,6 +128,17 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
};
|
||||
static RTL_CRITICAL_SECTION fd_cache_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
+/* atomically exchange a 64-bit value */
|
||||
+static inline LONG64 interlocked_xchg64( LONG64 *dest, LONG64 val )
|
||||
+{
|
||||
+#ifdef _WIN64
|
||||
+ return (LONG64)interlocked_xchg_ptr( (void **)dest, (void *)val );
|
||||
+#else
|
||||
+ LONG64 tmp = *dest;
|
||||
+ while (interlocked_cmpxchg64( dest, val, tmp ) != tmp) tmp = *dest;
|
||||
+ return tmp;
|
||||
+#endif
|
||||
+}
|
||||
|
||||
#ifdef __GNUC__
|
||||
static void fatal_error( const char *err, ... ) __attribute__((noreturn, format(printf,1,2)));
|
||||
@@ -790,19 +803,27 @@ static int receive_fd( obj_handle_t *handle )
|
||||
/***********************************************************************/
|
||||
/* fd cache support */
|
||||
|
||||
-struct fd_cache_entry
|
||||
+#include "pshpack1.h"
|
||||
+union fd_cache_entry
|
||||
{
|
||||
- int fd;
|
||||
- enum server_fd_type type : 5;
|
||||
- unsigned int access : 3;
|
||||
- unsigned int options : 24;
|
||||
+ LONG64 data;
|
||||
+ struct
|
||||
+ {
|
||||
+ int fd;
|
||||
+ enum server_fd_type type : 5;
|
||||
+ unsigned int access : 3;
|
||||
+ unsigned int options : 24;
|
||||
+ } s;
|
||||
};
|
||||
+#include "poppack.h"
|
||||
|
||||
-#define FD_CACHE_BLOCK_SIZE (65536 / sizeof(struct fd_cache_entry))
|
||||
+C_ASSERT( sizeof(union fd_cache_entry) == sizeof(LONG64) );
|
||||
+
|
||||
+#define FD_CACHE_BLOCK_SIZE (65536 / sizeof(union fd_cache_entry))
|
||||
#define FD_CACHE_ENTRIES 128
|
||||
|
||||
-static struct fd_cache_entry *fd_cache[FD_CACHE_ENTRIES];
|
||||
-static struct fd_cache_entry fd_cache_initial_block[FD_CACHE_BLOCK_SIZE];
|
||||
+static union fd_cache_entry *fd_cache[FD_CACHE_ENTRIES];
|
||||
+static union fd_cache_entry fd_cache_initial_block[FD_CACHE_BLOCK_SIZE];
|
||||
|
||||
static inline unsigned int handle_to_index( HANDLE handle, unsigned int *entry )
|
||||
{
|
||||
@@ -821,6 +842,7 @@ static BOOL add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
|
||||
unsigned int access, unsigned int options )
|
||||
{
|
||||
unsigned int entry, idx = handle_to_index( handle, &entry );
|
||||
+ union fd_cache_entry cache;
|
||||
|
||||
if (entry >= FD_CACHE_ENTRIES)
|
||||
{
|
||||
@@ -833,26 +855,26 @@ static BOOL add_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
|
||||
if (!entry) fd_cache[0] = fd_cache_initial_block;
|
||||
else
|
||||
{
|
||||
- void *ptr = wine_anon_mmap( NULL, FD_CACHE_BLOCK_SIZE * sizeof(struct fd_cache_entry),
|
||||
+ void *ptr = wine_anon_mmap( NULL, FD_CACHE_BLOCK_SIZE * sizeof(union fd_cache_entry),
|
||||
PROT_READ | PROT_WRITE, 0 );
|
||||
if (ptr == MAP_FAILED) return FALSE;
|
||||
fd_cache[entry] = ptr;
|
||||
}
|
||||
}
|
||||
+
|
||||
/* store fd+1 so that 0 can be used as the unset value */
|
||||
- fd = interlocked_xchg( &fd_cache[entry][idx].fd, fd + 1 );
|
||||
- fd_cache[entry][idx].type = type;
|
||||
- fd_cache[entry][idx].access = access;
|
||||
- fd_cache[entry][idx].options = options;
|
||||
- assert( !fd );
|
||||
+ cache.s.fd = fd + 1;
|
||||
+ cache.s.type = type;
|
||||
+ cache.s.access = access;
|
||||
+ cache.s.options = options;
|
||||
+ cache.data = interlocked_xchg64( &fd_cache[entry][idx].data, cache.data );
|
||||
+ assert( !cache.s.fd );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_cached_fd
|
||||
- *
|
||||
- * Caller must hold fd_cache_section.
|
||||
*/
|
||||
static inline int get_cached_fd( HANDLE handle, enum server_fd_type *type,
|
||||
unsigned int *access, unsigned int *options )
|
||||
@@ -862,10 +884,12 @@ static inline int get_cached_fd( HANDLE handle, enum server_fd_type *type,
|
||||
|
||||
if (entry < FD_CACHE_ENTRIES && fd_cache[entry])
|
||||
{
|
||||
- fd = fd_cache[entry][idx].fd - 1;
|
||||
- if (type) *type = fd_cache[entry][idx].type;
|
||||
- if (access) *access = fd_cache[entry][idx].access;
|
||||
- if (options) *options = fd_cache[entry][idx].options;
|
||||
+ union fd_cache_entry cache;
|
||||
+ cache.data = interlocked_cmpxchg64( &fd_cache[entry][idx].data, 0, 0 );
|
||||
+ fd = cache.s.fd - 1;
|
||||
+ if (type) *type = cache.s.type;
|
||||
+ if (access) *access = cache.s.access;
|
||||
+ if (options) *options = cache.s.options;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
@@ -880,7 +904,11 @@ int server_remove_fd_from_cache( HANDLE handle )
|
||||
int fd = -1;
|
||||
|
||||
if (entry < FD_CACHE_ENTRIES && fd_cache[entry])
|
||||
- fd = interlocked_xchg( &fd_cache[entry][idx].fd, 0 ) - 1;
|
||||
+ {
|
||||
+ union fd_cache_entry cache;
|
||||
+ cache.data = interlocked_xchg64( &fd_cache[entry][idx].data, 0 );
|
||||
+ fd = cache.s.fd - 1;
|
||||
+ }
|
||||
|
||||
return fd;
|
||||
}
|
||||
@@ -903,33 +931,36 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
|
||||
*needs_close = 0;
|
||||
wanted_access &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA;
|
||||
|
||||
- server_enter_uninterrupted_section( &fd_cache_section, &sigset );
|
||||
-
|
||||
fd = get_cached_fd( handle, type, &access, options );
|
||||
if (fd != -1) goto done;
|
||||
|
||||
- SERVER_START_REQ( get_handle_fd )
|
||||
+ server_enter_uninterrupted_section( &fd_cache_section, &sigset );
|
||||
+ fd = get_cached_fd( handle, type, &access, options );
|
||||
+ if (fd == -1)
|
||||
{
|
||||
- req->handle = wine_server_obj_handle( handle );
|
||||
- if (!(ret = wine_server_call( req )))
|
||||
+ SERVER_START_REQ( get_handle_fd )
|
||||
{
|
||||
- if (type) *type = reply->type;
|
||||
- if (options) *options = reply->options;
|
||||
- access = reply->access;
|
||||
- if ((fd = receive_fd( &fd_handle )) != -1)
|
||||
+ req->handle = wine_server_obj_handle( handle );
|
||||
+ if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
- assert( wine_server_ptr_handle(fd_handle) == handle );
|
||||
- *needs_close = (!reply->cacheable ||
|
||||
- !add_fd_to_cache( handle, fd, reply->type,
|
||||
- reply->access, reply->options ));
|
||||
+ if (type) *type = reply->type;
|
||||
+ if (options) *options = reply->options;
|
||||
+ access = reply->access;
|
||||
+ if ((fd = receive_fd( &fd_handle )) != -1)
|
||||
+ {
|
||||
+ assert( wine_server_ptr_handle(fd_handle) == handle );
|
||||
+ *needs_close = (!reply->cacheable ||
|
||||
+ !add_fd_to_cache( handle, fd, reply->type,
|
||||
+ reply->access, reply->options ));
|
||||
+ }
|
||||
+ else ret = STATUS_TOO_MANY_OPENED_FILES;
|
||||
}
|
||||
- else ret = STATUS_TOO_MANY_OPENED_FILES;
|
||||
}
|
||||
+ SERVER_END_REQ;
|
||||
}
|
||||
- SERVER_END_REQ;
|
||||
+ server_leave_uninterrupted_section( &fd_cache_section, &sigset );
|
||||
|
||||
done:
|
||||
- server_leave_uninterrupted_section( &fd_cache_section, &sigset );
|
||||
if (!ret && ((access & wanted_access) != wanted_access))
|
||||
{
|
||||
ret = STATUS_ACCESS_DENIED;
|
||||
--
|
||||
2.3.5
|
||||
|
@ -3433,12 +3433,14 @@ fi
|
||||
# Patchset ntdll-FD_Cache
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/server.c
|
||||
# | * dlls/ntdll/server.c, libs/port/interlocked.c
|
||||
# |
|
||||
if test "$enable_ntdll_FD_Cache" -eq 1; then
|
||||
patch_apply ntdll-FD_Cache/0001-ntdll-Use-lockfree-implementation-for-get_cached_fd.patch
|
||||
patch_apply ntdll-FD_Cache/0001-libs-Implement-interlocked_cmpxchg64-on-PowerPC-usin.patch
|
||||
patch_apply ntdll-FD_Cache/0002-ntdll-Use-lockfree-implementation-for-get_cached_fd..patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "ntdll: Use lockfree implementation for get_cached_fd.", 5 },';
|
||||
echo '+ { "Sebastian Lackner", "libs: Implement interlocked_cmpxchg64 on PowerPC using pthread mutex.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "ntdll: Use lockfree implementation for get_cached_fd.", 2 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user