SyncMutexLock(), SyncMutexLock_r()

Захватить (блокировать) объект синхронизации

Прототип:

#include <sys/neutrino.h>
int SyncMutexLock( sync_t *sync );
int SyncMutexLock_r( sync_t *sync );

Аргументы:

sync
Указатель на объект синхронизации sync_t.

Библиотека:

libc

Описание:

Системные вызовы SyncMutexLock() и SyncMutexLock_r() пробуют захватить мьютекс sync. Если мьютекс сейчас не заблокирован вызов немедленно возвращает управление и владельцем мьютекса становится текущий процесс. Мьютекс считается разблокированным если поле owner в структуре sync равно 0. В противном случае поле owner рассматривается в качестве идентификатора потока – владельца мьютекса.

Эти функции эквивалентны, за исключением способа информирования об ошибках.


Note: POSIX-функции pthread_mutex_lock() и pthread_mutex_unlock() работают быстрее, поскольку они не во всех случаях приводят к системному вызову.

Если мьютексом владеет другой поток, вызывающий поток блокируется на мьютексе sync до его освобождения. Если ожидающих потоков более одного, то они организуются в очередь в порядке приоритетов.

Если приоритет блокированного потока выше приоритета потока-владельца мьютекса, приоритет последнего принудительно повышается до приоритета первого. Другими словами, в этом случае владелец наследует приоритет высокоприоритетного заблокированного потока. При освобождении владельцем мьютекса, его приоритет принудительно понижается до исходного. Таким образом функционирует протокол наследования приоритетов (PIP, Priority Inheritance Protocol) на уровне мьютексов. Стоит учитывать, что приоритет может повышаться более одного раза, если описанный сценарий повторяется многократно в рамках одной критической секции кода.

Если в рамках PIP поток самостоятельно меняет свой приоритет, то он немедленно применяется и становится тем уровнем приоритета, который используется для восстановления при освобождении мьютекса.

Ожидание на мьютексе не является точкой остановки потока. Если в момент ожидания на мьютексе в поток поступает сигнал, то его обработчик немедленно вызывается, но при выходе из него поток вновь оказывается ожидающим на мьютексе без явного прерывания блокировки.


Note: Избегайте таймаутов при использовании мьютексов. Мьютексы следует использовать для ограниченных по длительности критических секций, что само по себе позволяет отказаться от регистрации таймаутов.

Аргумент sync должен быть предварительно проинициализирован через вызов SyncTypeCreate() или статический инициализатор PTHREAD_MUTEX_INITIALIZER.

Состояния блокировки:

STATE_MUTEX
Вызывающий поток заблокирован в ожидании освобождения объекта синхронизации владельцем.

Возвращаемое значение:

SyncMutexLock()
Если возникла ошибка функция возвращает -1, код ошибки записывается в errno. Любое другое возвращенное значение считается успешным завершением.
SyncMutexLock_r()
EOK возвращается при успешном завершении. Функция НЕ устанавливает errno. При возникновении ошибки функция возвращает один из представленных ниже кодов.

Коды ошибок:

EAGAIN
При первом использовании статически инициализированного объекта sync все объекты синхронизации ядра уже используются.
EFAULT
Возникла ошибка при доступе ядра к объекту sync.
EINTR
Поток был разблокирован вызовом pthread_mutex_wakeup_np().
EINVAL
Объект синхронизации sync не существует.
ETIMEDOUT
Ожидание прервано таймаутом (см. TimerTimeout()).

Классификация:

ЗОСРВ «Нейтрино»

Точка остановки потока
Нет
Обработчик прерываний
Нет
Обработчик сигналов
Да
В потоке
Да

Тематические ссылки:

sync_t, pthread_mutex_lock(), pthread_mutex_unlock(), SyncTypeCreate(), SyncDestroy(), SyncMutexUnlock()




Предыдущий раздел: Описание API системной библиотеки