Author: fireball Date: Mon Feb 5 23:14:59 2007 New Revision: 25730
URL: http://svn.reactos.org/svn/reactos?rev=25730&view=rev Log: Merge 25584, 25588.
Added: branches/ros-branch-0_3_1/reactos/dll/win32/syssetup/syssetup_It.rc - copied unchanged from r25588, trunk/reactos/dll/win32/syssetup/syssetup_It.rc Modified: branches/ros-branch-0_3_1/reactos/dll/win32/syssetup/syssetup.rc branches/ros-branch-0_3_1/reactos/ntoskrnl/ex/init.c branches/ros-branch-0_3_1/reactos/ntoskrnl/ex/pushlock.c branches/ros-branch-0_3_1/reactos/ntoskrnl/include/internal/ex.h
Modified: branches/ros-branch-0_3_1/reactos/dll/win32/syssetup/syssetup.rc URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_1/reactos/dll/win... ============================================================================== --- branches/ros-branch-0_3_1/reactos/dll/win32/syssetup/syssetup.rc (original) +++ branches/ros-branch-0_3_1/reactos/dll/win32/syssetup/syssetup.rc Mon Feb 5 23:14:59 2007 @@ -51,3 +51,4 @@ #include "syssetup_Es.rc" #include "syssetup_Hu.rc" #include "syssetup_Uk.rc" +#include "syssetup_It.rc"
Modified: branches/ros-branch-0_3_1/reactos/ntoskrnl/ex/init.c URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_1/reactos/ntoskrn... ============================================================================== --- branches/ros-branch-0_3_1/reactos/ntoskrnl/ex/init.c (original) +++ branches/ros-branch-0_3_1/reactos/ntoskrnl/ex/init.c Mon Feb 5 23:14:59 2007 @@ -1,11 +1,11 @@ /* -* PROJECT: ReactOS Kernel -* LICENSE: GPL - See COPYING in the top level directory -* FILE: ntoskrnl/ex/init.c -* PURPOSE: Executive Initialization Code -* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) -* Eric Kohl (ekohl@rz-online.de) -*/ + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ex/init.c + * PURPOSE: Executive Initialization Code + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + * Eric Kohl (ekohl@rz-online.de) + */
/* INCLUDES ******************************************************************/
Modified: branches/ros-branch-0_3_1/reactos/ntoskrnl/ex/pushlock.c URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_1/reactos/ntoskrn... ============================================================================== --- branches/ros-branch-0_3_1/reactos/ntoskrnl/ex/pushlock.c (original) +++ branches/ros-branch-0_3_1/reactos/ntoskrnl/ex/pushlock.c Mon Feb 5 23:14:59 2007 @@ -342,6 +342,33 @@ }
/*++ + * @name ExWaitForUnblockPushLock + * + * The ExWaitForUnblockPushLock routine waits for a pushlock + * to be unblocked, for a specified internal. + * + * @param PushLock + * Pointer to a pushlock whose waiter list needs to be optimized. + * + * @param WaitBlock + * Pointer to the pushlock's wait block. + * + * @return STATUS_SUCCESS is the pushlock is now unblocked, otherwise the error + * code returned by KeWaitForSingleObject. + * + * @remarks If the wait fails, then a manual unblock is attempted. + * + *--*/ +VOID +FASTCALL +ExWaitForUnblockPushLock(IN PEX_PUSH_LOCK PushLock, + IN PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock) +{ + /* Call the timed function with no timeout */ + ExTimedWaitForUnblockPushLock(PushLock, WaitBlock, NULL); +} + +/*++ * @name ExBlockPushLock * * The ExBlockPushLock routine blocks a pushlock. @@ -360,25 +387,33 @@ VOID FASTCALL ExBlockPushLock(PEX_PUSH_LOCK PushLock, - PVOID WaitBlock) -{ - PVOID NewValue, OldValue; + PVOID pWaitBlock) +{ + PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock = pWaitBlock; + EX_PUSH_LOCK NewValue, OldValue; + + /* Detect invalid wait block alignment */ + ASSERT((ULONG_PTR)pWaitBlock & 0x10);
/* Set the waiting bit */ - ((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->Flags |= EX_PUSH_LOCK_FLAGS_WAIT; - - /* Link the wait blocks */ - ((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->Next = PushLock->Ptr; - - /* Try to set this one as the wait block now */ - NewValue = PushLock->Ptr; + WaitBlock->Flags = EX_PUSH_LOCK_FLAGS_WAIT; + + /* Get the old value */ + OldValue = *PushLock; + + /* Start block loop */ for (;;) { + /* Link the wait blocks */ + WaitBlock->Next = OldValue.Ptr; + /* Set the new wait block value */ - OldValue = InterlockedCompareExchangePointer(&PushLock->Ptr, - WaitBlock, - NewValue); - if (OldValue == NewValue) break; + NewValue.Ptr = InterlockedCompareExchangePointer(&PushLock->Ptr, + WaitBlock, + OldValue.Ptr); + if (OldValue.Ptr == NewValue.Ptr) break; + + /* Try again with the new value */ NewValue = OldValue; } } @@ -404,7 +439,7 @@ FASTCALL ExfAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock) { - EX_PUSH_LOCK_WAIT_BLOCK WaitBlock; + DEFINE_WAIT_BLOCK(WaitBlock); EX_PUSH_LOCK OldValue = *PushLock, NewValue, TempValue; BOOLEAN NeedWake; ULONG i; @@ -435,23 +470,23 @@ else { /* We'll have to create a Waitblock */ - WaitBlock.Flags = EX_PUSH_LOCK_FLAGS_EXCLUSIVE | - EX_PUSH_LOCK_FLAGS_WAIT; - WaitBlock.Previous = NULL; + WaitBlock->Flags = EX_PUSH_LOCK_FLAGS_EXCLUSIVE | + EX_PUSH_LOCK_FLAGS_WAIT; + WaitBlock->Previous = NULL; NeedWake = FALSE;
/* Check if there is already a waiter */ if (OldValue.Waiting) { /* Nobody is the last waiter yet */ - WaitBlock.Last = NULL; + WaitBlock->Last = NULL;
/* We are an exclusive waiter */ - WaitBlock.ShareCount = 0; + WaitBlock->ShareCount = 0;
/* Set the current Wait Block pointer */ - WaitBlock.Next = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR) - OldValue.Ptr &~ EX_PUSH_LOCK_PTR_BITS); + WaitBlock->Next = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR) + OldValue.Ptr &~ EX_PUSH_LOCK_PTR_BITS);
/* Point to ours */ NewValue.Value = (OldValue.Value & EX_PUSH_LOCK_MULTIPLE_SHARED) | @@ -466,10 +501,10 @@ else { /* We are the first waiter, so loop the wait block */ - WaitBlock.Last = &WaitBlock; + WaitBlock->Last = WaitBlock;
/* Set the share count */ - WaitBlock.ShareCount = OldValue.Shared; + WaitBlock->ShareCount = OldValue.Shared;
/* Check if someone is sharing this pushlock */ if (OldValue.Shared > 1) @@ -483,7 +518,7 @@ else { /* No shared count */ - WaitBlock.ShareCount = 0; + WaitBlock->ShareCount = 0;
/* Point to our wait block */ NewValue.Value = EX_PUSH_LOCK_LOCK | @@ -494,10 +529,10 @@
#if DBG /* Setup the Debug Wait Block */ - WaitBlock.Signaled = 0; - WaitBlock.OldValue = OldValue; - WaitBlock.NewValue = NewValue; - WaitBlock.PushLock = PushLock; + WaitBlock->Signaled = 0; + WaitBlock->OldValue = OldValue; + WaitBlock->NewValue = NewValue; + WaitBlock->PushLock = PushLock; #endif
/* Sanity check */ @@ -524,26 +559,26 @@ }
/* Set up the Wait Gate */ - KeInitializeGate(&WaitBlock.WakeGate); + KeInitializeGate(&WaitBlock->WakeGate);
/* Now spin on the push lock if necessary */ i = ExPushLockSpinCount; - if ((i) && (WaitBlock.Flags & EX_PUSH_LOCK_WAITING)) + if ((i) && (WaitBlock->Flags & EX_PUSH_LOCK_WAITING)) { /* Spin */ while (--i) YieldProcessor(); }
/* Now try to remove the wait bit */ - if (InterlockedBitTestAndReset(&WaitBlock.Flags, 1)) + if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1)) { /* Nobody removed it already, let's do a full wait */ - KeWaitForGate(&WaitBlock.WakeGate, WrPushLock, KernelMode); - ASSERT(WaitBlock.Signaled); + KeWaitForGate(&WaitBlock->WakeGate, WrPushLock, KernelMode); + ASSERT(WaitBlock->Signaled); }
/* We shouldn't be shared anymore */ - ASSERT((WaitBlock.ShareCount == 0)); + ASSERT((WaitBlock->ShareCount == 0));
/* Loop again */ OldValue = NewValue; @@ -570,7 +605,7 @@ FASTCALL ExfAcquirePushLockShared(PEX_PUSH_LOCK PushLock) { - EX_PUSH_LOCK_WAIT_BLOCK WaitBlock; + DEFINE_WAIT_BLOCK(WaitBlock); EX_PUSH_LOCK OldValue = *PushLock, NewValue; BOOLEAN NeedWake; ULONG i; @@ -614,20 +649,20 @@ else { /* We'll have to create a Waitblock */ - WaitBlock.Flags = EX_PUSH_LOCK_FLAGS_WAIT; - WaitBlock.ShareCount = 0; + WaitBlock->Flags = EX_PUSH_LOCK_FLAGS_WAIT; + WaitBlock->ShareCount = 0; NeedWake = FALSE; - WaitBlock.Previous = NULL; + WaitBlock->Previous = NULL;
/* Check if there is already a waiter */ if (OldValue.Waiting) { /* Set the current Wait Block pointer */ - WaitBlock.Next = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR) - OldValue.Ptr &~ EX_PUSH_LOCK_PTR_BITS); + WaitBlock->Next = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR) + OldValue.Ptr &~ EX_PUSH_LOCK_PTR_BITS);
/* Nobody is the last waiter yet */ - WaitBlock.Last = NULL; + WaitBlock->Last = NULL;
/* Point to ours */ NewValue.Value = (OldValue.Value & (EX_PUSH_LOCK_MULTIPLE_SHARED | @@ -642,7 +677,7 @@ else { /* We are the first waiter, so loop the wait block */ - WaitBlock.Last = &WaitBlock; + WaitBlock->Last = WaitBlock;
/* Point to our wait block */ NewValue.Value = (OldValue.Value & (EX_PUSH_LOCK_MULTIPLE_SHARED | @@ -656,10 +691,10 @@
#if DBG /* Setup the Debug Wait Block */ - WaitBlock.Signaled = 0; - WaitBlock.OldValue = OldValue; - WaitBlock.NewValue = NewValue; - WaitBlock.PushLock = PushLock; + WaitBlock->Signaled = 0; + WaitBlock->OldValue = OldValue; + WaitBlock->NewValue = NewValue; + WaitBlock->PushLock = PushLock; #endif
/* Write the new value */ @@ -683,26 +718,26 @@ }
/* Set up the Wait Gate */ - KeInitializeGate(&WaitBlock.WakeGate); + KeInitializeGate(&WaitBlock->WakeGate);
/* Now spin on the push lock if necessary */ i = ExPushLockSpinCount; - if ((i) && (WaitBlock.Flags & EX_PUSH_LOCK_WAITING)) + if ((i) && (WaitBlock->Flags & EX_PUSH_LOCK_WAITING)) { /* Spin */ while (--i) YieldProcessor(); }
/* Now try to remove the wait bit */ - if (InterlockedBitTestAndReset(&WaitBlock.Flags, 1)) + if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1)) { /* Fast-path did not work, we need to do a full wait */ - KeWaitForGate(&WaitBlock.WakeGate, WrPushLock, KernelMode); - ASSERT(WaitBlock.Signaled); + KeWaitForGate(&WaitBlock->WakeGate, WrPushLock, KernelMode); + ASSERT(WaitBlock->Signaled); }
/* We shouldn't be shared anymore */ - ASSERT((WaitBlock.ShareCount == 0)); + ASSERT((WaitBlock->ShareCount == 0)); } } } @@ -1004,7 +1039,7 @@ FASTCALL ExfReleasePushLockExclusive(PEX_PUSH_LOCK PushLock) { - EX_PUSH_LOCK NewValue; + EX_PUSH_LOCK NewValue, WakeValue; EX_PUSH_LOCK OldValue = *PushLock;
/* Loop until we can change */ @@ -1023,6 +1058,28 @@
/* Sanity check */ ASSERT(NewValue.Waking && !NewValue.Locked); + + /* Write the New Value. Save our original value for waking */ + WakeValue = NewValue; + NewValue.Ptr = InterlockedCompareExchangePointer(PushLock, + NewValue.Ptr, + OldValue.Ptr); + + /* Check if the value changed behind our back */ + if (NewValue.Value != OldValue.Value) + { + /* Wake the Pushlock */ + ExfWakePushLock(PushLock, WakeValue); + break; + } + } + else + { + /* A simple unlock */ + NewValue.Value = OldValue.Value &~ EX_PUSH_LOCK_LOCK; + + /* Sanity check */ + ASSERT(NewValue.Waking && !NewValue.Waiting);
/* Write the New Value */ NewValue.Ptr = InterlockedCompareExchangePointer(PushLock, @@ -1030,36 +1087,11 @@ OldValue.Ptr);
/* Check if the value changed behind our back */ - if (NewValue.Value != OldValue.Value) - { - /* Loop again */ - OldValue = NewValue; - continue; - } - - /* Wake the Pushlock */ - ExfWakePushLock(PushLock, NewValue); - break; - } - else - { - /* A simple unlock */ - NewValue.Value = OldValue.Value &~ EX_PUSH_LOCK_LOCK; - - /* Sanity check */ - ASSERT(NewValue.Waking && !NewValue.Waiting); - - /* Write the New Value */ - NewValue.Ptr = InterlockedCompareExchangePointer(PushLock, - NewValue.Ptr, - OldValue.Ptr); - - /* Check if the value changed behind our back */ if (NewValue.Value == OldValue.Value) break; - - /* Loop again */ - OldValue = NewValue; - } + } + + /* Loop again */ + OldValue = NewValue; } }
@@ -1128,7 +1160,7 @@ KIRQL OldIrql = DISPATCH_LEVEL;
/* Get the wait block and erase the previous one */ - WaitBlock = InterlockedExchangePointer(PushLock->Ptr, 0); + WaitBlock = InterlockedExchangePointer(&PushLock->Ptr, NULL); if (WaitBlock) { /* Check if there is a linked pushlock and raise IRQL appropriately */ @@ -1144,7 +1176,7 @@ if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1)) { /* Nobody removed the flag before us, so signal the event */ - KeSetEventBoostPriority(&WaitBlock->WakeEvent, IO_NO_INCREMENT); + KeSetEventBoostPriority(&WaitBlock->WakeEvent, NULL); }
/* Check if there was a next block */ @@ -1161,6 +1193,6 @@ EX_PUSH_LOCK_FLAGS_WAIT)) { /* Wait for the pushlock to be unblocked */ - ExTimedWaitForUnblockPushLock(PushLock, CurrentWaitBlock, NULL); - } -} + ExWaitForUnblockPushLock(PushLock, CurrentWaitBlock); + } +}
Modified: branches/ros-branch-0_3_1/reactos/ntoskrnl/include/internal/ex.h URL: http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_1/reactos/ntoskrn... ============================================================================== --- branches/ros-branch-0_3_1/reactos/ntoskrnl/include/internal/ex.h (original) +++ branches/ros-branch-0_3_1/reactos/ntoskrnl/include/internal/ex.h Mon Feb 5 23:14:59 2007 @@ -49,6 +49,36 @@ #define ExRundownCompleted _ExRundownCompleted #define ExGetPreviousMode KeGetPreviousMode
+// +// Detect GCC 4.1.2+ +// +#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40102 + +// +// Broken GCC with Alignment Bug. We'll do alignment ourselves at higher cost. +// +#define DEFINE_WAIT_BLOCK(x) \ + struct _AlignHack \ + { \ + UCHAR Hack[15]; \ + EX_PUSH_LOCK_WAIT_BLOCK UnalignedBlock; \ + } WaitBlockBuffer; \ + PEX_PUSH_LOCK_WAIT_BLOCK x = (PEX_PUSH_LOCK_WAIT_BLOCK) \ + ((ULONG_PTR)&WaitBlockBuffer.UnalignedBlock &~ 0xF); + +#else + +// +// This is only for compatibility; the compiler will optimize the extra +// local variable (the actual pointer) away, so we don't take any perf hit +// by doing this. +// +#define DEFINE_WAIT_BLOCK(x) \ + EX_PUSH_LOCK_WAIT_BLOCK WaitBlockBuffer; \ + PEX_PUSH_LOCK_WAIT_BLOCK x = &WaitBlockBuffer; + +#endif + /* INITIALIZATION FUNCTIONS *************************************************/
VOID @@ -498,6 +528,23 @@
/* PUSHLOCKS *****************************************************************/
+/* FIXME: VERIFY THESE! */ + +VOID +FASTCALL +ExBlockPushLock(PEX_PUSH_LOCK PushLock, + PVOID WaitBlock); + +VOID +FASTCALL +ExfUnblockPushLock(PEX_PUSH_LOCK PushLock, + PVOID CurrentWaitBlock); + +VOID +FASTCALL +ExWaitForUnblockPushLock(IN PEX_PUSH_LOCK PushLock, + IN PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock); + /*++ * @name ExInitializePushLock * INTERNAL MACRO @@ -653,12 +700,16 @@ FORCEINLINE ExWaitOnPushLock(PEX_PUSH_LOCK PushLock) { - /* Acquire the lock */ - ExfAcquirePushLockExclusive(PushLock); - ASSERT(PushLock->Locked); - - /* Release it */ - ExfReleasePushLockExclusive(PushLock); + /* Check if we're locked */ + if (PushLock->Locked) + { + /* Acquire the lock */ + ExfAcquirePushLockExclusive(PushLock); + ASSERT(PushLock->Locked); + + /* Release it */ + ExfReleasePushLockExclusive(PushLock); + } }
/*++