30.4.4. СЕМАФОРНЫЕ ОПЕРАЦИИ И БЛОКИРОВАНИЕ ШИНЫ




THIS SECTION IS UNDER CONSTRUCTION


Часто в мультипроцессорных системах реализовывать взаимоисключения на ресурсы. Например семафоры (флаги показывающие свободен ли доступ к ресурсу). Чтобы осуществить доступ к такому объекту нужна операция которая сначала бы читала его состояние, потом устанавливала бы новое, при этом никто не должен получить доступ к семафору в этот период. т.е. надо захватить шину на 2 или более циклов.


Semaphore N-арный семафор, служит для доступа к заданному числу однородных ресурсов Mutex Взаимоисключающий доступ к ресурсам


Для этого служит сигнал LOCK (захват шины). Как правило процессоры имею специальные команды для работы с семафорами которые делают нужные операции (ВНИМАНИЕ: обращение к семафорам должно идти напрямую в память а не быть проглощено cache (как при чтении, так при записи (WriteBack)). E.W.Dijkstra 1965 P(S) if S > 0 then S = S - 1 else wait on S V(S) if one or more processes waits on S then let one process proceed else S = S + 1 TODO: Расписать семафорные операции Interlocked functions Прибавить integer Присвоить integer Условно прибавить integer Условно присвоить integer Инкрементировать Декриментировать x86: LOCK XCHG dest,src Lock Bus temp = dest; dest = src; src = temp; Unlock Bus LOCK XADD dest,src Lock Bus temp = dest + src; src = dest; dest = temp; Unlock Bus LOCK CMPXCHG dest,src Lock Bus if (acc == dest) { ZF = 1; dest = src; } else { ZF = 0; acc = dest; } Unlock Bus LOCK BTS dest, bitn Lock Bus CF = Bit{dest,bitn}; Bit{dest,bitn} = 1; Unlock Bus LOCK BTR dest, bitn Lock Bus CF = Bit{dest,bitn}; Bit{dest,bitn} = 0; Unlock Bus On x86 LOCK prefix may used with next instructions: ADD, ADC, AND, BTC, BTR*, BTS*, CMPXCHG*, CMPXCHG8B*, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD*, XCHG* (* помечены операции с помощью которых можно реализовать мьютексы). Есть и другой подход когда специальной командой включают LOCK на время всех остальных операций, а потом выключают. Плюсы: можно реализовать сложную семафорную логику. Минусы: так очень долго можно держать шину, а если забыть выключить LOCK, то даже вечно. Понятно, что это убъет bus-mastering устройства ввода/вывода и другие процессоры.


Mutex: Без LOCK шины - облом:



С LOCK шины:

Захват мьютекса называется - Acquire Освобождение мьютекса называется - Release ------------------------------------------------------- mutex dd 0 ; Mutex in memory acquire: mov eax,1 lock xchg eax, mutex or eax,eax jz ok jmp acquire ; Spin-Lock ok: .... release: lock mov mutex, 0 ; LOCK - потому что может быть не выровненный ... ; адресс ------------------------------------------------------- На базе мьютекса можно легко делать семафоры. Просто код который изменяет счетчик семафора должен быть защищен мьютексом. Например семафор на 5: ------------------------------------------------------- Data: mutex count Acquire(semaphore): Acquire(mutex) if (count > 5) { Release(mutex) return FAILED } count = count + 1; Release(mutex) return SUCCESS Release(semaphore) Acquire(mutex) count = count - 1; Release(mutex) -------------------------------------------------------


В принципе в однопроцессорной системе можно не заморачиватся а просто запретить прерывания на время выполнения атомарной операции (если конечно семафор не испульзуется каким нибудь hardware).


Spin-Lock пытаемся поставить мьютекс в цикле пока не поставим.



Наметилась тенденция к тому что стали появляться команды которые тянут время до обращения к семафору, иначе постоянный опрос просто убивает шину. Идея простая: зная адресс семафора мы можем его мониторить по шине, и не делать на ней операции. MWAIT MONITOR


Index Prev Next