Złożone instrukcje atomowe (testsset, exchange)

Operacja test&set


Atomowo wykonywana operacja test & set polega na odczytaniu dotychczasowej wartości zmiennej logicznej (w praktyce jakiegoś bitu), a następnie ustawieniu wartości tej zmiennej na true. Jeśli wartość była już true, wykonanie operacji niczego nie zmieni.

W systemie jednoprocesorowym efekt atomowości (niepodzielności) można uzyskać poprzez zablokowanie przerwań na czasy wykonywania operacji. W implementacji musiałyby się zatem znaleźć rozkazy blokowania przerwań na początku i odblokowania na końcu, właściwe dla danej architektury.

W architekturze IA-32 (Intel) tego typu operacje realizowane są na poziomie maszynowym przez rozkazy: bts, btr, btc, poprzedzone ewentualnie prefiksem lock.

slajd 31

Operacja exchange


Atomowo wykonywana operacja exchange polega na zamianie wartości dwóch zmiennych logicznych. Podobnie, jak w przypadku test & set, w systemie jednoprocesorowym efekt atomowości operacji można uzyskać poprzez zablokowanie przerwań na czas jej wykonywania.

W architekturze IA-32 (Intel) operacja exchange realizowana jest na poziomie maszynowym przez rozkaz: xchg, dotyczy jednak nie bitów a zawartości całych rejestrów. Pewnym ograniczeniem jest fakt, że jeden z operandów musi być w rejestrze procesora, ale nie przeszkadza to np. w zastosowaniu tego. rozkazu do rozwiązania problemu wzajemnego wykluczania. Jeśli któryś z operandów rozkazu xchg jest w pamięci, następuje blokada magistrali niezależnie od użycia prefiksu lock.

slajd 32

Wzajemne wykluczanie z użyciem instrukcji test&set


Rozwiązanie polega na wykorzystaniu współdzielonej zmiennej zamek, której wartość true oznacza zajętość sekcji krytycznej.

Na zmiennej wykonywana jest operacja test & set , która ustawia true (być może ponownie) i zwraca poprzednią wartość zmiennej. Jeśli poprzednia wartość była false, to znaczy, że w sekcji krytycznej nie było żadnego procesu i może ona zostać zajęta. W przeciwnym przypadku nie nastąpiła zmiana wartości zmiennej zamek (było true i jest nadal true), a jedynie ustalenie wartości tej zmiennej. Z wartości tej wynika oczywiście, że sekcja krytyczna jest zajęta i należy dalej kontynuować wykonywanie pętli while.

Taki algorytm może być stosowany dla dowolnej liczby współpracujących procesów. Nie gwarantuje on jednak ograniczonego czekania, gdyż nie ma żadnej pewności, że konkretny proces będzie mógł wykonać na swoje potrzeby operację test & set akurat wówczas, gdy zmienna zamek będzie miała wartość false.

slajd

Wzajemne wykluczanie z użyciem instrukcji exchange


Rozwiązanie z użyciem procedury exchange jest bardzo podobne. Wykorzystywana jest jednak dodatkowa zmienna lokalna klucz. Wartość zmiennej klucz zamieniana jest z wartością zmiennej zamek. Ponieważ na początku sekcji wejściowej pod klucz podstawiana jest wartość true, ta wartość trafia następnie do zmiennej zamek. Z zamka do klucza trafia z kolei dotychczasowa wartość zamka. Jeśli wartość ta jest false, można przerwać pętlę repeat - until i wejść do sekcji krytycznej. Jeśli wartością tą jest true, wykonanie operacji exchange niczego nie zmieni, a za pośrednictwem klucza proces dowie się, że sekcja krytyczna jest niedostępna.

Z realizacją wzajemnego wykluczania w taki sposób wiążą się te same kwestie, które poruszono przy rozwiązaniu z użyciem test & set.

slajd 34