Программирование DSP VDK: API мьютексов Tue, October 08 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

VDK: API мьютексов Печать
Добавил(а) microsin   

Перевод документации по функциям мьютексов из даташита [1]. Подробную информацию про поведение семафоров, мьютексов и потоков VDK см. [2].

[AcquireMutex]

// Прототип C:
void VDK_AcquireMutex(VDK_MutexID inMutexID);
 
// Прототип C++:
void VDK::AcquireMutex(VDK::MutexID inMutexID);

Предоставляет механизм, позволяющий потоку захватывать мьютекс (становиться его владельцем).

Когда мьютекс создан (см. далее CreateMutex), у него нет владельца. Если поток пытается завладеть (acquire) мьютексом, и у мьютекса нет владельца, то он становится владельцем мьютекса, и управление выполнением кода переходит к работающему (running) потоку. Иначе поток блокируется на ожидании освобождения мьютекса.

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

В библиотеке VDK мьютексы рекурсивные, что позволяет делать вложенные вызовые AcquireMutex(). Это значит, что мьютекс может быть захвачен его же владельцем несколько раз. Владение мьютексом освобождается только когда ReleaseMutex (см. далее) будет вызван по одному разу на каждый захват мьютекса. В этот момент мютекст становится доступным для всех потоков, и может быть захвачен без самым высокоприоритетным потоком, претендующим на мьютекс, без остановки выполнения.

Параметры:

inMutexID идентификатор мьютекса типа MutexID (см. далее "Типы данных"), которым поток пытается завладеть.

Влияние на планировщик: запускает планировщик, и может привести к переключению контекста.

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

Обработка ошибок поддерживается только для библиотек с функционалом full instrumentation и error-checking:

kInvalidMutexID показывает, что inMutexID не мьютекс, созданный вызовом API-функции CreateMutex.

kDbgPossibleBlockInRegion показывает, что функция AcquireMutex была вызвана в необслуживаемом (unscheduled) регионе кода [3], что потенциально приводит к конфликту планировщика.

kBlockInInvalidRegion показывает, что AcquireMutex пытается выполнить блокировку потока в необслуживаемом регионе, что приводит к конфликту планировщика ("мертвая" блокировка, deadlock).

kInvalidMutexOwner показывает, что владелец мьютекса был уничтожен, и мьютекс никогда не станет доступным.

[CreateMutex]

// Прототип C:
VDK_MutexID VDK_CreateMutex(void);
 
// Прототип C++:
VDK::MutexID VDK::CreateMutex(void);

Создает и инициализирует объект нового мьютекса, который может использоваться для взаимного исключения потоков (mutual exclusion). Возвращаемое значение - идентификатор нового мьютекса. Когда мьютекс создан, у него нет владельца. Если поток хочет захватить владение мьютексом, он должен вызывать AcquireMutex.

Влияние на планировщик: не запускает планировщик.

Детерминизм: функция выполняется неопределенное время.

Возвращаемое значение: новый MutexID в случае успеха и UINT_MAX в случае ошибки.

Обработка ошибок поддерживается только для библиотек с функционалом full instrumentation и error-checking:

kMutexCreationFailure показывает, что ядро RTOS (VDK kernel) не может выделить и/или инициализировать память для мьютекса.

[DestroyMutex]

// Прототип C:
void VDK_DestroyMutex (VDK_MutexID inMutexID);
 
// Прототип C++:
void VDK::DestroyMutex (VDK::MutexID inMutexID);

Уничтожает мьютекс, связанный с идентификатором inMutexID, и освобождает память, связанную с этим мьютексом. Уничтожение мьютекса не произойдет, если мьютексом владеет какой-либо поток, потому что могут существовать потоки, ожидающие освобождения мьютекса. В этом случае произойдет ошибка, которая будет обработана, если применяется сборка с поддержкой библиотек full instrumentation и error-checking.

Параметры:

inMutexID значение идентификатора мьютекса, который должен быть удален.

Влияние на планировщик: не запускает планировщик.

Детерминизм: функция выполняется неопределенное время.

Обработка ошибок поддерживается только для библиотек с функционалом full instrumentation и error-checking:

kInvalidMutexID показывает, что inMutexID не мьютекс, созданный вызовом API-функции CreateMutex.

kMutexDestructionFailure показывает, что мьютекс не может быть уничтожен, потому что у него есть владелец, и могут существовать другие потоки, ожидающие освобождения этого мьютекса.

[ReleaseMutex]

// Прототип C:
void VDK_ReleaseMutex (VDK_MutexID inMutexID);
 
// Прототип C++:
void VDK::ReleaseMutex (VDK::MutexID inMutexID);

Предоставляет механизм, с помощью которых потоки освобождают мьютекс (перестают быть его владельцем).

Когда поток больше не нуждается во владении мьютексом, он может освободить (release) этот мьютекс вызовом ReleaseMutex. Мьютексы RTOS VDK рекурсивные, и могут быть захвачены своим же владельцем несколько раз без блокировки, с помощью вложенных вызовов AcquireMutex. Мьютекс освобождается только тогда, когда была вызвана API-функция ReleaseMutex столько же раз, сколько ранее мьютекс был захвачен вложенными вызовами AcquireMutex. В момент последнего освобождения мьютекса вызовом ReleaseMutex мьютекс становится доступным для всех потоков, и может быть захвачен одним из потоков без его приостановки.

Замечание: вызов ReleaseMutex приведет к ошибке, если вызвавший ReleaseMutex поток не владеет запрашиваемым мьютексом.

Параметры:

inMutexID значение идентификатора мьютекса, который должен быть освобожден.

Влияние на планировщик: запускает планировщик, и может привести к переключению контекста.

Детерминизм:

• Вызов ReleaseMutex() не меняет текущий работающий поток (нет переключения контекста): постоянное время.
• Вызов ReleaseMutex() меняет текущий работающий поток (переключение контекста): постоянное время плюс время на переключение контекста.

Обработка ошибок поддерживается только для библиотек с функционалом full instrumentation и error-checking:

kInvalidMutexID показывает, что inMutexID не мьютекс, созданный вызовом API-функции CreateMutex.

kMutexNotOwned показывает, что мьютекс не был захвачен каким-либо потоком, и поэтому не может быть освобожден.

kNotMutexOwner показывает, что этим мьютексом владеет другой поток.

[Типы данных]

MutexID

Тип MutexID используется для хранения уникального идентификатора мьютекса.

enum MutexID
{
   /* Определяется IDDE в хедере VDK.h. */
};

Перечисление в VDK.h пустое. Все мьютексы выделяются динамически, и получают свои ID типа MutexID, чтобы компилятор мог произвести проверку типов без возникновения ошибок.

// Определение типа на C:
typedef enum MutexID VDK_MutexID;
 
// Определение типа на C++:
typedef enum MutexID VDK::MutexID;

[Ссылки]

1. VisualDSP++ 5.0 Kernel (VDK) User’s Guide site:analog.com.
2. VDK: сигналы, взаимодействие потоков и ISR (синхронизация).
3. Специфика использования VDK для процессоров Blackfin.
4. VDK: API семафоров.
5VDK: API сообщений.
6Чем отличается мьютекс от семафора?

 

Добавить комментарий


Защитный код
Обновить

Top of Page