Status = STATUS_SEMAPHORE_LIMIT_EXCEEDED; } else {
}
// 记录当前的信号量的值。 if (NULL != PreviousCount) { }
int mm=Semaphore->Count;
// 目前仅实现了标准记录型信号量,每执行一次信号量的释放操作 // 只能使信号量的值增加 1。
while ((!ListIsEmpty(&Semaphore->WaitListHead))&&(ReleaseCount)){ }
Semaphore->Count=mm+ReleaseCount; // 可能有线程被唤醒,执行线程调度。 Status = STATUS_SUCCESS;
PspWakeThread(&Semaphore->WaitListHead, STATUS_SUCCESS); PspThreadSchedule(); ReleaseCount--;
*PreviousCount = Semaphore->Count;
5. 源程序并附上注释
#include \VOID
PsInitializeSemaphore( /*++ 功能描述:
初始化信号量结构体。 IN PSEMAPHORE Semaphore, IN LONG InitialCount, IN LONG MaximumCount)
参数:
Semaphore -- 要初始化的信号量结构体指针。
InitialCount -- 信号量的初始值,不能小于 0 且不能大于 MaximumCount。 MaximumCount -- 信号量的最大值,必须大于 0。
返回值:无。 --*/ {
ASSERT(InitialCount >= 0 && InitialCount <= MaximumCount && MaximumCount > 0); Semaphore->Count = InitialCount; }
Semaphore->MaximumCount = MaximumCount; ListInitializeHead(&Semaphore->WaitListHead);
5
STATUS
PsWaitForSemaphore( /*++ 功能描述:
信号量的 Wait 操作(P 操作)。 IN PSEMAPHORE Semaphore, IN ULONG Milliseconds)
参数:
Semaphore -- Wait 操作的信号量对象。 Milliseconds -- 等待超时上限,单位毫秒。
返回值: --*/ {
BOOL IntState; STATUS flag;
ASSERT(KeGetIntNesting() == 0); // 中断环境下不能调用此函数。 IntState = KeEnableInterrupts(FALSE); // 开始原子操作,禁止中断。
// 目前仅实现了标准记录型信号量,不支持超时唤醒功能,所以 PspWait 函数 // 的第二个参数的值只能是 INFINITE。 if (Semaphore->Count>0){ } else
flag=PspWait(&Semaphore->WaitListHead, Milliseconds); Semaphore->Count--; flag=STATUS_SUCCESS; STATUS_SUCCESS。
当你修改信号量使之支持超时唤醒功能后,如果等待超时,应该返回 STATUS_TIMEOUT。
KeEnableInterrupts(IntState); // 原子操作完成,恢复中断。 return flag; } STATUS
PsReleaseSemaphore( /*++ 功能描述:
信号量的 Signal 操作(V 操作)。 IN PSEMAPHORE Semaphore, IN LONG ReleaseCount, OUT PLONG PreviousCount )
参数:
6
Semaphore -- Wait 操作的信号量对象。
ReleaseCount -- 信号量计数增加的数量。当前只能为 1。当你修改信号量使之支持
超时唤醒功能后,此参数的值能够大于等于 1。
PreviousCount -- 返回信号量计数在增加之前的值。
返回值: --*/ {
STATUS Status; BOOL IntState;
IntState = KeEnableInterrupts(FALSE); // 开始原子操作,禁止中断。 if (Semaphore->Count + ReleaseCount > Semaphore->MaximumCount) { Status = STATUS_SEMAPHORE_LIMIT_EXCEEDED; } else {
}
KeEnableInterrupts(IntState); // 原子操作完成,恢复中断。 return Status; }
////////////////////////////////////////////////////////////////////////// // 下面是和信号量对象类型相关的代码。 // 信号量对象类型指针。
POBJECT_TYPE PspSemaphoreType = NULL; // 用于初始化 semaphore 结构体的参数结构体。 typedef struct _SEM_CREATE_PARAM{
LONG InitialCount; LONG MaximumCount;
// 记录当前的信号量的值。 if (NULL != PreviousCount) { }
int mm=Semaphore->Count;
// 目前仅实现了标准记录型信号量,每执行一次信号量的释放操作 // 只能使信号量的值增加 1。
while ((!ListIsEmpty(&Semaphore->WaitListHead))&&(ReleaseCount)){ }
Semaphore->Count=mm+ReleaseCount; // 可能有线程被唤醒,执行线程调度。 Status = STATUS_SUCCESS;
PspWakeThread(&Semaphore->WaitListHead, STATUS_SUCCESS); PspThreadSchedule(); ReleaseCount--;
*PreviousCount = Semaphore->Count;
如果成功释放信号量,返回 STATUS_SUCCESS。
7
}SEM_CREATE_PARAM, *PSEM_CREATE_PARAM;
// semaphore 对象的构造函数,在创建新 semaphore 对象时被调用。 VOID
PspOnCreateSemaphoreObject( { }
// semaphore 对象类型的初始化函数。 VOID
PspCreateSemaphoreObjectType( { }
// semaphore 对象的构造函数。 STATUS
PsCreateSemaphoreObject( {
STATUS Status; PVOID SemaphoreObject; SEM_CREATE_PARAM CreateParam;
if(InitialCount < 0 || MaximumCount <= 0 || InitialCount > MaximumCount){ IN LONG InitialCount, IN LONG MaximumCount, IN PSTR Name,
OUT PHANDLE SemaphoreHandle )
STATUS Status;
OBJECT_TYPE_INITIALIZER Initializer;
Initializer.Create = PspOnCreateSemaphoreObject; Initializer.Delete = NULL;
Initializer.Wait = (OB_WAIT_METHOD)PsWaitForSemaphore; Initializer.Read = NULL; Initializer.Write = NULL;
Status = ObCreateObjectType(\if (!EOS_SUCCESS(Status)) { }
KeBugCheck(\VOID)
PsInitializeSemaphore( (PSEMAPHORE)SemaphoreObject,
((PSEM_CREATE_PARAM)CreateParam)->InitialCount, ((PSEM_CREATE_PARAM)CreateParam)->MaximumCount );
IN PVOID SemaphoreObject, IN ULONG_PTR CreateParam)
8
}
}
return STATUS_INVALID_PARAMETER;
// 创建信号量对象。
CreateParam.InitialCount = InitialCount; CreateParam.MaximumCount = MaximumCount; Status = ObCreateObject( PspSemaphoreType,
Name,
sizeof(SEMAPHORE), (ULONG_PTR)&CreateParam, &SemaphoreObject);
if (!EOS_SUCCESS(Status)) { }
Status = ObCreateHandle(SemaphoreObject, SemaphoreHandle); if (!EOS_SUCCESS(Status)) { }
return Status;
ObDerefObject(SemaphoreObject); return Status;
// semaphore 对象的 signal 操作函数。 STATUS
PsReleaseSemaphoreObject( {
STATUS Status; PSEMAPHORE Semaphore; if (ReleaseCount < 1) { }
// 由 semaphore 句柄得到 semaphore 对象的指针。
Status = ObRefObjectByHandle(Handle, PspSemaphoreType, (PVOID*)&Semaphore); if (EOS_SUCCESS(Status)) { }
return Status;
Status = PsReleaseSemaphore(Semaphore, ReleaseCount, PreviousCount); ObDerefObject(Semaphore); return STATUS_INVALID_PARAMETER; IN HANDLE Handle, IN LONG ReleaseCount, IN PLONG PreviousCount)
}
9