ntdll: Use the standard Interlocked* functions.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Alexandre Julliard 2020-05-02 15:10:04 +02:00
parent adb45d2294
commit 39e4b788d6
13 changed files with 138 additions and 113 deletions

View File

@ -1178,12 +1178,12 @@ static ACTIVATION_CONTEXT *check_actctx( HANDLE h )
static inline void actctx_addref( ACTIVATION_CONTEXT *actctx )
{
interlocked_xchg_add( &actctx->ref_count, 1 );
InterlockedIncrement( &actctx->ref_count );
}
static void actctx_release( ACTIVATION_CONTEXT *actctx )
{
if (interlocked_xchg_add( &actctx->ref_count, -1 ) == 1)
if (!InterlockedDecrement( &actctx->ref_count ))
{
unsigned int i, j;
@ -3547,7 +3547,7 @@ static NTSTATUS find_dll_redirection(ACTIVATION_CONTEXT* actctx, const UNICODE_S
NTSTATUS status = build_dllredirect_section(actctx, &section);
if (status) return status;
if (interlocked_cmpxchg_ptr((void**)&actctx->dllredirect_section, section, NULL))
if (InterlockedCompareExchangePointer((void**)&actctx->dllredirect_section, section, NULL))
RtlFreeHeap(GetProcessHeap(), 0, section);
}
@ -3740,7 +3740,7 @@ static NTSTATUS find_window_class(ACTIVATION_CONTEXT* actctx, const UNICODE_STRI
NTSTATUS status = build_wndclass_section(actctx, &section);
if (status) return status;
if (interlocked_cmpxchg_ptr((void**)&actctx->wndclass_section, section, NULL))
if (InterlockedCompareExchangePointer((void**)&actctx->wndclass_section, section, NULL))
RtlFreeHeap(GetProcessHeap(), 0, section);
}
@ -3931,7 +3931,7 @@ static NTSTATUS find_tlib_redirection(ACTIVATION_CONTEXT* actctx, const GUID *gu
NTSTATUS status = build_tlib_section(actctx, &section);
if (status) return status;
if (interlocked_cmpxchg_ptr((void**)&actctx->tlib_section, section, NULL))
if (InterlockedCompareExchangePointer((void**)&actctx->tlib_section, section, NULL))
RtlFreeHeap(GetProcessHeap(), 0, section);
}
@ -4266,7 +4266,7 @@ static NTSTATUS find_comserver_redirection(ACTIVATION_CONTEXT* actctx, const GUI
NTSTATUS status = build_comserver_section(actctx, &section);
if (status) return status;
if (interlocked_cmpxchg_ptr((void**)&actctx->comserver_section, section, NULL))
if (InterlockedCompareExchangePointer((void**)&actctx->comserver_section, section, NULL))
RtlFreeHeap(GetProcessHeap(), 0, section);
}
@ -4456,7 +4456,7 @@ static NTSTATUS find_cominterface_redirection(ACTIVATION_CONTEXT* actctx, const
NTSTATUS status = build_ifaceps_section(actctx, &section);
if (status) return status;
if (interlocked_cmpxchg_ptr((void**)&actctx->ifaceps_section, section, NULL))
if (InterlockedCompareExchangePointer((void**)&actctx->ifaceps_section, section, NULL))
RtlFreeHeap(GetProcessHeap(), 0, section);
}
@ -4604,7 +4604,7 @@ static NTSTATUS find_clr_surrogate(ACTIVATION_CONTEXT* actctx, const GUID *guid,
NTSTATUS status = build_clr_surrogate_section(actctx, &section);
if (status) return status;
if (interlocked_cmpxchg_ptr((void**)&actctx->clrsurrogate_section, section, NULL))
if (InterlockedCompareExchangePointer((void**)&actctx->clrsurrogate_section, section, NULL))
RtlFreeHeap(GetProcessHeap(), 0, section);
}
@ -4807,7 +4807,7 @@ static NTSTATUS find_progid_redirection(ACTIVATION_CONTEXT* actctx, const UNICOD
NTSTATUS status = build_comserver_section(actctx, &section);
if (status) return status;
if (interlocked_cmpxchg_ptr((void**)&actctx->comserver_section, section, NULL))
if (InterlockedCompareExchangePointer((void**)&actctx->comserver_section, section, NULL))
RtlFreeHeap(GetProcessHeap(), 0, section);
}
@ -4818,7 +4818,7 @@ static NTSTATUS find_progid_redirection(ACTIVATION_CONTEXT* actctx, const UNICOD
NTSTATUS status = build_progid_section(actctx, &section);
if (status) return status;
if (interlocked_cmpxchg_ptr((void**)&actctx->progid_section, section, NULL))
if (InterlockedCompareExchangePointer((void**)&actctx->progid_section, section, NULL))
RtlFreeHeap(GetProcessHeap(), 0, section);
}

View File

@ -40,16 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
WINE_DECLARE_DEBUG_CHANNEL(relay);
static inline LONG interlocked_inc( PLONG dest )
{
return interlocked_xchg_add( dest, 1 ) + 1;
}
static inline LONG interlocked_dec( PLONG dest )
{
return interlocked_xchg_add( dest, -1 ) - 1;
}
static inline void small_pause(void)
{
#ifdef __i386__
@ -108,7 +98,7 @@ static inline NTSTATUS fast_wait( RTL_CRITICAL_SECTION *crit, int timeout )
timespec.tv_sec = timeout;
timespec.tv_nsec = 0;
while ((val = interlocked_cmpxchg( (int *)&crit->LockSemaphore, 0, 1 )) != 1)
while ((val = InterlockedCompareExchange( (int *)&crit->LockSemaphore, 0, 1 )) != 1)
{
/* note: this may wait longer than specified in case of signals or */
/* multiple wake-ups, but that shouldn't be a problem */
@ -145,7 +135,7 @@ static inline semaphore_t get_mach_semaphore( RTL_CRITICAL_SECTION *crit )
{
semaphore_t sem;
if (semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, 0 )) return 0;
if (!(ret = interlocked_cmpxchg( (int *)&crit->LockSemaphore, sem, 0 )))
if (!(ret = InterlockedCompareExchange( (int *)&crit->LockSemaphore, sem, 0 )))
ret = sem;
else
semaphore_destroy( mach_task_self(), sem ); /* somebody beat us to it */
@ -217,7 +207,7 @@ static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
{
HANDLE sem;
if (NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 )) return 0;
if (!(ret = interlocked_cmpxchg_ptr( &crit->LockSemaphore, sem, 0 )))
if (!(ret = InterlockedCompareExchangePointer( &crit->LockSemaphore, sem, 0 )))
ret = sem;
else
NtClose(sem); /* somebody beat us to it */
@ -565,13 +555,13 @@ NTSTATUS WINAPI RtlEnterCriticalSection( RTL_CRITICAL_SECTION *crit )
if (crit->LockCount > 0) break; /* more than one waiter, don't bother spinning */
if (crit->LockCount == -1) /* try again */
{
if (interlocked_cmpxchg( &crit->LockCount, 0, -1 ) == -1) goto done;
if (InterlockedCompareExchange( &crit->LockCount, 0, -1 ) == -1) goto done;
}
small_pause();
}
}
if (interlocked_inc( &crit->LockCount ))
if (InterlockedIncrement( &crit->LockCount ))
{
if (crit->OwningThread == ULongToHandle(GetCurrentThreadId()))
{
@ -610,7 +600,7 @@ done:
BOOL WINAPI RtlTryEnterCriticalSection( RTL_CRITICAL_SECTION *crit )
{
BOOL ret = FALSE;
if (interlocked_cmpxchg( &crit->LockCount, 0, -1 ) == -1)
if (InterlockedCompareExchange( &crit->LockCount, 0, -1 ) == -1)
{
crit->OwningThread = ULongToHandle(GetCurrentThreadId());
crit->RecursionCount = 1;
@ -618,7 +608,7 @@ BOOL WINAPI RtlTryEnterCriticalSection( RTL_CRITICAL_SECTION *crit )
}
else if (crit->OwningThread == ULongToHandle(GetCurrentThreadId()))
{
interlocked_inc( &crit->LockCount );
InterlockedIncrement( &crit->LockCount );
crit->RecursionCount++;
ret = TRUE;
}
@ -684,13 +674,13 @@ NTSTATUS WINAPI RtlLeaveCriticalSection( RTL_CRITICAL_SECTION *crit )
{
if (--crit->RecursionCount)
{
if (crit->RecursionCount > 0) interlocked_dec( &crit->LockCount );
if (crit->RecursionCount > 0) InterlockedDecrement( &crit->LockCount );
else ERR( "section %p is not acquired\n", crit );
}
else
{
crit->OwningThread = 0;
if (interlocked_dec( &crit->LockCount ) >= 0)
if (InterlockedDecrement( &crit->LockCount ) >= 0)
{
/* someone is waiting */
RtlpUnWaitCriticalSection( crit );

View File

@ -410,7 +410,7 @@ static void release_fileio( struct async_fileio *io )
{
struct async_fileio *next = fileio_freelist;
io->next = next;
if (interlocked_cmpxchg_ptr( (void **)&fileio_freelist, io, next ) == next) return;
if (InterlockedCompareExchangePointer( (void **)&fileio_freelist, io, next ) == next) return;
}
}
@ -418,7 +418,7 @@ static struct async_fileio *alloc_fileio( DWORD size, async_callback_t callback,
{
/* first free remaining previous fileinfos */
struct async_fileio *io = interlocked_xchg_ptr( (void **)&fileio_freelist, NULL );
struct async_fileio *io = InterlockedExchangePointer( (void **)&fileio_freelist, NULL );
while (io)
{

View File

@ -380,10 +380,33 @@ LONGLONG WINAPI RtlExtendedMagicDivide(
/*************************************************************************
* RtlInterlockedCompareExchange64 (NTDLL.@)
*/
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
LONGLONG WINAPI RtlInterlockedCompareExchange64( LONGLONG *dest, LONGLONG xchg, LONGLONG compare )
{
return interlocked_cmpxchg64( dest, xchg, compare );
return __sync_val_compare_and_swap( dest, compare, xchg );
}
#else
__ASM_STDCALL_FUNC(RtlInterlockedCompareExchange64, 20,
"push %ebx\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
__ASM_CFI(".cfi_rel_offset %ebx,0\n\t")
"push %esi\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
__ASM_CFI(".cfi_rel_offset %esi,0\n\t")
"movl 12(%esp),%esi\n\t"
"movl 16(%esp),%ebx\n\t"
"movl 20(%esp),%ecx\n\t"
"movl 24(%esp),%eax\n\t"
"movl 28(%esp),%edx\n\t"
"lock; cmpxchg8b (%esi)\n\t"
"pop %esi\n\t"
__ASM_CFI(".cfi_same_value %esi\n\t")
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
"pop %ebx\n\t"
__ASM_CFI(".cfi_same_value %ebx\n\t")
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
"ret $20")
#endif
#endif /* _WIN64 */

View File

@ -1055,7 +1055,7 @@ static SHORT alloc_tls_slot( LDR_DATA_TABLE_ENTRY *mod )
(ULONG_PTR)teb->ClientId.UniqueThread, i, size, dir->SizeOfZeroFill, new_ptr );
RtlFreeHeap( GetProcessHeap(), 0,
interlocked_xchg_ptr( (void **)teb->ThreadLocalStoragePointer + i, new_ptr ));
InterlockedExchangePointer( (void **)teb->ThreadLocalStoragePointer + i, new_ptr ));
}
*(DWORD *)dir->AddressOfIndex = i;
@ -4371,7 +4371,7 @@ NTSTATUS WINAPI RtlSetSearchPathMode( ULONG flags )
val = 0;
break;
case BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT:
interlocked_xchg( (int *)&path_safe_mode, 2 );
InterlockedExchange( (int *)&path_safe_mode, 2 );
return STATUS_SUCCESS;
default:
return STATUS_INVALID_PARAMETER;
@ -4381,7 +4381,7 @@ NTSTATUS WINAPI RtlSetSearchPathMode( ULONG flags )
{
int prev = path_safe_mode;
if (prev == 2) break; /* permanently set */
if (interlocked_cmpxchg( (int *)&path_safe_mode, val, prev ) == prev) return STATUS_SUCCESS;
if (InterlockedCompareExchange( (int *)&path_safe_mode, val, prev ) == prev) return STATUS_SUCCESS;
}
return STATUS_ACCESS_DENIED;
}

View File

@ -237,7 +237,7 @@ static NTSTATUS load_norm_table( ULONG form, const struct norm_table **info )
if (i && tables[i] < tables[i-1]) goto invalid;
}
if (interlocked_cmpxchg_ptr( (void **)&norm_tables[form], data, NULL ))
if (InterlockedCompareExchangePointer( (void **)&norm_tables[form], data, NULL ))
RtlFreeHeap( GetProcessHeap(), 0, data );
}
*info = norm_tables[form];

View File

@ -294,6 +294,10 @@ extern SYSTEM_CPU_INFORMATION cpu_info DECLSPEC_HIDDEN;
NTSTATUS WINAPI RtlHashUnicodeString(PCUNICODE_STRING,BOOLEAN,ULONG,ULONG*);
void WINAPI LdrInitializeThunk(CONTEXT*,void**,ULONG_PTR,ULONG_PTR);
#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
#define InterlockedCompareExchange64(dest,xchg,cmp) RtlInterlockedCompareExchange64(dest,xchg,cmp)
#endif
/* string functions */
int __cdecl NTDLL_tolower( int c );
int __cdecl _stricmp( LPCSTR str1, LPCSTR str2 );

View File

@ -97,6 +97,25 @@ static const DWORD CRC_table[256] =
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#if defined(_WIN64) && !defined(_MSC_VER)
static inline unsigned char _InterlockedCompareExchange128(__int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare)
{
unsigned char ret;
#ifdef __x86_64__
__asm__ __volatile__( "lock cmpxchg16b %0; setz %b2"
: "=m" (dest[0]), "=m" (dest[1]), "=r" (ret),
"=a" (compare[0]), "=d" (compare[1])
: "m" (dest[0]), "m" (dest[1]), "3" (compare[0]), "4" (compare[1]),
"c" (xchg_high), "b" (xchg_low) );
#else
ret = __sync_bool_compare_and_swap( (__int128 *)dest, (__int128 *)compare,
((__int128)xchg_high << 64) | xchg_low );
#endif
return ret;
}
#endif
/*
* resource functions
*/
@ -1216,7 +1235,7 @@ static DWORD_PTR get_pointer_obfuscator( void )
/* set the high bits so dereferencing obfuscated pointers will (usually) crash */
rand |= (ULONG_PTR)0xc0000000 << ((sizeof (DWORD_PTR) - sizeof (ULONG))*8);
interlocked_cmpxchg_ptr( (void**) &pointer_obfuscator, (void*) rand, NULL );
InterlockedCompareExchangePointer( (void**) &pointer_obfuscator, (void*) rand, NULL );
}
return pointer_obfuscator;
@ -1289,7 +1308,7 @@ PSLIST_ENTRY WINAPI RtlInterlockedFlushSList(PSLIST_HEADER list)
{
old = *list;
new.Header16.Sequence = old.Header16.Sequence + 1;
} while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
} while (!_InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
#else
if (!list->s.Next.Next) return NULL;
@ -1298,8 +1317,8 @@ PSLIST_ENTRY WINAPI RtlInterlockedFlushSList(PSLIST_HEADER list)
{
old = *list;
new.s.Sequence = old.s.Sequence + 1;
} while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
old.Alignment) != old.Alignment);
} while (InterlockedCompareExchange64((__int64 *)&list->Alignment, new.Alignment,
old.Alignment) != old.Alignment);
return old.s.Next.Next;
#endif
}
@ -1319,7 +1338,7 @@ PSLIST_ENTRY WINAPI RtlInterlockedPushEntrySList(PSLIST_HEADER list, PSLIST_ENTR
entry->Next = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
new.Header16.Depth = old.Header16.Depth + 1;
new.Header16.Sequence = old.Header16.Sequence + 1;
} while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
} while (!_InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
#else
new.s.Next.Next = entry;
@ -1329,8 +1348,8 @@ PSLIST_ENTRY WINAPI RtlInterlockedPushEntrySList(PSLIST_HEADER list, PSLIST_ENTR
entry->Next = old.s.Next.Next;
new.s.Depth = old.s.Depth + 1;
new.s.Sequence = old.s.Sequence + 1;
} while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
old.Alignment) != old.Alignment);
} while (InterlockedCompareExchange64((__int64 *)&list->Alignment, new.Alignment,
old.Alignment) != old.Alignment);
return old.s.Next.Next;
#endif
}
@ -1359,7 +1378,7 @@ PSLIST_ENTRY WINAPI RtlInterlockedPopEntrySList(PSLIST_HEADER list)
{
}
__ENDTRY
} while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
} while (!_InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
#else
do
{
@ -1376,8 +1395,8 @@ PSLIST_ENTRY WINAPI RtlInterlockedPopEntrySList(PSLIST_HEADER list)
{
}
__ENDTRY
} while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
old.Alignment) != old.Alignment);
} while (InterlockedCompareExchange64((__int64 *)&list->Alignment, new.Alignment,
old.Alignment) != old.Alignment);
#endif
return entry;
}
@ -1398,7 +1417,7 @@ PSLIST_ENTRY WINAPI RtlInterlockedPushListSListEx(PSLIST_HEADER list, PSLIST_ENT
new.Header16.Depth = old.Header16.Depth + count;
new.Header16.Sequence = old.Header16.Sequence + 1;
last->Next = (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
} while (!interlocked_cmpxchg128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
} while (!_InterlockedCompareExchange128((__int64 *)list, new.s.Region, new.s.Alignment, (__int64 *)&old));
return (SLIST_ENTRY *)((ULONG_PTR)old.Header16.NextEntry << 4);
#else
new.s.Next.Next = first;
@ -1408,8 +1427,8 @@ PSLIST_ENTRY WINAPI RtlInterlockedPushListSListEx(PSLIST_HEADER list, PSLIST_ENT
new.s.Depth = old.s.Depth + count;
new.s.Sequence = old.s.Sequence + 1;
last->Next = old.s.Next.Next;
} while (interlocked_cmpxchg64((__int64 *)&list->Alignment, new.Alignment,
old.Alignment) != old.Alignment);
} while (InterlockedCompareExchange64((__int64 *)&list->Alignment, new.Alignment,
old.Alignment) != old.Alignment);
return old.s.Next.Next;
#endif
}

View File

@ -159,10 +159,10 @@ static RTL_CRITICAL_SECTION fd_cache_section = { &critsect_debug, -1, 0, 0, 0, 0
static inline LONG64 interlocked_xchg64( LONG64 *dest, LONG64 val )
{
#ifdef _WIN64
return (LONG64)interlocked_xchg_ptr( (void **)dest, (void *)val );
return (LONG64)InterlockedExchangePointer( (void **)dest, (void *)val );
#else
LONG64 tmp = *dest;
while (interlocked_cmpxchg64( dest, val, tmp ) != tmp) tmp = *dest;
while (InterlockedCompareExchange64( dest, val, tmp ) != tmp) tmp = *dest;
return tmp;
#endif
}
@ -1032,7 +1032,7 @@ static inline NTSTATUS get_cached_fd( HANDLE handle, int *fd, enum server_fd_typ
if (entry >= FD_CACHE_ENTRIES || !fd_cache[entry]) return STATUS_INVALID_HANDLE;
cache.data = interlocked_cmpxchg64( &fd_cache[entry][idx].data, 0, 0 );
cache.data = InterlockedCompareExchange64( &fd_cache[entry][idx].data, 0, 0 );
if (!cache.data) return STATUS_INVALID_HANDLE;
/* if fd type is invalid, fd stores an error value */

View File

@ -283,7 +283,7 @@ __ASM_STDCALL_FUNC( RtlCaptureContext, 8,
*/
static void set_cpu_context( const CONTEXT *context )
{
interlocked_xchg_ptr( (void **)&arm64_thread_data()->context, (void *)context );
InterlockedExchangePointer( (void **)&arm64_thread_data()->context, (void *)context );
raise( SIGUSR2 );
}
@ -1229,7 +1229,7 @@ static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*/
static void usr2_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
CONTEXT *context = interlocked_xchg_ptr( (void **)&arm64_thread_data()->context, NULL );
CONTEXT *context = InterlockedExchangePointer( (void **)&arm64_thread_data()->context, NULL );
if (!context) return;
if ((context->ContextFlags & ~CONTEXT_ARM64) & CONTEXT_FLOATING_POINT)
restore_fpu( context, sigcontext );

View File

@ -1587,16 +1587,16 @@ DWORD WINAPI RtlRunOnceBeginInitialize( RTL_RUN_ONCE *once, ULONG flags, void **
switch (val & 3)
{
case 0: /* first time */
if (!interlocked_cmpxchg_ptr( &once->Ptr,
(flags & RTL_RUN_ONCE_ASYNC) ? (void *)3 : (void *)1, 0 ))
if (!InterlockedCompareExchangePointer( &once->Ptr,
(flags & RTL_RUN_ONCE_ASYNC) ? (void *)3 : (void *)1, 0 ))
return STATUS_PENDING;
break;
case 1: /* in progress, wait */
if (flags & RTL_RUN_ONCE_ASYNC) return STATUS_INVALID_PARAMETER;
next = val & ~3;
if (interlocked_cmpxchg_ptr( &once->Ptr, (void *)((ULONG_PTR)&next | 1),
(void *)val ) == (void *)val)
if (InterlockedCompareExchangePointer( &once->Ptr, (void *)((ULONG_PTR)&next | 1),
(void *)val ) == (void *)val)
NtWaitForKeyedEvent( 0, &next, FALSE, NULL );
break;
@ -1632,7 +1632,7 @@ DWORD WINAPI RtlRunOnceComplete( RTL_RUN_ONCE *once, ULONG flags, void *context
switch (val & 3)
{
case 1: /* in progress */
if (interlocked_cmpxchg_ptr( &once->Ptr, context, (void *)val ) != (void *)val) break;
if (InterlockedCompareExchangePointer( &once->Ptr, context, (void *)val ) != (void *)val) break;
val &= ~3;
while (val)
{
@ -1644,7 +1644,7 @@ DWORD WINAPI RtlRunOnceComplete( RTL_RUN_ONCE *once, ULONG flags, void *context
case 3: /* in progress, async */
if (!(flags & RTL_RUN_ONCE_ASYNC)) return STATUS_INVALID_PARAMETER;
if (interlocked_cmpxchg_ptr( &once->Ptr, context, (void *)val ) != (void *)val) break;
if (InterlockedCompareExchangePointer( &once->Ptr, context, (void *)val ) != (void *)val) break;
return STATUS_SUCCESS;
default:
@ -1729,7 +1729,7 @@ static NTSTATUS fast_try_acquire_srw_exclusive( RTL_SRWLOCK *lock )
new = old;
ret = STATUS_TIMEOUT;
}
} while (interlocked_cmpxchg( futex, new, old ) != old);
} while (InterlockedCompareExchange( futex, new, old ) != old);
return ret;
}
@ -1750,7 +1750,7 @@ static NTSTATUS fast_acquire_srw_exclusive( RTL_SRWLOCK *lock )
old = *futex;
new = old + SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_INC;
assert(new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK);
} while (interlocked_cmpxchg( futex, new, old ) != old);
} while (InterlockedCompareExchange( futex, new, old ) != old);
for (;;)
{
@ -1772,7 +1772,7 @@ static NTSTATUS fast_acquire_srw_exclusive( RTL_SRWLOCK *lock )
new = old;
wait = TRUE;
}
} while (interlocked_cmpxchg( futex, new, old ) != old);
} while (InterlockedCompareExchange( futex, new, old ) != old);
if (!wait)
return STATUS_SUCCESS;
@ -1811,7 +1811,7 @@ static NTSTATUS fast_try_acquire_srw_shared( RTL_SRWLOCK *lock )
new = old;
ret = STATUS_TIMEOUT;
}
} while (interlocked_cmpxchg( futex, new, old ) != old);
} while (InterlockedCompareExchange( futex, new, old ) != old);
return ret;
}
@ -1846,7 +1846,7 @@ static NTSTATUS fast_acquire_srw_shared( RTL_SRWLOCK *lock )
new = old | SRWLOCK_FUTEX_SHARED_WAITERS_BIT;
wait = TRUE;
}
} while (interlocked_cmpxchg( futex, new, old ) != old);
} while (InterlockedCompareExchange( futex, new, old ) != old);
if (!wait)
return STATUS_SUCCESS;
@ -1880,7 +1880,7 @@ static NTSTATUS fast_release_srw_exclusive( RTL_SRWLOCK *lock )
if (!(new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK))
new &= ~SRWLOCK_FUTEX_SHARED_WAITERS_BIT;
} while (interlocked_cmpxchg( futex, new, old ) != old);
} while (InterlockedCompareExchange( futex, new, old ) != old);
if (new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK)
futex_wake_bitset( futex, 1, SRWLOCK_FUTEX_BITSET_EXCLUSIVE );
@ -1915,7 +1915,7 @@ static NTSTATUS fast_release_srw_shared( RTL_SRWLOCK *lock )
}
new = old - SRWLOCK_FUTEX_SHARED_OWNERS_INC;
} while (interlocked_cmpxchg( futex, new, old ) != old);
} while (InterlockedCompareExchange( futex, new, old ) != old);
/* Optimization: only bother waking if there are actually exclusive waiters. */
if (!(new & SRWLOCK_FUTEX_SHARED_OWNERS_MASK) && (new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK))
@ -2031,7 +2031,7 @@ static inline unsigned int srwlock_lock_exclusive( unsigned int *dest, int incr
srwlock_check_invalid( tmp );
if ((tmp & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(tmp & SRWLOCK_MASK_SHARED_QUEUE))
tmp |= SRWLOCK_MASK_IN_EXCLUSIVE;
if ((tmp = interlocked_cmpxchg( (int *)dest, tmp, val )) == val)
if ((tmp = InterlockedCompareExchange( (int *)dest, tmp, val )) == val)
break;
}
return val;
@ -2050,7 +2050,7 @@ static inline unsigned int srwlock_unlock_exclusive( unsigned int *dest, int inc
srwlock_check_invalid( tmp );
if (!(tmp & SRWLOCK_MASK_EXCLUSIVE_QUEUE))
tmp &= SRWLOCK_MASK_SHARED_QUEUE;
if ((tmp = interlocked_cmpxchg( (int *)dest, tmp, val )) == val)
if ((tmp = InterlockedCompareExchange( (int *)dest, tmp, val )) == val)
break;
}
return val;
@ -2133,7 +2133,7 @@ void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock )
tmp = val + SRWLOCK_RES_EXCLUSIVE;
else
tmp = val + SRWLOCK_RES_SHARED;
if ((tmp = interlocked_cmpxchg( (int *)&lock->Ptr, tmp, val )) == val)
if ((tmp = InterlockedCompareExchange( (int *)&lock->Ptr, tmp, val )) == val)
break;
}
@ -2188,8 +2188,8 @@ BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
if ((ret = fast_try_acquire_srw_exclusive( lock )) != STATUS_NOT_IMPLEMENTED)
return (ret == STATUS_SUCCESS);
return interlocked_cmpxchg( (int *)&lock->Ptr, SRWLOCK_MASK_IN_EXCLUSIVE |
SRWLOCK_RES_EXCLUSIVE, 0 ) == 0;
return InterlockedCompareExchange( (int *)&lock->Ptr, SRWLOCK_MASK_IN_EXCLUSIVE |
SRWLOCK_RES_EXCLUSIVE, 0 ) == 0;
}
/***********************************************************************
@ -2207,7 +2207,7 @@ BOOLEAN WINAPI RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock )
{
if (val & SRWLOCK_MASK_EXCLUSIVE_QUEUE)
return FALSE;
if ((tmp = interlocked_cmpxchg( (int *)&lock->Ptr, val + SRWLOCK_RES_SHARED, val )) == val)
if ((tmp = InterlockedCompareExchange( (int *)&lock->Ptr, val + SRWLOCK_RES_SHARED, val )) == val)
break;
}
return TRUE;
@ -2289,7 +2289,7 @@ static NTSTATUS fast_wake_cv( RTL_CONDITION_VARIABLE *variable, int count )
if (!(futex = get_futex( &variable->Ptr )))
return STATUS_NOT_IMPLEMENTED;
interlocked_xchg_add( futex, 1 );
InterlockedIncrement( futex );
futex_wake( futex, count );
return STATUS_SUCCESS;
}
@ -2347,7 +2347,7 @@ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable )
{
if (fast_wake_cv( variable, 1 ) == STATUS_NOT_IMPLEMENTED)
{
interlocked_xchg_add( (int *)&variable->Ptr, 1 );
InterlockedIncrement( (int *)&variable->Ptr );
RtlWakeAddressSingle( variable );
}
}
@ -2361,7 +2361,7 @@ void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable )
{
if (fast_wake_cv( variable, INT_MAX ) == STATUS_NOT_IMPLEMENTED)
{
interlocked_xchg_add( (int *)&variable->Ptr, 1 );
InterlockedIncrement( (int *)&variable->Ptr );
RtlWakeAddressAll( variable );
}
}
@ -2500,7 +2500,7 @@ static inline NTSTATUS fast_wait_addr( const void *addr, const void *cmp, SIZE_T
* now and waiting on the futex, we know that val will have changed.
* Use an atomic load so that memory accesses are ordered between this read
* and the increment below. */
val = interlocked_cmpxchg( futex, 0, 0 );
val = InterlockedCompareExchange( futex, 0, 0 );
if (!compare_addr( addr, cmp, size ))
return STATUS_SUCCESS;
@ -2526,7 +2526,7 @@ static inline NTSTATUS fast_wake_addr( const void *addr )
futex = hash_addr( addr );
interlocked_xchg_add( futex, 1 );
InterlockedIncrement( futex );
futex_wake( futex, INT_MAX );
return STATUS_SUCCESS;

View File

@ -312,7 +312,7 @@ TEB *thread_init(void)
void abort_thread( int status )
{
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
if (interlocked_xchg_add( &nb_threads, -1 ) <= 1) _exit( get_unix_exit_code( status ));
if (InterlockedDecrement( &nb_threads ) <= 0) _exit( get_unix_exit_code( status ));
signal_exit_thread( status );
}
@ -349,7 +349,7 @@ void WINAPI RtlExitUserThread( ULONG status )
SERVER_END_REQ;
}
if (interlocked_xchg_add( &nb_threads, -1 ) <= 1)
if (InterlockedDecrement( &nb_threads ) <= 0)
{
LdrShutdownProcess();
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
@ -361,7 +361,7 @@ void WINAPI RtlExitUserThread( ULONG status )
pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );
if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
if ((teb = InterlockedExchangePointer( &prev_teb, NtCurrentTeb() )))
{
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
@ -545,10 +545,10 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
(char *)teb->Tib.StackBase + extra_stack - (char *)teb->DeallocationStack );
pthread_attr_setguardsize( &attr, 0 );
pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); /* force creating a kernel thread */
interlocked_xchg_add( &nb_threads, 1 );
InterlockedIncrement( &nb_threads );
if (pthread_create( &pthread_id, &attr, (void * (*)(void *))start_thread, info ))
{
interlocked_xchg_add( &nb_threads, -1 );
InterlockedDecrement( &nb_threads );
pthread_attr_destroy( &attr );
status = STATUS_NO_MEMORY;
goto error;

View File

@ -379,16 +379,6 @@ static void tp_object_prepare_shutdown( struct threadpool_object *object );
static BOOL tp_object_release( struct threadpool_object *object );
static struct threadpool *default_threadpool = NULL;
static inline LONG interlocked_inc( PLONG dest )
{
return interlocked_xchg_add( dest, 1 ) + 1;
}
static inline LONG interlocked_dec( PLONG dest )
{
return interlocked_xchg_add( dest, -1 ) - 1;
}
static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
{
unsigned int new_capacity, max_capacity;
@ -605,14 +595,14 @@ static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
wait_work_item->Context );
TimerOrWaitFired = TRUE;
}
interlocked_xchg( &wait_work_item->CallbackInProgress, TRUE );
InterlockedExchange( &wait_work_item->CallbackInProgress, TRUE );
if (wait_work_item->CompletionEvent)
{
TRACE( "Work has been canceled.\n" );
break;
}
wait_work_item->Callback( wait_work_item->Context, TimerOrWaitFired );
interlocked_xchg( &wait_work_item->CallbackInProgress, FALSE );
InterlockedExchange( &wait_work_item->CallbackInProgress, FALSE );
if (wait_work_item->Flags & WT_EXECUTEONLYONCE)
break;
@ -622,7 +612,7 @@ static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
}
if (interlocked_inc( &wait_work_item->DeleteCount ) == 2 )
if (InterlockedIncrement( &wait_work_item->DeleteCount ) == 2 )
{
completion_event = wait_work_item->CompletionEvent;
delete_wait_work_item( wait_work_item );
@ -725,7 +715,7 @@ NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE WaitHandle, HANDLE CompletionEvent)
if (WaitHandle == NULL)
return STATUS_INVALID_HANDLE;
interlocked_xchg_ptr( &wait_work_item->CompletionEvent, INVALID_HANDLE_VALUE );
InterlockedExchangePointer( &wait_work_item->CompletionEvent, INVALID_HANDLE_VALUE );
CallbackInProgress = wait_work_item->CallbackInProgress;
TRACE( "callback in progress %u\n", CallbackInProgress );
if (CompletionEvent == INVALID_HANDLE_VALUE || !CallbackInProgress)
@ -733,16 +723,16 @@ NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE WaitHandle, HANDLE CompletionEvent)
status = NtCreateEvent( &LocalEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE );
if (status != STATUS_SUCCESS)
return status;
interlocked_xchg_ptr( &wait_work_item->CompletionEvent, LocalEvent );
InterlockedExchangePointer( &wait_work_item->CompletionEvent, LocalEvent );
}
else if (CompletionEvent != NULL)
{
interlocked_xchg_ptr( &wait_work_item->CompletionEvent, CompletionEvent );
InterlockedExchangePointer( &wait_work_item->CompletionEvent, CompletionEvent );
}
NtSetEvent( wait_work_item->CancelEvent, NULL );
if (interlocked_inc( &wait_work_item->DeleteCount ) == 2 )
if (InterlockedIncrement( &wait_work_item->DeleteCount ) == 2 )
{
status = STATUS_SUCCESS;
delete_wait_work_item( wait_work_item );
@ -1107,8 +1097,7 @@ static struct timer_queue *get_timer_queue(HANDLE TimerQueue)
NTSTATUS status = RtlCreateTimerQueue(&q);
if (status == STATUS_SUCCESS)
{
PVOID p = interlocked_cmpxchg_ptr(
(void **) &default_timer_queue, q, NULL);
PVOID p = InterlockedCompareExchangePointer( (void **) &default_timer_queue, q, NULL );
if (p)
/* Got beat to the punch. */
RtlDeleteTimerQueueEx(q, NULL);
@ -1384,7 +1373,7 @@ static NTSTATUS tp_new_worker_thread( struct threadpool *pool )
threadpool_worker_proc, pool, &thread, NULL );
if (status == STATUS_SUCCESS)
{
interlocked_inc( &pool->refcount );
InterlockedIncrement( &pool->refcount );
pool->num_workers++;
pool->num_busy_workers++;
NtClose( thread );
@ -1506,7 +1495,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
timeout.QuadPart = wait->u.wait.timeout;
assert( num_handles < MAXIMUM_WAITQUEUE_OBJECTS );
interlocked_inc( &wait->refcount );
InterlockedIncrement( &wait->refcount );
objects[num_handles] = wait;
handles[num_handles] = wait->u.wait.handle;
num_handles++;
@ -1899,7 +1888,7 @@ static BOOL tp_threadpool_release( struct threadpool *pool )
{
unsigned int i;
if (interlocked_dec( &pool->refcount ))
if (InterlockedDecrement( &pool->refcount ))
return FALSE;
TRACE( "destroying threadpool %p\n", pool );
@ -1957,7 +1946,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
if (status != STATUS_SUCCESS)
return status;
if (interlocked_cmpxchg_ptr( (void *)&default_threadpool, pool, NULL ) != NULL)
if (InterlockedCompareExchangePointer( (void *)&default_threadpool, pool, NULL ) != NULL)
{
tp_threadpool_shutdown( pool );
tp_threadpool_release( pool );
@ -1977,7 +1966,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
* last thread doesn't terminate. */
if (status == STATUS_SUCCESS)
{
interlocked_inc( &pool->refcount );
InterlockedIncrement( &pool->refcount );
pool->objcount++;
}
@ -2047,7 +2036,7 @@ static void tp_group_shutdown( struct threadpool_group *group )
*/
static BOOL tp_group_release( struct threadpool_group *group )
{
if (interlocked_dec( &group->refcount ))
if (InterlockedDecrement( &group->refcount ))
return FALSE;
TRACE( "destroying group %p\n", group );
@ -2134,7 +2123,7 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
if (object->group)
{
struct threadpool_group *group = object->group;
interlocked_inc( &group->refcount );
InterlockedIncrement( &group->refcount );
RtlEnterCriticalSection( &group->cs );
list_add_tail( &group->members, &object->group_entry );
@ -2173,7 +2162,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
status = tp_new_worker_thread( pool );
/* Queue work item and increment refcount. */
interlocked_inc( &object->refcount );
InterlockedIncrement( &object->refcount );
if (!object->num_pending_callbacks++)
tp_object_prio_queue( object );
@ -2275,7 +2264,7 @@ static void tp_object_prepare_shutdown( struct threadpool_object *object )
*/
static BOOL tp_object_release( struct threadpool_object *object )
{
if (interlocked_dec( &object->refcount ))
if (InterlockedDecrement( &object->refcount ))
return FALSE;
TRACE( "destroying object %p of type %u\n", object, object->type );
@ -2920,11 +2909,11 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
assert( object->group == this );
assert( object->is_group_member );
if (interlocked_inc( &object->refcount ) == 1)
if (InterlockedIncrement( &object->refcount ) == 1)
{
/* Object is basically already destroyed, but group reference
* was not deleted yet. We can safely ignore this object. */
interlocked_dec( &object->refcount );
InterlockedDecrement( &object->refcount );
list_remove( &object->group_entry );
object->is_group_member = FALSE;
continue;