Эта глава поддерживается проектом FreeBSD SMP Next Generation Project <freebsd-smp@FreeBSD.org>.
Этот документ описывает механизм блокировки, используемый в ядре FreeBSD для обеспечения эффективной поддержки нескольких процессоров в ядре. Блокировку можно рассматривать с нескольких точек зрения. Структуры данных могут быть защищены с помощью блокировок mutex или lockmgr(9). Несколько переменных защищены просто в силу атомарности используемых для доступа к ним операций.
Мьютекс (mutex) - это просто блокировка, используемая для реализации гарантированной исключительности. В частности, в каждый момент времени мьютексом может владеть только один объект. Если какой-то объект хочет получить мьютекс, который уже кто-то занял, он должен дождаться момента его освобождения. В ядре FreeBSD владельцами мьютексов являются процессы.
Мьютексы могут быть затребованы рекурсивно, но предполагается, что они занимаются на короткое время. В частности, владельцу мьютекса нельзя выдерживать паузу. Если вам нужно выполнить блокировку на время паузы, используйте блокировку через lockmgr(9).
Каждый мьютекс имеет несколько представляющих интерес характеристик:
Имя переменной struct mtx в исходных текстах ядра.
Имя мьютекса, назначенное ему через mtx_init. Это имя выводится в сообщениях трассировки KTR и диагностических предупреждающих и ошибочных сообщениях и используется для идентификации мьютексов в отладочном коде.
Тип мьютекса в терминах флагов MTX_*. Значение каждого флага связано с его смыслом так, как это описано в mutex(9).
Sleep-мьютекс
Spin-мьютекс
Этот мьютекс инициализируется очень рано. Поэтому он должен быть объявлен через функции MUTEX_DECLARE, а флаг MTX_COLD должен быть передан в функцию mtx_init.
Этот spin-мьютекс не запрещает прерывания.
Этот мьютекс не разрешается блокировать рекурсивно.
Список структур данных или членов структур данных, которые защищает этот мьютекс. Для членов структур данных иям будет в форме имя структуры.имя члена структуры.
Функции, которые можно вызвать, если этот мьютекс занят.
Table 10-1. Список мьютексов
Имя переменной | Логическое имя | Тип | Защиты | Зависимые функции |
---|---|---|---|---|
sched_lock | "sched lock" | MTX_SPIN | MTX_COLD | _gmonparam, cnt.v_swtch, cp_time, curpriority, mtx.mtx_blocked, mtx.mtx_contested, proc.p_contested, proc.p_blocked, proc.p_flag (P_PROFIL XXX, P_INMEM, P_SINTR, P_TIMEOUT, P_SWAPINREQ XXX, P_INMEN XXX), proc.p_nice, proc.p_procq, proc.p_blocked, proc.p_estcpu, proc.p_nativepri, proc.p_priority, proc.p_usrpri, proc.p_rtprio, proc.p_rqindex, proc.p_stats->p_prof, proc.p_stats->p_ru, proc.p_stat, proc.p_cpticks proc.p_iticks, proc.p_uticks, proc.p_sticks, proc.p_swtime, proc.p_slptime, proc.p_runtime, proc.p_pctcpu, proc.p_oncpu, proc.p_asleep, proc.p_wchan, proc.p_wmesg, proc.p_slpq, proc.p_vmspace (XXX - в statclock), pscnt, slpque, itqueuebits, itqueues, rtqueuebits, rtqueues, queuebits, queues, idqueuebits, idqueues, switchtime, | setrunqueue, remrunqueue, mi_switch, chooseproc, schedclock, resetpriority, updatepri, maybe_resched, cpu_switch, cpu_throw |
vm86pcb_lock | "vm86pcb lock" | MTX_DEF | MTX_COLD | vm86pcb | vm86_bioscall |
Giant | "Giant" | MTX_DEF | MTX_COLD | nearly everything | lots |
callout_lock | "callout lock" | MTX_SPIN | callfree, callwheel, nextsoftcheck, proc.p_itcallout, proc.p_slpcallout, softticks, ticks |