isolamento del codice paginabile

Non è possibile fare il paging di una routine che utilizza uno spin lock. Tuttavia, in alcuni casi è possibile isolare le operazioni che richiedono uno spin lock in una routine separata che non verrà inclusa nella sezione paginabile.

Si consideri ad esempio il frammento seguente:

//  PAGED_CODE(); 
 
KeInitializeEvent( &event, NotificationEvent, FALSE ); 
irp = IoBuildDeviceIoControlRequest( IRP_MJ_DEVICE_CONTROL, 
                                     DeviceObject, 
                                     (PVOID) NULL, 
                                     0, 
                                     (PVOID) NULL, 
                                     0, 
                                     FALSE, 
                                     &event, 
                                     &ioStatus ); 
if (irp) { 
   irpSp = IoGetNextIrpStackLocation( irp ); 
   irpSp->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL; 
   irpSp->MinorFunction = IRP_MN_LOAD_FILE_SYSTEM; 
   status = IoCallDriver( DeviceObject, irp ); 
   if (status == STATUS_PENDING) { 
   (VOID) KeWaitForSingleObject( &event, 
                                 Executive, 
                                 KernelMode, 
                                 FALSE, 
                                 (PLARGE_INTEGER) NULL ); 
   } 
} 

SPINLOCKUSE ! 
KeAcquireSpinLock( &IopDatabaseLock, &irql ); 
// Code inside spin lock ...

DeviceObject->ReferenceCount--; 
 
if (!DeviceObject->ReferenceCount && !DeviceObject->AttachedDevice) { 
   //Unload the driver
   .
   .
   . 
} else { 
   KeReleaseSpinLock( &IopDatabaseLock, irql ); 
} 

La routine precedente può essere resa paginabile (salvando circa 160 byte) spostando le poche righe di codice che fanno riferimento a un blocco di selezione in una routine separata.

Tenere inoltre presente che il codice driver non deve essere contrassegnato come pageable se chiama routine di supporto KeXxx , ad esempio KeReleaseMutex o KeReleaseSemaphore, in cui il parametro Wait è impostato su TRUE. Tale chiamata restituisce con IRQL in DISPATCH_LEVEL.