- Use a spin lock to protect the port bitmap instead of a fast mutex
[reactos.git] / lib / drivers / ip / network / ports.c
index 6630b5e..0da2722 100644 (file)
@@ -15,106 +15,96 @@ NTSTATUS PortsStartup( PPORT_SET PortSet,
                   UINT PortsToManage ) {
     PortSet->StartingPort = StartingPort;
     PortSet->PortsToOversee = PortsToManage;
-    PortSet->LastAllocatedPort = PortSet->StartingPort +
-                                 PortSet->PortsToOversee - 1;
+
     PortSet->ProtoBitBuffer =
-       PoolAllocateBuffer( (PortSet->PortsToOversee + 7) / 8 );
+       ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8,
+                               PORT_SET_TAG );
     if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES;
     RtlInitializeBitMap( &PortSet->ProtoBitmap,
                         PortSet->ProtoBitBuffer,
                         PortSet->PortsToOversee );
     RtlClearAllBits( &PortSet->ProtoBitmap );
-    ExInitializeFastMutex( &PortSet->Mutex );
+    KeInitializeSpinLock( &PortSet->Lock );
     return STATUS_SUCCESS;
 }
 
 VOID PortsShutdown( PPORT_SET PortSet ) {
-    PoolFreeBuffer( PortSet->ProtoBitBuffer );
+    ExFreePoolWithTag( PortSet->ProtoBitBuffer, PORT_SET_TAG );
 }
 
 VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) {
+    KIRQL OldIrql;
+
     Port = htons(Port);
     ASSERT(Port >= PortSet->StartingPort);
     ASSERT(Port < PortSet->StartingPort + PortSet->PortsToOversee);
+
+    KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
     RtlClearBits( &PortSet->ProtoBitmap, Port - PortSet->StartingPort, 1 );
+    KeReleaseSpinLock( &PortSet->Lock, OldIrql );
 }
 
 BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port ) {
     BOOLEAN Clear;
+    KIRQL OldIrql;
 
     Port = htons(Port);
-    ASSERT(Port >= PortSet->StartingPort);
-    ASSERT(Port < PortSet->StartingPort + PortSet->PortsToOversee);
+
+    if ((Port < PortSet->StartingPort) ||
+        (Port >= PortSet->StartingPort + PortSet->PortsToOversee))
+    {
+       return FALSE;
+    }
+
     Port -= PortSet->StartingPort;
 
-    ExAcquireFastMutex( &PortSet->Mutex );
+    KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
     Clear = RtlAreBitsClear( &PortSet->ProtoBitmap, Port, 1 );
     if( Clear ) RtlSetBits( &PortSet->ProtoBitmap, Port, 1 );
-    ExReleaseFastMutex( &PortSet->Mutex );
+    KeReleaseSpinLock( &PortSet->Lock, OldIrql );
 
     return Clear;
 }
 
 ULONG AllocateAnyPort( PPORT_SET PortSet ) {
     ULONG AllocatedPort;
-    ULONG Next;
+    KIRQL OldIrql;
 
-    if (PortSet->StartingPort + PortSet->PortsToOversee <=
-        PortSet->LastAllocatedPort + 1) {
-       Next = PortSet->StartingPort;
-    } else {
-       Next = PortSet->LastAllocatedPort + 1;
-    }
-    Next -= PortSet->StartingPort;
-
-    ExAcquireFastMutex( &PortSet->Mutex );
-    AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, Next );
+    KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
+    AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, 0 );
     if( AllocatedPort != (ULONG)-1 ) {
        RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
        AllocatedPort += PortSet->StartingPort;
-       PortSet->LastAllocatedPort = AllocatedPort;
+       KeReleaseSpinLock( &PortSet->Lock, OldIrql );
+       return htons(AllocatedPort);
     }
-    ExReleaseFastMutex( &PortSet->Mutex );
-
-    AllocatedPort = htons(AllocatedPort);
-
-    ASSERT(AllocatedPort >= PortSet->StartingPort);
-    ASSERT(AllocatedPort < PortSet->StartingPort + PortSet->PortsToOversee);
+    KeReleaseSpinLock( &PortSet->Lock, OldIrql );
 
-    return AllocatedPort;
+    return -1;
 }
 
 ULONG AllocatePortFromRange( PPORT_SET PortSet, ULONG Lowest, ULONG Highest ) {
     ULONG AllocatedPort;
-    ULONG Next;
+    KIRQL OldIrql;
 
-    if (PortSet->StartingPort + PortSet->PortsToOversee <=
-        PortSet->LastAllocatedPort + 1) {
-       Next = PortSet->StartingPort;
-    } else {
-       Next = PortSet->LastAllocatedPort + 1;
+    if ((Lowest < PortSet->StartingPort) ||
+        (Highest >= PortSet->StartingPort + PortSet->PortsToOversee))
+    {
+        return -1;
     }
-    if (Next < Lowest || Highest <= Next) {
-       Next = Lowest;
-    }
-    Next -= PortSet->StartingPort;
+
     Lowest -= PortSet->StartingPort;
     Highest -= PortSet->StartingPort;
 
-    ExAcquireFastMutex( &PortSet->Mutex );
-    AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, Next );
-    if( AllocatedPort != (ULONG)-1 && AllocatedPort >= Lowest &&
-        AllocatedPort <= Highest) {
+    KeAcquireSpinLock( &PortSet->Lock, &OldIrql );
+    AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, Lowest );
+    if( AllocatedPort != (ULONG)-1 && AllocatedPort <= Highest) {
        RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
        AllocatedPort += PortSet->StartingPort;
-       PortSet->LastAllocatedPort = AllocatedPort;
+       KeReleaseSpinLock( &PortSet->Lock, OldIrql );
+       return htons(AllocatedPort);
     }
-    ExReleaseFastMutex( &PortSet->Mutex );
-
-    AllocatedPort = htons(AllocatedPort);
-
-    ASSERT(AllocatedPort >= PortSet->StartingPort);
-    ASSERT(AllocatedPort < PortSet->StartingPort + PortSet->PortsToOversee);
+    KeReleaseSpinLock( &PortSet->Lock, OldIrql );
 
-    return AllocatedPort;
+    return -1;
 }