From cc461324dacdaa756259cf29160c238f9552043b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 15 Jun 2004 00:52:03 +0000 Subject: [PATCH] Store the number of processors in the PEB structure. More correct support for setting critical section spin counts (based on a patch by Robert Shearman). --- dlls/kernel/kernel32.spec | 2 +- dlls/kernel/kernel_main.c | 5 +++++ dlls/kernel/sync.c | 23 ----------------------- dlls/ntdll/critsection.c | 45 ++++++++++++++++++++++++++++++++------------- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/thread.c | 9 +++++---- include/winternl.h | 5 ++++- 7 files changed, 48 insertions(+), 42 deletions(-) diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec index d9a5bca4796..e852f5e5442 100644 --- a/dlls/kernel/kernel32.spec +++ b/dlls/kernel/kernel32.spec @@ -1073,7 +1073,7 @@ @ stdcall ProcessIdToSessionId(long ptr) @ stdcall SetCalendarInfoA(long long long str) @ stdcall SetCalendarInfoW(long long long wstr) -@ stdcall SetCriticalSectionSpinCount(ptr long) +@ stdcall SetCriticalSectionSpinCount(ptr long) ntdll.RtlSetCriticalSectionSpinCount @ stub SetInformationJobObject @ stub SetTermsrvAppInstallMode @ stdcall VerifyVersionInfoA(long long long long) diff --git a/dlls/kernel/kernel_main.c b/dlls/kernel/kernel_main.c index 1f03e9ad3d6..7c749f52dc2 100644 --- a/dlls/kernel/kernel_main.c +++ b/dlls/kernel/kernel_main.c @@ -108,6 +108,11 @@ static void thread_detach(void) static BOOL process_attach(void) { HMODULE16 hModule; + SYSTEM_INFO si; + + /* FIXME: should probably be done in ntdll */ + GetSystemInfo( &si ); + NtCurrentTeb()->Peb->NumberOfProcessors = si.dwNumberOfProcessors; /* Setup registry locale information */ LOCALE_InitRegistry(); diff --git a/dlls/kernel/sync.c b/dlls/kernel/sync.c index f867b79a38e..e9d23b3f14e 100644 --- a/dlls/kernel/sync.c +++ b/dlls/kernel/sync.c @@ -317,29 +317,6 @@ BOOL WINAPI InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION *crit, DWORD } /*********************************************************************** - * SetCriticalSectionSpinCount (KERNEL32.@) - * - * Set the spin count for a critical section. - * - * PARAMS - * crit [O] Critical section to set the spin count for. - * spincount [I] Number of times to spin upon contention. - * - * RETURNS - * The previous spin count value of crit. - * - * NOTES - * This function is available on NT4SP3 or later, but not Win98. - */ -DWORD WINAPI SetCriticalSectionSpinCount( CRITICAL_SECTION *crit, DWORD spincount ) -{ - ULONG_PTR oldspincount = crit->SpinCount; - if(spincount) FIXME("critsection=%p: spincount=%ld not supported\n", crit, spincount); - crit->SpinCount = spincount; - return oldspincount; -} - -/*********************************************************************** * MakeCriticalSectionGlobal (KERNEL32.@) */ void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit ) diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c index 4d60bb489d4..4257715f470 100644 --- a/dlls/ntdll/critsection.c +++ b/dlls/ntdll/critsection.c @@ -78,6 +78,27 @@ static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit ) */ NTSTATUS WINAPI RtlInitializeCriticalSection( RTL_CRITICAL_SECTION *crit ) { + return RtlInitializeCriticalSectionAndSpinCount( crit, 0 ); +} + +/*********************************************************************** + * RtlInitializeCriticalSectionAndSpinCount (NTDLL.@) + * + * Initialise a new RTL_CRITICAL_SECTION with a given spin count. + * + * PARAMS + * crit [O] Critical section to initialise + * spincount [I] Spin count for crit + * + * RETURNS + * STATUS_SUCCESS. + * + * NOTES + * The InitializeCriticalSectionAndSpinCount() (KERNEL32) function is + * available on NT4SP3 or later, and Win98 or later. + */ +NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount( RTL_CRITICAL_SECTION *crit, ULONG spincount ) +{ if (!GetProcessHeap()) crit->DebugInfo = NULL; else { @@ -99,35 +120,33 @@ NTSTATUS WINAPI RtlInitializeCriticalSection( RTL_CRITICAL_SECTION *crit ) crit->RecursionCount = 0; crit->OwningThread = 0; crit->LockSemaphore = 0; + crit->SpinCount = spincount; return STATUS_SUCCESS; } /*********************************************************************** - * RtlInitializeCriticalSectionAndSpinCount (NTDLL.@) + * RtlSetCriticalSectionSpinCount (NTDLL.@) * - * Initialise a new RTL_CRITICAL_SECTION with a given spin count. + * Sets the spin count of a critical section. * * PARAMS - * crit [O] Critical section to initialise + * crit [O] Critical section * spincount [I] Spin count for crit - * + * * RETURNS - * STATUS_SUCCESS. + * The previous spin count. * * NOTES - * The InitializeCriticalSectionAndSpinCount() (KERNEL32) function is - * available on NT4SP3 or later, and Win98 or later. - * I am assuming that this is the correct definition given the MSDN - * docs for the kernel32 functions. + * If the system is not SMP, spincount is ignored and set to 0. */ -NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount( RTL_CRITICAL_SECTION *crit, DWORD spincount ) +ULONG WINAPI RtlSetCriticalSectionSpinCount( RTL_CRITICAL_SECTION *crit, ULONG spincount ) { - if(spincount) TRACE("critsection=%p: spincount=%ld not supported\n", crit, spincount); + ULONG oldspincount = crit->SpinCount; + if (NtCurrentTeb()->Peb->NumberOfProcessors <= 1) spincount = 0; crit->SpinCount = spincount; - return RtlInitializeCriticalSection( crit ); + return oldspincount; } - /*********************************************************************** * RtlDeleteCriticalSection (NTDLL.@) * diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index ad00d1f47dc..0b7899e1f31 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -563,6 +563,7 @@ @ stdcall RtlSelfRelativeToAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall RtlSetAllBits(ptr) @ stdcall RtlSetBits(ptr long long) +@ stdcall RtlSetCriticalSectionSpinCount(ptr long) @ stdcall RtlSetCurrentDirectory_U(ptr) @ stdcall RtlSetCurrentEnvironment(wstr ptr) @ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long) diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index a1867dbd4c9..070ece0e2c9 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -106,9 +106,10 @@ void thread_init(void) struct wine_pthread_thread_info thread_info; static struct debug_info debug_info; /* debug info for initial thread */ - peb.ProcessParameters = ¶ms; - peb.TlsBitmap = &tls_bitmap; - peb.LdrData = &ldr; + peb.NumberOfProcessors = 1; + peb.ProcessParameters = ¶ms; + peb.TlsBitmap = &tls_bitmap; + peb.LdrData = &ldr; RtlInitializeBitMap( &tls_bitmap, (BYTE *)peb.TlsBitmapBits, sizeof(peb.TlsBitmapBits) * 8 ); InitializeListHead( &ldr.InLoadOrderModuleList ); InitializeListHead( &ldr.InMemoryOrderModuleList ); @@ -524,7 +525,7 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, DWORD index; if (length != sizeof(DWORD)) return STATUS_INVALID_PARAMETER; - index = *(DWORD *)data; + index = *(const DWORD *)data; if (index >= 64) return STATUS_INVALID_PARAMETER; RtlAcquirePebLock(); for (entry = tls_links.Flink; entry != &tls_links; entry = entry->Flink) diff --git a/include/winternl.h b/include/winternl.h index 2a889dc8b53..1a61a5f23b8 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -156,7 +156,9 @@ typedef struct _PEB BYTE __pad_1c[36]; /* 1c */ PRTL_BITMAP TlsBitmap; /* 40 */ ULONG TlsBitmapBits[2]; /* 44 */ - BYTE __pad_4c[156]; /* 4c */ + BYTE __pad_4c[24]; /* 4c */ + ULONG NumberOfProcessors; /* 64 */ + BYTE __pad_68[128]; /* 68 */ PVOID Reserved3[59]; /* e8 */ ULONG SessionId; /* 1d4 */ } PEB, *PPEB; @@ -1513,6 +1515,7 @@ NTSTATUS WINAPI RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR,PSECURITY_DESC PDWORD,PACL,PDWORD,PACL,PDWORD,PSID,PDWORD,PSID,PDWORD); void WINAPI RtlSetAllBits(PRTL_BITMAP); void WINAPI RtlSetBits(PRTL_BITMAP,ULONG,ULONG); +ULONG WINAPI RtlSetCriticalSectionSpinCount(RTL_CRITICAL_SECTION*,ULONG); NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING*); void WINAPI RtlSetCurrentEnvironment(PWSTR, PWSTR*); NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,BOOLEAN); -- 2.11.4.GIT