API определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.
Основные возможности API:
Сведения о функциях API приведены в таблице ниже.
Библиотека libkos также предоставляет высокоуровневый API для управления потоками исполнения. Рекомендуется использовать именно этот API. Низкоуровневый API следует использовать, если недостаточно возможностей высокоуровневого API.
Создание потока исполнения. Классы планирования и приоритеты потоков исполнения
Чтобы создать поток исполнения, нужно вызвать функцию KnThreadCreateByHandle(). Через параметр flags этой функции для создаваемого потока исполнения можно задать следующие классы планирования:
Приоритет стандартного потока исполнения может принимать значения от 0 до 15. Чем выше приоритет стандартного потока исполнения, тем больше размер квантов времени, выделяемых этому потоку, и тем чаще эти кванты выделяются. Один стандартный поток исполнения с высоким приоритетом может занимать несколько мест подряд в очереди потоков исполнения. Стандартные потоки исполнения не могут вытеснять другие стандартные потоки исполнения, а также потоки исполнения реального времени независимо от соотношения приоритетов. Если в очереди появляется поток исполнения реального времени, то текущий стандартный поток исполнения немедленно передает ему управление. Если в очереди нет потоков исполнения реального времени, то текущий стандартный поток исполнения передает управление следующему, если завершился, стал заблокированным, исчерпал свой квант времени или отдал его следующему.
Приоритет потока исполнения реального времени может принимать значения от 0 от 31. Более приоритетные потоки исполнения реального времени вытесняют менее приоритетные. Также потоки исполнения реального времени вытесняют стандартные потоки исполнения независимо от соотношения приоритетов. Передача управления от текущего потока исполнения реального времени следующему в очереди осуществляется в следующих случаях:
Пока поток исполнения реального времени с классом планирования FIFO не будет завершен, заблокирован или вытеснен потоком исполнения реального времени с более высоким приоритетом, он может сколь угодно долго не передавать управление следующему.
Поток исполнения реального времени с классом планирования RR, который не был завершен, заблокирован или вытеснен потоком исполнения реального времени с более высоким приоритетом, передает управление следующему по истечении своего кванта времени, если следующий является потоком исполнения реального времени с таким же приоритетом. В противном случае осуществляется передача управления снова себе.
Поток исполнения реального времени может отдать свой квант времени следующему, если следующий является потоком исполнения реального времени с таким же приоритетом. В противном случае осуществляется передача управления снова себе.
Исполнение потоков реального времени с более низким приоритетом начинается только после того, как каждый из потоков реального времени с более высоким приоритетом завершился или стал заблокированным. Потоки исполнения реального времени с одним приоритетом образуют очередь по принципу FIFO.
Чтобы получить класс планирования потока исполнения, нужно вызвать функцию KnThreadGetSchedPolicyByHandle().
Чтобы изменить класс планирования потока исполнения, нужно вызвать функции KnThreadSetSchedPolicyByHandle(). Также эта функция позволяет изменить размер кванта времени, выделенного потоку исполнения реального времени с классом планирования RR. Это значение является единственным параметром класса планирования потоков реального времени RR, который по умолчанию имеет значение 10 мс, но может принимать значения от 2 мс до 100 мс. Класс планирования стандартных потоков и класс планирования потоков реального времени FIFO не имеют параметров.
Чтобы получить приоритет потока исполнения, нужно вызвать функцию KnThreadGetPriorityByHandle().
Чтобы получить максимально и минимально возможный приоритет потоков исполнения с заданным классом планирования, нужно вызвать функцию KnThreadGetPriorityRange().
Чтобы изменить приоритет потока исполнения, нужно вызвать функцию KnThreadSetSchedPolicyByHandle() или KnThreadSetPriorityByHandle().
После привязки к прерыванию поток исполнения становится потоком исполнения реального времени с классом планирования FIFO и приоритетом выше 31 независимо от того, какой класс планирования и приоритет были у этого потока исполнения до привязки к прерыванию. (О привязке потока исполнения к прерыванию см. "Управление обработкой прерываний (irq.h)".)
Для потока исполнения, привязанного к прерыванию, нельзя применять некоторые функции API, в том числе KnThreadGetPriorityByHandle(), KnThreadSetPriorityByHandle(), KnThreadGetAffinityByHandle(), KnThreadSetAffinityByHandle(), KnThreadGetSchedPolicyByHandle(), KnThreadSetSchedPolicyByHandle(). Также из потока исполнения, привязанного к прерыванию, нельзя вызывать некоторые функции этого и других API библиотеки libkos, включая KnSleep(), KnThreadSuspendCurrent(), KnThreadWaitByHandle(), KnFutexWait(), KnNoticeGetEvent(), KnCmConnect(), KnCmListen(), KnAuRead(), KnSamplingProfiler*().
Создание дескриптора потока исполнения
Дескриптор потока исполнения создается при создании потока исполнения вызовом функции KnThreadCreateByHandle(). Также поток исполнения (в том числе начальный) может создать свой дескриптор вызовом функции KnThreadOpenCurrent().
Дескриптор потока исполнения нельзя передать другому процессу через IPC.
Обработка исключений
Чтобы зарегистрировать функцию обработки исключений для потока исполнения, нужно вызвать функцию KnThreadSetExceptionHandler(). Эта функция дерегистрирует предыдущую функцию обработки исключений и возвращает ее идентификатор. Сохранив этот идентификатор, в дальнейшем можно снова зарегистрировать предыдущую функцию обработки исключений.
Чтобы получить сведения о последнем исключении потока исполнения, в обработчике исключений нужно вызвать функцию KnThreadGetLastException().
Отвязывание потока исполнения от прерывания
Чтобы отвязать поток исполнения от прерывания, нужно вызвать функцию KnThreadDetachIrq(). (Подробнее об использовании функции KnThreadDetachIrq() см. "Управление обработкой прерываний (irq.h)".)
После отвязывания от прерывания поток исполнения получает класс планирования и приоритет, которые были у этого потока исполнения до привязки к прерыванию.
Привязка потока исполнения к процессорам (вычислительным ядрам)
По умолчанию поток может исполняться на всех процессорах (вычислительных ядрах). Чтобы ограничить набор процессоров (вычислительных ядер), которые могут быть использованы для исполнения потока, нужно изменить маску сходства этого потока. Маска сходства (англ. Affinity Mask) – битовая маска, указывающая на каких процессорах (вычислительных ядрах) должен исполняться поток.
Чтобы получить маску сходства потока исполнения, нужно вызвать функцию KnThreadGetAffinityByHandle().
Чтобы корректировать и выполнять другие операции с масками сходства, нужно использовать API, определенный в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.
Чтобы задать маску сходства потока исполнения, нужно вызвать функцию KnThreadSetAffinityByHandle().
Завершение потока исполнения
Завершение потока исполнения представляет собой его перманентное удаление из планировщика. Поток исполнения завершается в следующих случаях:
Должен быть осуществлен выход оператором return из корневой (не из вложенной) функции, выполняемой потоком исполнения.
KnThreadTerminateByHandle() или KnThreadExit().Функция KnThreadTerminateByHandle() завершает поток исполнения только в том случае, если этот поток заблокирован вызовом функции KnThreadSuspendCurrent() или находится в заблокированном состоянии с момента создания.
Функция KnThreadExit() завершает поток исполнения, даже если вызвана не из корневой функции, выполняемой потоком исполнения, а из вложенной.
О "замороженном" состоянии процесса см. "Управление процессами (низкоуровневый API task_api.h)".
Коды завершения потоков исполнения определяются разработчиком решения на базе KasperskyOS . Эти коды нужно указывать в параметре code функций KnThreadTerminateByHandle() и KnThreadExit(), а также при вызове оператора return в функции, выполняемой потоком исполнения. Чтобы получить код завершения потока исполнения, нужно вызвать функцию KnThreadWaitByHandle().
Блокирование и возобновление исполнения потока исполнения
Чтобы заблокировать поток исполнения, нужно вызвать функцию KnThreadSuspendCurrent().
Чтобы возобновить исполнение потока, заблокированного с момента создания или в результате вызова функции KnThreadSuspendCurrent(), нужно вызвать функцию KnThreadResumeByHandle().
Чтобы заблокировать поток исполнения до завершения другого, нужно вызвать функцию KnThreadWaitByHandle().
Чтобы заблокировать поток исполнения на заданное время, нужно вызвать функцию KnSleep().
Получение адреса TCB
Блок управления потоком исполнения (англ. Thread Control Block, TCB) – структура, содержащая сведения о потоке исполнения, которые используются ядром для управления этим потоком исполнения. TCB содержит базовый адрес TLS. Получить адрес TCB позволяет функция KnThreadGetTcb(). Эта функция предназначена для использования библиотекой libc.
Получение сведений о потоке исполнения
Чтобы получить TID, нужно вызвать функцию KnThreadCurrent().
Получить базовый адрес и размер стека потока исполнения, TID, а также базовый адрес TLS позволяет функция KnThreadGetInfoByHandle(). Эта функция предназначена для использования библиотекой libc.
Освобождение ресурсов завершившегося потока исполнения
Ресурсами потока исполнения являются его стек, контекст и TCB. Чтобы ресурсы потока исполнения были освобождены после его завершения, нужно до или после завершения этого потока исполнения закрыть его дескриптор. Исключением являются следующие случаи:
KnThreadCreateByHandle() автоматически закрывает дескриптор созданного потока исполнения, если вызвана со значением RTL_NULL в параметре thread.KnThreadOpenCurrent()).Также ресурсы потоков исполнения освобождаются при завершении процесса, в который они входят.
Сведения о функциях API
Функции thread_api.h
Функция |
Сведения о функции |
|---|---|
|
Назначение Создает поток исполнения. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре
|
|
Назначение Создает дескриптор вызывающего потока исполнения. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить максимально и минимально возможный приоритет потоков исполнения с заданным классом планирования. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре
|
|
Назначение Позволяет получить приоритет потока исполнения. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Задает приоритет потока исполнения. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Блокирует вызывающий поток исполнения. Параметры Нет. Возвращаемые значения В случае успеха возвращает |
|
Назначение Возобновляет исполнение заблокированного потока. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Завершает заблокированный поток исполнения. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Завершает вызывающий поток исполнения. Параметры
Возвращаемые значения Код ошибки. |
|
Назначение Позволяет получить сведения о потоке исполнения. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Блокирует вызывающий поток исполнения до завершения заданного потока исполнения. Параметры
Возвращаемые значения В случае успеха возвращает Если время ожидания истекло, возвращает Дополнительные сведения Неблокирующий вызов, если в параметре |
|
Назначение Блокирует вызывающий поток исполнения на заданное время. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения Неблокирующий вызов, если в параметре |
|
Назначение Позволяет получить TID для вызывающего потока исполнения. Параметры Нет. Возвращаемые значения TID для вызывающего потока исполнения. Тип возвращаемого значения определен в заголовочном файле |
|
Назначение Позволяет получить адрес TCB для вызывающего потока исполнения. Параметры Нет. Возвращаемые значения Указатель на TCB для вызывающего потока исполнения. Тип данных для хранения TCB определен в заголовочном файле |
|
Назначение Отвязывает вызывающий поток исполнения от прерывания, обрабатываемого в его контексте. Параметры Нет. Возвращаемые значения В случае успеха возвращает |
|
Назначение Регистрирует функцию обработки исключений для вызывающего потока исполнения. Параметры
Возвращаемые значения Идентификатор предыдущей зарегистрированной функции обработки исключений или |
|
Назначение Позволяет получить сведения о последнем исключении вызывающего потока исполнения. Параметры
Возвращаемые значения Нет. |
|
Назначение Позволяет получить маску сходства потока исполнения. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Задает маску сходства потока исполнения. Параметры
Возвращаемые значения В случае успеха возвращает |
|
Назначение Позволяет получить сведения о классе планирования потока исполнения. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре В параметре |
|
Назначение Задает класс планирования и приоритет потока исполнения. Параметры
Возвращаемые значения В случае успеха возвращает Дополнительные сведения В параметре
В параметре В параметре |