Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensemphobj.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/ke/sem.c 00005 * PURPOSE: Implements the Semaphore Dispatcher Object 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* FUNCTIONS *****************************************************************/ 00016 00017 /* 00018 * @implemented 00019 */ 00020 VOID 00021 NTAPI 00022 KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, 00023 IN LONG Count, 00024 IN LONG Limit) 00025 { 00026 /* Simply Initialize the Header */ 00027 Semaphore->Header.Type = SemaphoreObject; 00028 Semaphore->Header.Size = sizeof(KSEMAPHORE) / sizeof(ULONG); 00029 Semaphore->Header.SignalState = Count; 00030 InitializeListHead(&(Semaphore->Header.WaitListHead)); 00031 00032 /* Set the Limit */ 00033 Semaphore->Limit = Limit; 00034 } 00035 00036 /* 00037 * @implemented 00038 */ 00039 LONG 00040 NTAPI 00041 KeReadStateSemaphore(IN PKSEMAPHORE Semaphore) 00042 { 00043 ASSERT_SEMAPHORE(Semaphore); 00044 00045 /* Just return the Signal State */ 00046 return Semaphore->Header.SignalState; 00047 } 00048 00049 /* 00050 * @implemented 00051 */ 00052 LONG 00053 NTAPI 00054 KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, 00055 IN KPRIORITY Increment, 00056 IN LONG Adjustment, 00057 IN BOOLEAN Wait) 00058 { 00059 LONG InitialState, State; 00060 KIRQL OldIrql; 00061 PKTHREAD CurrentThread; 00062 ASSERT_SEMAPHORE(Semaphore); 00063 ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); 00064 00065 /* Lock the Dispatcher Database */ 00066 OldIrql = KiAcquireDispatcherLock(); 00067 00068 /* Save the Old State and get new one */ 00069 InitialState = Semaphore->Header.SignalState; 00070 State = InitialState + Adjustment; 00071 00072 /* Check if the Limit was exceeded */ 00073 if ((Semaphore->Limit < State) || (InitialState > State)) 00074 { 00075 /* Raise an error if it was exceeded */ 00076 KiReleaseDispatcherLock(OldIrql); 00077 ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED); 00078 } 00079 00080 /* Now set the new state */ 00081 Semaphore->Header.SignalState = State; 00082 00083 /* Check if we should wake it */ 00084 if (!(InitialState) && !(IsListEmpty(&Semaphore->Header.WaitListHead))) 00085 { 00086 /* Wake the Semaphore */ 00087 KiWaitTest(&Semaphore->Header, Increment); 00088 } 00089 00090 /* Check if the caller wants to wait after this release */ 00091 if (Wait == FALSE) 00092 { 00093 /* Release the Lock */ 00094 KiReleaseDispatcherLock(OldIrql); 00095 } 00096 else 00097 { 00098 /* Set a wait */ 00099 CurrentThread = KeGetCurrentThread(); 00100 CurrentThread->WaitNext = TRUE; 00101 CurrentThread->WaitIrql = OldIrql; 00102 } 00103 00104 /* Return the previous state */ 00105 return InitialState; 00106 } 00107 00108 /* EOF */ Generated on Sun May 27 2012 04:37:32 for ReactOS by
1.7.6.1
|