Seqlock

En seqlock (förkortning för sekvenslås ) är en speciell låsmekanism som används i Linux för att stödja snabb skrivning av delade variabler mellan två parallella operativsystemrutiner . Semantiken stabiliserades från och med version 2.5.59, och de finns i 2.6.x-serien med stabil kärna. Seqlocks utvecklades av Stephen Hemminger och kallades ursprungligen frlocks, baserat på tidigare arbete av Andrea Arcangeli. Den första implementeringen var i x86-64-tidskoden där det behövdes synkroniseras med användarutrymme där det inte gick att använda ett riktigt lås.

Det är en läsare-författare konsekvent mekanism som undviker problemet med författaresvält . Ett seqlock består av lagring för att spara ett sekvensnummer utöver ett lås. Låset ska stödja synkronisering mellan två skribenter och räknaren är till för att indikera konsistens hos läsare. Förutom att uppdatera de delade data, ökar skribenten sekvensnumret, både efter att ha hämtat låset och innan låset släpps. Läsare läser sekvensnumret före och efter att ha läst de delade data. Om sekvensnumret är udda vid något tillfälle, hade en författare tagit låset medan data lästes och det kan ha ändrats. Om sekvensnumren är olika har en skribent ändrat data medan den lästes. I båda fallen försöker läsarna helt enkelt igen (med en loop) tills de läser samma jämna sekvensnummer före och efter.

Läsaren blockerar aldrig, men den kan behöva försöka igen om en skrivning pågår; detta snabbar upp läsarna i de fall data inte ändrades, eftersom de inte behöver skaffa låset som de skulle med ett traditionellt läs-skrivlås. Författare väntar inte heller på läsarna, medan de gör det med traditionella läs-skriv-lås, vilket leder till potentiell resurssvält i en situation där det finns ett antal läsare (eftersom författaren måste vänta tills det inte finns några läsare). På grund av dessa två faktorer är seqlocks mer effektiva än traditionella läs-skriv-lås för situationen där det finns många läsare och få skribenter. Nackdelen är att om det är för mycket skrivaktivitet eller om läsaren är för långsam, kan de få liv (och läsarna kan svälta).

Tekniken fungerar inte för data som innehåller pekare, eftersom vilken författare som helst kan ogiltigförklara en pekare som en läsare redan har följt. Att uppdatera minnesblocket som pekas på är bra med hjälp av seqlocks, men att uppdatera själva pekaren är inte tillåten. I ett fall där själva pekarna måste uppdateras eller ändras, är synkronisering av läs-kopia-uppdatering att föredra.

Detta användes först för uppdatering av systemtidsräknare. Varje tidsavbrott uppdaterar tiden på dygnet; det kan finnas många läsare av tiden för intern användning och applikationer i operativsystemet, men skrivningar är relativt sällsynta och sker bara en i taget. BSD-tidsräknarkoden verkar till exempel använda en liknande teknik.

En subtil fråga med att använda seqlocks för en tidsräknare är att det är omöjligt att gå igenom det med en debugger. Försök igen logiken kommer att utlösas hela tiden eftersom debuggern är tillräckligt långsam för att få läsloppet att alltid inträffa.

Se även