ПредишенСледващото

Spinlock - прост механизъм синхронизация. заключване Spin може да бъде заловен. и освободен. Ако spinlock е придобито, допълнителен опит да вземете spinlock всеки поток ще доведе до безкраен цикъл, за да се опита да се обхване по-spinlock (зает чакащо състояние поток). Цикълът ще завърши едва когато бившият собственик на спин-ключалката я освободи. С помощта на заключване спин безопасно в многопроцесорни платформи, това означава, че се гарантира, че, дори ако това е поискано в същото време две нишки на два процесора, той улавя само един от потоците.
Spin ключалки са предназначени за защита на данните, достъпът до което се извършва в различни, включително повишени нива IRQL. А сега си представете следната ситуация: кодът, който работи на ниво IRQL PASSIVE_ НИВО взе заключване спин за последващо сейф смяна на някои данни. Кодът е била прекъсната код с по-висока IRQL DISPATCH_LEVEL, който се опита да улови една и съща ключалката въртене, а това от описанието на спин-ключалката, влиза в безкраен цикъл чака заключване освобождаване. Този цикъл никога няма да свърши, защото кода, който улавя spinlock и то трябва да бъде свободен, има по-ниска IRQL и никога не се отдаде възможност да се извърши! За такава ситуация не възниква, механизъм, който не позволява на кода с някакво ниво IRQL прекъсване код с по-ниска IRQL в момента, когато кода с по-ниска IRQL притежава spinlock. Един такъв механизъм е да се увеличи сегашното ниво в момента на залавянето IRQL spinlock IRQL до определено ниво, свързано с spinlock и възстановяването на стари ниво IRQL в момента на освобождаване. От това следва, че кодът работи при IRQL повишено ниво, които нямат право на достъп до защитено от спин-ключалката ресурс ако IRQL на ниво по-ниско ниво spinlocks IRQL производство на достъп до кода на ресурсите. Когато се опитате този код за улавяне на нивото на въртене заключване IRQL тя ще бъде намалена до spinlocks на ниво IRQL, които ще доведат до непредвидими последици.
В Новия Завет, има два вида съпътстващи брави:

  • Конвенционални спин-заключване, които са специален случай на непредвиден ключалката отмените I / O заявка, която се използва, за да се реди на опашка на I / O заявки (вж. "Отказ I / O искания" раздел).
  • Spinlocks прекъсва синхронизация.

С конвенционалните спин брави, свързани IRQL DISPATCH_LEVEL, а именно:

  • Всички опити да ги заснемат трябва да бъдат направени на ниво IRQL-малка или равна DISPATCH_LEVEL;
  • в случай на залавяне spinlock текущата ниво IRQL издига на DISPATCH_LEVEL на ниво.

С синхронизация спин-заключване прекъсне свързани един от нива DIRQL. Като се използват конвенционални заключване завъртане ще бъде описано по-долу (с изключение на заключване завъртане I затвори / O искания, които са описани в предишния раздел). Използване на прекъсване на спин-заключване синхронизация ще бъде описана в раздела, посветен на обработка на прекъсване.

Използването на конвенционален заключване спин

  1. 1. VOID KeInitializeSpinLock (IN PKSPIN_LOCK SpinLock); Тази функция инициализира KSPIN_LOCK ядро ​​обект. Памет за заключване на въртене трябва да бъдат разпределени на не-пейджъра памет.
    2. VOID KeAcquireSpinLock (IN PKSPIN_LOGK SpinLock, OUT PKIRQL Oldlrql); Тази функция улавя заключването на спин. Функцията не ще се върне към успеха на заключване. След завършване на ниво функция IRQL се издига до нивото на DISPATCH_LEVEL. Вторият параметър се връща IRQL ниво, което е за заснемане на заключване (той трябва да бъде <= DISPATCH_LEVEL).
    3. VOID KeReleaseSpinLock (IN PKSPINJLOCK SpinLock, OUT PKIRQL Newlrql); Тази функция изчиства спин-ключалката, и определя нивото IRQL стойност Newlrql параметъра. Това трябва да бъде стойността, върната от функция KeAcquireSpinLock () в параметър Oldlrql.
    4. VOID KeAcquireLockAtDpcLevel (IN PKSPIN_LOCK SpinLock); Тази оптимизирана функция улавя кода за спин-заключване, вече работи на ниво IRQL DISPATCH_LEVEL. В този случай, се изисква промяна на нивото на IRQL. На една платформа процесор, тази функция не прави нищо, защото синхронизацията се осигурява от най-IRQL архитектура.
    5. VOID KeReleaseLockFromDpcLevel (IN PKSPIN_LOCK SpinLock); Тази функция изчиства кода на спин-заключване на заключващото използване функция KeAcquireLockAtDpcLevel (). На една платформа процесор, тази функция не прави нищо.

Пример използват конвенционални съпътстващи брави:

typedef структура _DEVICE_EXTENSION
KSPIN_LOCK spinlock> DEVICE_EXTENSION, * PDEVICE_EXTENSION;
*
NTSTATUS DriverEntry (.)
KelnitializeSpinLock (extension-> spinlock);>
NTSTATUS DispatchReadWrite (.)
KIRQL Oldlrql;
KeAcquireSpinLock (extension-> spinlock, 01dlrql); // направи обработването на данни, защитени // spinlock
KeReleaseSpinLock (extension-> spinlock, Oldlrql);>

Deadlock Проблем (мъртвите зони)

Ако една нишка се опитва да вземете spinlock отново, то ще отиде в един безкраен цикъл чака - "виси". Подобна ситуация ще възникне, ако два потока се използват две spinlock. Поток 1 придобива бравата 1, като в същото време резба 2 придобива заключване 2. След това, поток 1 2 опита за заключване на бравата, и потока 2 - заключване 1. двата потока "виси". Тази ситуация може да бъде удължен до произволен брой теми, той е широко известен и се нарича безизходица (мъртвите зони).
Решението на този проблем е много проста. Всички ключалки, които могат да бъдат записани в същото време, включени в списъка в низходящ ред на честотата на използване. Ако е необходимо, залавянето на брави те трябва да бъдат заловени в реда, в който те се появяват в списъка. По този начин, ние сме създали една йерархия на ключалки.

Свързани статии

Подкрепете проекта - споделете линка, благодаря!