Программирование DSP VDK: потоки Thu, January 19 2017  

Поделиться

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

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

VDK: потоки Печать
Добавил(а) microsin   

Потоки в RTOS VDK отвечают за основной функционал приложения. В них заключается обработка всех алгоритмов программы. Ниже в таблицах приведен список API-функций VDK, которые относятся к созданию, управлению поведением, конфигурированию и удалению потоков.

Таблица 5-9. Функции для создания и удаления потоков.

Имя функции Описание
CreateThread() Создание потока определенного ранее типа.
CreateThreadEx() Расширенное создание потока, позволяющее передать в поток некоторые параметры и настроить свойства потока по умолчанию.
CreateThreadEx2() То же самое, что и предыдущая функция, но она также позволяет расширять функционал при создании потока, что может быть использовано для обработки новых параметров потока, которые возможно появятся в будущих релизах VDK.
DestroyThread() Уничтожение потока.
FreeDestroyedThreads() Освобождение ресурсов уничтоженных потоков.

Таблица 5-10. Функции управления локальным хранилищем потока.

Имя функции Описание
AllocateThreadSlot() Выделяет слот хранилища потока.
AllocateThreadSlotEx() То же самое, что и AllocateThreadSlot, отличие только в том, что предоставляется дополнительная функция очистки хранилища.
FreeThreadSlot() Освобождает слот.
GetThreadSlotValue() Вернет значение из слота хранилища потоков.
SetThreadSlotValue() Установит значение в слоте хранилища потока.

Таблица 5-11. Функции обработки ошибок потока.

Имя функции Описание
ClearThreadError() Сбрасывает состояние ошибки потока.
DispatchThreadError() Переводит поток в состояние ошибки и запускает функцию обработки ошибки потока.
GetLastThreadError() Вернет информацию о последней ошибке потока.
GetLastThreadErrorValue() Вернет значение, связанное с последней ошибкой потока.
SetThreadError() Установит состояние ошибки потока.

Таблица 5-12. Функции управления приоритетом потока.

Имя функции Описание
GetPriority() Запрашивает текущий приоритет потока.
ResetPriority() Сбрасывает приоритет потока в его значение по умолчанию.
SetPriority() Устанавливает текущий приоритет потока.

Таблица 5-13. Функции, влияющие на планировщик.

Имя функции Описание
Sleep() Приостанавливает поток на время, указанное в тиках системы, освобождая контекст для других потоков.
Yield() Уступает процессорное время для других потоков.

[Функции создания и удаления потоков]

Прототип C:

VDK_ThreadID VDK_CreateThread (VDK_ThreadType inType);

Прототип C++:

VDK::ThreadID VDK::CreateThread (VDK::ThreadType inType);

Создает поток указанного типа (типы потоков создаются на этапе конфигурирования проекта VDK, закладка Kernel -> Threads -> Thread Types) и возвратит новый поток. API-функция CreateThread() не должна быть вызвана из конструктора потока.

[Параметры]

inType константа типа потока ThreadType, которая автоматически определена в файле VDK.h (см. enum ThreadType) и используется в файле VDK.cpp (файлы VDK.h и VDK.cpp автоматически генерируются системой VisualDSP++). Эти файлы содержат такие настройки типа потока, как значение по умолчанию для размера стека потока, начальный приоритет потока и другие свойства.

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

Время выполнения функции не определено.

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

Новый идентификатор потока ThreadID при успешном завершении и UINT_MAX в случае ошибки.

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и при использовании библиотек проверки ошибок:

kUnknownThreadType показывает, что inType не элемент типа ThreadType, как это определено в VDK.h.

kThreadCreationFailure показывает, что ядро не может выделить и/или инициализировать память для потока.

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

Прототип C:

VDK_ThreadID VDK_CreateThreadEx (VDK_ThreadCreationBlock *inOutTCB);

Прототип C++:

VDK::ThreadID VDK::CreateThreadEx (VDK::ThreadCreationBlock *inOutTCB);

Создает поток с указанными характеристиками и возвратит новый поток. API-функция CreateThreadEx() не должна быть вызвана из конструктора потока.

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

Время выполнения функции не определено.

[Параметры]

inOutTCB указатель на структуру данных типа ThreadCreationBlock (см. врезку с описанием типа ThreadCreationBlock).

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

Новый идентификатор потока ThreadID при успешном завершении и UINT_MAX в случае ошибки.

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и с библиотеками обработки ошибок:

kUnknownThreadType показывает, что inType не элемент типа ThreadType, как это определено в VDK.h.

kThreadCreationFailure показывает, что ядро не может выделить и/или инициализировать память для потока.

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

Прототип C:

VDK_ThreadID VDK_CreateThreadEx2 (VDK_ThreadCreationBlock *inOutTCB,
                                  unsigned int inFieldsRequired);

Прототип C++:

VDK::ThreadID VDK::CreateThreadEx2 (VDK::ThreadCreationBlock *inOutTCB,
                                    unsigned int inFieldsRequired); 

CreateThreadEx2() доступна в VisualDSP++ 5.0 update 9 и более поздней версии. Это API работает только для процессоров Blackfin и SHARC.

Создает поток с указанными характеристиками и возвратит новый поток.

Когда создается новый поток с использованием CreateThreadEx2(), аргумент inFieldsRequired указывает, какие параметры по умолчанию потока типа ThreadType будут переназначены значениями из *inOutTCB.

Каждому полю в inOutTCB поставлено в соответствие бит в inFieldsRequired. Если бит установлен (1), то содержимое соответствующего поля будет использоваться при создании потока. Если же бит в inFieldsRequired очищен (0), то соответствующий бит в inOutTCB будет игнорироваться, и будет использоваться значение по умолчанию для этого параметра.

VDK предоставляет перечисление (enum) TCBBitfield, в котором есть имена для различных бит, которые можно выставить в inFieldsRequired. Эти флаги, предоставленные в перечислении, могут быть объединены операцией OR друг с другом, чтобы указать несколько параметров для изменения.

Когда создается поток с использованием ThreadType (который определен на закладке Kernel), Вы должны передать флаг kSetThreadTemplateID в inFieldsRequired.

На процессорах Blackfin библиотека VDK использует стек потока для сохранения информации контекста потока. Когда для приложения Blackfin размер стека задается вручную, убедитесь, что область выделенной памяти для стека достаточно велика, чтобы уместить в себе эту информацию. Т. е. размер выделенной памяти под стек должен быть не меньше (размер стека + размер области контекста). API-вызов функции GetContextRecordSize() может использоваться для определения размера области контекста.

API-функция CreateThreadEx() не должна быть вызвана из конструктора потока. Функция запускает планировщик и может привести к переключению контекста.

Время выполнения функции не определено.

[Параметры]

inOutTCB указатель на структуру данных типа ThreadCreationBlock (см. врезку с описанием типа ThreadCreationBlock).

inFieldsRequired задает те поля в структуре ThreadCreationBlock, которые будут использоваться для замену параметров по умолчанию для ThreadType. Для списка допустимых флагов, которые могут быть переданы в этом параметре, см. описание типа данных TCBBitfield (далее в соответствующей врезке).

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

Новый идентификатор потока ThreadID при успешном завершении и UINT_MAX в случае ошибки.

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и с библиотеками обработки ошибок:

kIncompatibleArguments показывает одно из следующего.

• В inFieldsRequired не было указано ни kSetThreadTemplateID, ни kSetThreadTemplatePointer.
• В inFieldsRequired были указаны оба kSetThreadTemplateID и kSetThreadTemplatePointer.
• В inFieldsRequired были указаны оба kSetThreadStackPointer и kSetStackHeap.
• В inFieldsRequired был указан kSetThreadStackPointer, но не был указан kSetThreadStackSize.

kInvalidPointer показывает одно из следующего.

• inOutTCB—>stack_pointer выровнен некорректно. Эта ошибка проверяется, когда в inFieldsRequired указан kSetThreadStackPointer.
• inOutTCB—>pTemplate равен NULL, и в inFieldsRequired указан kSetThreadTemplatePointer.

kUnknownThreadType показывает, что inType не элемент типа ThreadType, как это определено в VDK.h (на закладке Kernel не был задан соответствующий тип потока).

kThreadCreationFailure показывает, что ядро не может выделить и/или инициализировать память для потока.

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

Прототип на языке C:

void VDK_DestroyThread (VDK_ThreadID inThreadID,
                        bool inDestroyNow);

Прототип на языке C++:

void VDK::DestroyThread (VDK::ThreadID inThreadID,
                         bool inDestroyNow);

Инициирует процесс уничтожения потока из системы VDK. Хотя планировщик никогда больше не запустит удаленный поток после того, как эта функция завершится, ядро может опционально отложить освобождение памяти, выделенной для уничтоженного потока до момента времени, когда запустится поток ожидания (Idle thread). Любые ссылки на уничтоженный поток будут недопустимыми, и могут привести к диспетчеризации ошибки. Дополнительную информацию по поводу потока ожидания см. в разделе "Поток фонового ожидания (Idle Thread)".

Функция влияет на поведение планировщика и может привести к переключению контекста только если поток уничтожает сам себя (т. е. сам вызвал DestroyThread()).

Время выполнения функции всегда одинаково, если inDestroyNow задано в FALSE, иначе время выполнения не определено.

[Параметры]

inThreadID имеет тип ThreadID и задает поток, который должен быть удален из системы.

inDestroyNow показывает, должен ли ресурсы в памяти потока быть освобождены немедленно (если TRUE) или отложены на поток ожидания с самым низким приоритетом (если FALSE).

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и с библиотеками обработки ошибок:

kInvalidThreadпоказывает, что сделана попытка уничтожить поток ожидания (Idle Thread).

kUnknownThreadType показывает, что inType не элемент типа ThreadType, как это определено в VDK.h (на закладке Kernel не был задан соответствующий тип потока).

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

Прототип на языке C:

void VDK_FreeDestroyedThreads (void);

Прототип на языке C++:

void VDK::FreeDestroyedThreads (void);

Освобождает память, которая удерживается уничтоженными потоками, которые еще не были освобождены потоком ожидания (Idle thread). Дополнительную информацию по поводу потока ожидания см. в разделе "Поток фонового ожидания (Idle Thread)".

Функция не влияет на поведение планировщика. Время выполнения функции не определено. Обработка ошибок функции не предусмотрена.

[Функции управления локальным хранилищем потока]

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

Для этой цели доступно 8 слотов локального хранилища потока. Перед тем, как значение будет сохранено в соответствующем слоте таблицы слотов потока, должна быть выделена запись в глобальной таблице слотов путем вызова функции AllocateThreadSlot() или AllocateThreadSlotEx(). Если слот доступен в глобальной таблице, то соответствующий слот также резервируется в каждой таблице слотов потока. Эти вызовы API вернут FALSE, если нет доступных свободных слотов. Выделенная запись в глобальной таблице слотов может быть впоследствии освобождена вызовом FreeThreadSlot(). Этот механизм для выделения слотов предоставляет единовременную инициализацию слотов для специфических данных потока, предназначенных для библиотечных функций. Слоты выделяются в каждой таблице слотов потока при первом вызове библиотечной функции любым потоком.

Как только слот был выделен в глобальной таблице слотов, соответствующее значение в таблице слотов отдельного потока может быть установлено вызовом SetThreadSlotValue() из рассматриваемого потока. Значение типа void * может быть использовано для сохранения целого числа или указателя на выделенную память. Использование AllocateThreadSlotEx() для выделения слота позволяет спецификацию функции очистки, которая может быть вызвана при уничтожении потока, чтобы она правильно обработала динамически выделенную память, связанную со слотом потока. И наконец, GetThreadSlotValue() может использоваться для получения значения, сохраненного в таблице слотов отдельного потока.

Прототип на языке C:

bool VDK_AllocateThreadSlot (int *ioSlotNum);

Прототип на языке C++:

bool VDK::AllocateThreadSlot (int *ioSlotNum);

Назначит новый номер слота, если *ioSlotNum = VDK::kTLSUnallocated, и введет выделенный *ioSlotNum в глобальную таблицу идентификаторов слотов.

• Вернет немедленно FALSE, если значение *ioSlotNum не равно VDK::kTLSUnallocated (INT_MIN), чтобы защититься от нескольких попыток выделить одну и ту же ключевую переменную.

• Вернет FALSE, если нет свободных слотов, и если *ioSlotNum все еще VDK::kTLSUnallocated.

• Иначе выделит первый доступный слот, поместит номер слота в *ioSlotNum, и вернет TRUE.

• Не влияет на изменение состояния ни одного потока.

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

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

• Эквивалентно вызову AllocateThreadSlot() с NULL функцией очистки.

Функция не влияет на поведение планировщика. Время выполнения функции не определено.

[Параметры]

ioSlotNum указатель на идентификатор слота.

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

Функция вернет TRUE в случае успеха, иначе вернет FALSE.

Прототип на языке C:

bool VDK_AllocateThreadSlotEx (int *ioSlotNum,
                               void(*cleanupFn)(void*));

Прототип на языке C++:

bool VDK::AllocateThreadSlotEx (int *ioSlotNum,
                                void(*cleanupFn)(void*));

Назначит новый номер слота, если *ioSlotNum = VDK::kTLSUnallocated, и введет выделенный *ioSlotNum в глобальную таблицу идентификаторов слотов.

• Вернет немедленно FALSE, если значение *ioSlotNum не равно VDK::kTLSUnallocated (INT_MIN), чтобы защититься от нескольких попыток выделить одну и ту же ключевую переменную.

• Вернет FALSE, если нет свободных слотов, и если *ioSlotNum все еще VDK::kTLSUnallocated.

• Иначе выделит первый доступный слот, поместит номер слота в *ioSlotNum, и вернет TRUE.

• Не влияет на изменение состояния ни одного потока.

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

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

Функция не влияет на поведение планировщика. Время выполнения функции не определено.

[Параметры]

ioSlotNum указатель на идентификатор слота.

cleanupFn указатель на функцию для очистки специфичных для потока данных в событии удаления потока и:

• Может быть равно NULL, в этом случае функция очистки не будет вызвана.
• Вызывается из DestroyThread().
• Выполняется в контекста вызвавшего потока, но не того потока, который уничтожается.
• Вызывается только когда значение слота не NULL.
• Функция free() может использоваться как функция очистки, где слот используется для хранения данных, память под которые выделена через malloc().

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

Функция вернет TRUE в случае успеха, иначе вернет FALSE.

Прототип на языке C:

bool VDK_FreeThreadSlot (int inSlotNum);

Прототип на языке C++:

bool VDK::FreeThreadSlot (int inSlotNum);

Освобождает и очищает запись в таблице слотов текущего работающего потока, связанную с inSlotNum, и:

• Вернет FALSE, если (и только в этом случае, если) ключ не идентифицирует текущий выделенный слот.
• Освобождает слот, идентифицируемый через inSlotNum, который был ранее создан вызовом функции AllocateThreadSlot().

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

Функция не влияет на поведение планировщика. Время выполнения функции всегда одинаковое. Обработка ошибок функции не предусмотрена.

[Параметры]

ioSlotNum указатель на идентификатор слота, который был выделен ранее статической библиотекой.

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

Функция вернет TRUE в случае успеха, иначе вернет FALSE.

Прототип на языке C:

void* VDK_GetThreadSlotValue (int inSlotNum);

Прототип на языке C++:

void* VDK::GetThreadSlotValue (int inSlotNum);

Вернет значение, находящееся в таблице слотов текущего работающего потока. Слот таблицы указывает inSlotNum. Вернет NULL, если ключ не идентифицирует текущий выделенный слот; иначе вернет текущее значение, удерживаемое в слоте, которое тоже может быть равно NULL.

Функция не влияет на поведение планировщика. Время выполнения функции всегда одинаковое. Обработка ошибок функции не предусмотрена.

[Параметры]

ioSlotNum указатель на идентификатор слота, который был выделен ранее статической библиотекой.

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

Функция вернет значение для указанного номера слота.

Прототип на языке C:

bool VDK_SetThreadSlotValue (int inSlotNum, void *inValue);

Прототип на языке C++:

bool VDK::SetThreadSlotValue (int inSlotNum, void *inValue);

Установит значение в таблице слотов текущего работающего потока. Слот идентифицируется через inSlotNum. Вернет FALSE, если (и только в этом случае) inSlotNum не идентифицирует текущий выделенный слот. Иначе будет в идентифицированный слот будет сохранено значение inValue, и функция вернет TRUE.

[Параметры]

ioSlotNum указатель на идентификатор слота, который был выделен ранее статической библиотекой.

inValue значение для сохранения в таблице слотов потока (запись в таблице идентифицируется параметром inSlotNum).

Функция не влияет на поведение планировщика. Время выполнения функции всегда одинаковое. Обработка ошибок функции не предусмотрена.

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

Функция вернет FALSE, если inSlotNum не идентифицирует текущий выделенный слот, иначе вернет TRUE.

[Функции обработки ошибок потока]

Прототип на языке C:

void VDK_ClearThreadError (void);

Прототип на языке C++:

void VDK::ClearThreadError (void);

Устанавливает состояние работающего потока в kNoError, и значение ошибки сбрасывает в 0.

Функция не влияет на работу планировщика. Время выполнения функции постоянно. Обработка ошибок функции не предусмотрена.

Прототип на языке C:

int VDK_DispatchThreadError (VDK_SystemError inErr,
                             const int inVal);

Прототип на языке C++:

int VDK::DispatchThreadError (VDK::SystemError inErr,
                              const int inVal);

Устанавливает состояние ошибки и значение ошибки в текущем работающем потоке и вызывает функцию обработки ошибки потока. Если DispatchThreadError() была вызвана перед инициализацией приложения VDK, то это вызовет панику ядра (KernelPanic) с PanicCode kBootError. Значения системной ошибки и паники являются аргументами inErr и inVal, которые передаются в функцию DispatchThreadError().

Функция не влияет на поведение планировщика, но обработчик исключения потока может запустить планировщик. Время работы функции не определено. Обработка ошибок функции не предусмотрена.

[Параметры]

inErr это значение из перечисления ошибок. Дополнительную информацию см. в описании типа перечисления SystemError.

inVal это значение, смысл которого зависит от первого параметра.

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

Функция вернет значение из обработчика ошибки текущего потока.

Прототип на языке C:

VDK_SystemError VDK_GetLastThreadError (void);

Прототип на языке C++:

VDK::SystemError VDK::GetLastThreadError (void);

Вернет состояние самой последней ошибки, которая была в потоке. Дополнительную информацию см. в описании типа перечисления SystemError.

Функция не влияет на планировщик. Время выполнения функции постоянное. Обработка ошибок функции не предусмотрена.

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

Функция вернет состояние (тип) самой последней ошибки, которая была в потоке.

Прототип на языке C:

int VDK_GetLastThreadErrorValue (void);

Прототип на языке C++:

int VDK::GetLastThreadErrorValue (void); 

Вернет значение для самой последней ошибки, которая была в потоке. Смысл этого значения зависит от типа произошедшей ошибки.

Функция не влияет на планировщик. Время выполнения функции постоянное. Обработка ошибок функции не предусмотрена.

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

Вернет дополнительное значение, поясняющее смысл последнего состояния диспетчеризированной ошибки. Для получения подробностей см. врезку с описанием перечисления SystemError, а также таблицу 5-22 в статье [4].

Прототип на языке C:

void VDK_SetThreadError (VDK_SystemError inErr, int inVal);

Прототип на языке C++:

void VDK::SetThreadError (VDK::SystemError inErr, int inVal);

Функция устанавливает состояние и значение ошибки потока.

Функция не влияет на планировщик. Время выполнения функции постоянное. Обработка ошибок функции не предусмотрена.

[Параметры]

inErr это значение из перечисления ошибок. Дополнительную информацию см. в описании типа перечисления SystemError.

inVal это значение, смысл которого зависит от первого параметра.

[Функции управления приоритетом потока]

Прототип на языке C:

VDK_Priority VDK_GetPriority (VDK_ThreadID inThreadID);

Прототип на языке C++:

VDK::Priority VDK::GetPriority (VDK::ThreadID inThreadID);

Вернет приоритет (тип Priority) указанного потока.

Функция не влияет на планировщик. Время выполнения функции постоянное.

[Параметры]

inThreadID значение типа ThreadID - идентификатор потока, у которого запрашивается значение приоритета.

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

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

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и при использовании библиотек проверки ошибок:

kUnknownThread показывает, что inThreadID недопустимый идентификатор потока (не принадлежит перечислению ThreadID).

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

Прототип на языке C:

void VDK_ResetPriority (const VDK_ThreadID inThreadID);

Прототип на языке C++:

void VDK::ResetPriority (const VDK::ThreadID inThreadID);

Восстанавливает приоритет указанного потока таким, каким он был изначально задан в шаблоне типа потока.

Функция влияет на поведение планировщика и может вызвать переключение контекста. Время обработки функции не определено.

[Параметры]

inThreadID значение типа ThreadID - идентификатор потока, у которого сбрасывается значение приоритета.

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и при использовании библиотек проверки ошибок:

kUnknownThread показывает, что inThreadID недопустимый идентификатор потока (не принадлежит перечислению ThreadID).

kInvalidThread показывает, что в inThreadID задан идентификатор потока ожидания (Idle Thread).

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

Прототип на языке C:

void VDK_SetPriority (const VDK_ThreadID inThreadID,
                      const VDK_Priority inPriority);

Прототип на языке C++:

void VDK::SetPriority (const VDK::ThreadID inThreadID,
                       const VDK::Priority inPriority);

Динамически устанавливает приоритет (Priority) указанного потока, изменяя тем самым его приоритет по умолчанию. Все потоки при создании получат приоритет по умолчанию, который указан в шаблоне потока.

Функция влияет на поведение планировщика и может вызвать переключение контекста. Время обработки функции не определено.

[Параметры]

inThreadID значение типа ThreadID - идентификатор потока, у которого устанавливается значение приоритета.

inPriority значение типа Priority, означающее новый приоритет для потока.

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и при использовании библиотек проверки ошибок:

kUnknownThread показывает, что inThreadID недопустимый идентификатор потока (не принадлежит перечислению ThreadID).

kInvalidThread показывает, что в inThreadID задан идентификатор потока ожидания (Idle Thread).

kInvalidPriority показывает, что в параметре inPriority указан недопустимый приоритет.

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

[Функции, влияющие на планировщик]

Прототип на языке C:

void VDK_Sleep (VDK_Ticks inSleepTicks);

Прототип на языке C++:

void VDK::Sleep (VDK::Ticks inSleepTicks);

Приостанавливает выполнение потока на указанное количество тиков системы (VDK Ticks), где каждый тик по времени соответствует интервалу между прерываниями обработчика таймера VDK (VDK Timer ISR). Как только указанное количество тиков истекло, вызвавший эту функцию поток снова переходит в состояние готовности к запуску, и возобновит свое выполнение только тогда, когда его приоритет станет самым высоким среди потоков, также готовых к запуску.

Минимальное количество тиков, которое можно указать для функции Sleep(), равно 1. Вызов Sleep() с параметром 1 приведет к тому, что текущий поток войдет в состояние сна до момента времени, когда произойдет следующий вызов обработчика таймера системы (Timer ISR).

В зависимости от времени вызова Sleep(), обработчик Timer ISR может запуститься в интервале времени от 0 и < Timer Period > мс после вызова Sleep(). Причина этого в том, что прерывание таймера может быть готова к запуску в момент вызова Sleep(). Обычно если Вы делаете вызов Sleep() с интервалом в N, то поток войдет в состояние сна на время между < Timer Period > * (N - 1) и < Timer Period > * N, в зависимости от того, в какой момент произошел вызов Sleep().

Функция влияет на поведение планировщика и может вызвать переключение контекста. Время обработки функции не определено.

[Параметры]

inSleepTicks это значение, меньшее чем INT_MAX, которое указывает длительность (в тиках системы), в которой поток должен находиться в режиме "сна".

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и при использовании библиотек проверки ошибок:

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

kInvalidDelay показывает, что значение параметра inSleepTicks не находится в допустимом диапазоне 1 .. (INT_MAX — 1).

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

Прототип на языке C:

void VDK_Yield (void);

Прототип на языке C++:

void VDK::Yield (void);

Уступает управление процессором другому потоку и перемещает текущий поток в конец очереди ожидания на запуск на таком же уровне приоритета. Когда Yield() вызывается из потока с уровнем приоритета, использующего многопоточность типа round-robin, вызов также уступает остаток слайса времени потока.

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

[Обработка ошибок]

Диспетчеризация ошибок в режиме поддержки отладки Full instrumentation и при использовании библиотек проверки ошибок:

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

Если библиотеки проверки ошибок не используются, то обработки ошибок нет.

[Определения перечислений и структур, связанных с потоками]

Переменная типа ThreadCreationBlock передается в API-функции CreateThreadEx() и CreateThreadEx2().

Функция CreateThreadEx() использует не нулевые поля из ThreadCreationBlock, которые существуют в VisualDSP++ 5.0 или более старых версиях (она не может использовать любые новые поля, в целях обеспечения обратной совместимости).

Функция CreateThreadEx2() кроме ThreadCreationBlock также требует второй аргумент, который показывает поля ThreadCreationBlock для установки. Это делает CreateThreadEx2() расширителем API, если новые поля будут введены в новых, последующих версиях VisualDSP++. Подробности см. в отдельных описаниях API. CreateThreadEx2() была введена в VisualDSP++ 5.0 update 9, и доступна только для процессоров Blackfin и SHARC.

На языке C:

typedef struct VDK_ThreadCreationBlock
{
   VDK_ThreadType             template_id;
   VDK_ThreadID               thread_id;
   unsigned int               thread_stack_size;
   VDK_Priority               thread_priority;
   void                       *user_data_ptr;
   struct VDK_ThreadTemplate  *pTemplate;
   unsigned int               *stack_pointer;
} VDK_ThreadCreationBlock;

На языке C++:

typedef struct VDK::ThreadCreationBlock
{
   VDK::ThreadType            template_id;
   VDK::ThreadID              thread_id;
   unsigned int               thread_stack_size;
   VDK::Priority              thread_priority;
   void                       *user_data_ptr;
   struct VDK::ThreadTemplate *pTemplate;
   unsigned int               *stack_pointer;
} VDK::ThreadCreationBlock;

template_id соотвествует типу ThreadType, определенному в файлах VDK.h и VDK.cpp. Эти файлы содержат информацию о значениях по умолчанию для размера стека потока и его начального приоритета, которые могут быть опционально быть переназначены следующими полями.

thread_id поле только для вывода. При успешном возврате оно содержит то же самое значение, что и вернула функция.

thread_stack_size выражается в 32-битных словах и изменяет первоначально заданный размер стека, который подразумевал бы тип ThreadType.

thread_priority переназначает приоритет по умолчанию, который подразумевал бы тип ThreadType.

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

pTemplate это указатель на шаблон потока, который используется для генерации потока. Это требуется только тогда, когда template_id установлен в значение kDynamicThreadType. Размер стека и начальный приоритет (опционально) нереназначаются значениями, указанными в полях thread_stack_size и thread_priority.

stack_pointer это указатель на предоставленную пользователем память размера thread_stack_size. Это поле игнорируется в вызове CreateThreadEx(). На процессорах Blackfin библиотека VDK сохраняет контекст потока в стеке и, таким образом, выделенная область памяти должна быть равна stack_size + context_size, где context_size может быть получена вызовом API-функции GetContextRecordSize().

Тип TCBBitfield (он доступен только в VisualDSP++ 5.0 update 9 или более поздней версии) перечисляет различные биты, которые могут быть установлены во втором аргументе вызова API-функции CreateThreadEx2(). Этот аргумент задает, какие параметры по умолчанию типа ThreadType должны быть переназначены теми значениями, которые для создания поток определил пользователь через первый параметр CreateThreadEx2(). Чтобы указать несколько параметров для замены, то флаги из этого перечисления должны быть объединить друг с другом операцией OR.

На языке C имя типа: VDK_TCBBitfield. Возможные значения:

VDK_kSetThreadTemplateID
VDK_kSetThreadStackSize
VDK_kSetThreadPriority
VDK_kSetUserDataPointer
VDK_kSetThreadTemplatePointer
VDK_kSetThreadStackPointer

На языке C++ имя типа: VDK::TCBBitfield. Возможные значения:

VDK::kSetThreadTemplateID
VDK::kSetThreadStackSize
VDK::kSetThreadPriority
VDK::kSetUserDataPointer
VDK::kSetThreadTemplatePointer
VDK::kSetThreadStackPointer

Тип SystemError перечисляет (это перечисление enum) ошибки, относящиеся к системе, которые передаются к обработчику ошибок (error handler).

На языке C имя типа VDK_SystemError. Возможные значения:

VDK_kUnknownThreadType
VDK_kUnknownThread
VDK_kInvalidThread
VDK_kThreadCreationFailure
VDK_kUnknownSemaphore
VDK_kUnknownEventBit
VDK_kUnknownEvent
VDK_kInvalidPriority
VDK_kInvalidDelay
VDK_kSemaphoreTimeout
VDK_kEventTimeout
VDK_kBlockInInvalidRegion
VDK_kDbgPossibleBlockInRegion
VDK_kInvalidPeriod
VDK_kAlreadyPeriodic
VDK_kNonperiodicSemaphore
VDK_kDbgPopUnderflow
VDK_kBadIOID
VDK_kBadDeviceDescriptor
VDK_kSSLInitFailure*
VDK_kOpenFailure
VDK_kCloseFailure
VDK_kReadFailure
VDK_kWriteFailure
VDK_kIOCtlFailure
VDK_kBadIOTemplateID
VDK_kInvalidDeviceFlag
VDK_kDeviceTimeout
VDK_kDeviceFlagCreationFailure
VDK_kMaxCountExceeded
VDK_kSemaphoreCreationFailure
VDK_kSemaphoreDestructionFailure
VDK_kPoolCreationFailure
VDK_kInvalidBlockPointer
VDK_kInvalidPoolParms
VDK_kInvalidPoolID
VDK_kErrorPoolNotEmpty
VDK_kErrorMallocBlock
VDK_kMessageCreationFailure
VDK_kInvalidMessageID
VDK_kInvalidMessageOwner
VDK_kInvalidMessageChannel
VDK_kInvalidMessageRecipient
VDK_kMessageTimeout
VDK_kMessageInQueue
VDK_kInvalidTimeout
VDK_kInvalidTargetDSP
VDK_kIOCreateFailure
VDK_kHeapInitialisationFailure
VDK_kInvalidHeapID
VDK_kNewFailure
VDK_kInvalidMarshalledType
VDK_kUncaughtException
VDK_kAbort
VDK_kInvalidMaskBit
VDK_kInvalidThreadStatus
VDK_kThreadStackOverflow
VDK_kMaxIDExceeded
VDK_kThreadDestroyedInInvalidRegion
VDK_kNotMutexOwner
VDK_kMutexNotOwned
VDK_kMutexCreationFailure
VDK_kMutexDestructionFailure
VDK_kMutexSpaceTooSmall
VDK_kInvalidMutexID
VDK_kInvalidMutexOwner
VDK_kAPIUsedfromISR
VDK_kMaxHistoryEventExceeded
VDK_kUnhandledExceptionError*
VDK_kInvalidPointer
VDK_kIntsAreDisabled
VDK_kRescheduleIntIsMasked
VDK_kNoError = 0
VDK_kFirstUserError
VDK_kLastUserError

На языке C++ имя типа VDK::SystemError. Возможные значения, их значения и имена те же самые, просто префикс VDK_ заменяется на префикс VDK::.

Примечание *: код ошибки kSSLInitFailure появился в VisualDSP++ 5.0 update 4, и в предыдущих релизах его не было. Код ошибки kUnhandledExceptionError появился в VisualDSP++ 5.0 update 9, и в предыдущих релизах его не было.

[Поток фонового ожидания (Idle Thread)]

Поток Idle является в VDK-приложении заранее определенным, он автоматически создается с ThreadID, установленным в 0, и у него будет задан самый низкий приоритет, ниже чем все приоритеты потоков пользователя. Таким образом, если в очереди готовности нет потоков пользователя, то будет запущен поток Idle. Единственная существенная работа, которую делает поток Idle, это освобождение ресурсов уничтоженных потоков. Другими словами, поток Idle обрабатывает уничтожение потоков, которые были переданы в функцию DestroyThread(), где в параметре inDestroyNow было задано FALSE. В зависимости от платформы можно настроить основные свойства потока Idle, такие как его размер стека и куча, откуда будут выделяться все его необходимые области памяти (включая стек потока Idle). Дополнительную информацию Вы можете получить из онлайн Help. Могут быть зависящие от процессора требования к отдельным свойствам потока Idle (также дополнительную информацию см. в приложении A "Замечания, касающиеся используемого процессора").

Время, проведенное в потоках кроме потока Idle, показано в процентах за длительный промежуток времени на закладке (Target Load) окна истории состояний (State History) среды разработки VisualDSP++. См. раздел "VDK State History Window" руководства [1] и онлайн Help для получения дополнительной информации об окне истории состояний.

[Ссылки]

1. VisualDSP++ 5.0 Kernel (VDK) User’s Guide site:analog.com.
2
. Обзор VisualDSP++ Kernel RTOS (VDK).
3. VDK: сигналы, взаимодействие потоков и ISR (синхронизация).
4. VDK: коды и значения ошибок.

 

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


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

Top of Page