KasperskyOS Community Edition 1.3

Управление потоками исполнения (низкоуровневый API thread_api.h)

API определен в заголовочном файле sysroot-*-kos/include/coresrv/thread/thread_api.h из состава KasperskyOS SDK.

Основные возможности API:

  • создавать, завершать, блокировать потоки исполнения;
  • возобновлять исполнение заблокированных потоков;
  • изменять приоритеты и классы планирования потоков исполнения;
  • обрабатывать исключения;
  • отвязывать потоки исполнения от прерываний;
  • выполнять привязку потоков исполнения к процессорам (вычислительным ядрам).

Функции API, которые принимают на вход или возвращают идентификатор потока исполнения (TID), являются устаревшими и в будущем будут удалены. Эти функции не описаны в этом разделе.

Сведения о функциях API приведены в таблице ниже.

Библиотека libkos также предоставляет высокоуровневый API для управления потоками исполнения, который определен в заголовочном файле sysroot-*-kos/include/kos/thread.h из состава KasperskyOS SDK. Рекомендуется использовать именно этот API. Низкоуровневый API следует использовать, если недостаточно возможностей высокоуровневого API.

Создание потоков исполнения. Классы планирования потоков исполнения

Чтобы создать поток исполнения, нужно вызвать функцию KnThreadCreateByHandle(). Через параметр flags этой функции для создаваемого потока исполнения можно задать следующие классы планирования:

  • класс планирования стандартных потоков;
  • класс планирования потоков реального времени FIFO (англ. First In, First Out);
  • класс планирования потоков реального времени RR (англ. Round-Robin).

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

Приоритет потока исполнения реального времени может принимать значения от 0 от 31. Более приоритетные потоки исполнения реального времени вытесняют менее приоритетные. Также потоки исполнения реального времени вытесняют стандартные потоки исполнения независимо от соотношения приоритетов. Передача управления от текущего потока исполнения реального времени следующему в очереди осуществляется в следующих случаях:

  • Текущий поток исполнения реального времени с классом планирования FIFO завершился или стал заблокированным, либо в очереди появился поток исполнения реального времени с более высоким приоритетом.

    Пока поток исполнения реального времени с классом планирования FIFO не будет завершен, заблокирован или вытеснен потоком исполнения реального времени с более высоким приоритетом, он может сколь угодно долго не передавать управление следующему.

  • Текущий поток исполнения реального времени с классом планирования RR завершился, стал заблокированным или исчерпал свой квант времени, либо в очереди появился поток исполнения реального времени с более высоким приоритетом.

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

  • Текущий поток исполнения реального времени отдал свой квант времени следующему в очереди потоку исполнения реального времени с таким же приоритетом.

    Поток исполнения реального времени может отдать свой квант времени следующему, если следующий является потоком исполнения реального времени с таким же приоритетом. В противном случае осуществляется передача управления снова себе.

Исполнение потоков реального времени с более низким приоритетом начинается только после того, как каждый из потоков реального времени с более высоким приоритетом завершился или стал заблокированным. Потоки исполнения реального времени с одним приоритетом образуют очередь по принципу FIFO.

Класс планирования потока исполнения можно изменить вызовом функции KnThreadSetSchedPolicyByHandle(). Также эта функция позволяет изменить размер кванта времени, выделенного потоку исполнения реального времени с классом планирования RR. Это значение является единственным параметром класса планирования потоков реального времени RR, который по умолчанию имеет значение 10 мс, но может принимать значения от 2 мс до 100 мс. Класс планирования стандартных потоков и класс планирования потоков реального времени FIFO не имеют параметров.

Приоритет потока исполнения можно изменить вызовом функции KnThreadSetSchedPolicyByHandle() или KnThreadSetPriorityByHandle().

После привязки к прерыванию поток исполнения становится потоком исполнения реального времени с классом планирования FIFO и приоритетом выше 31 независимо от того, какой класс планирования и приоритет были у этого потока исполнения до привязки к прерыванию. (О привязке потока исполнения к прерыванию см. "Управление обработкой прерываний (irq.h)".)

Для потоков исполнения, привязанных к прерываниям, нельзя применять многие функции API, в том числе KnThreadCreateByHandle(), KnThreadSetPriorityByHandle(), KnThreadSuspendCurrent(), KnThreadResumeByHandle(), KnThreadTerminateByHandle(), KnThreadWaitByHandle(), KnSleep(), KnThreadSetSchedPolicyByHandle().

Создание дескрипторов потоков исполнения

Дескриптор потока исполнения создается при создании потока исполнения вызовом функции KnThreadCreateByHandle(). Также поток исполнения (в том числе начальный) может создать свой дескриптор вызовом функции KnThreadOpenCurrent().

Дескриптор потока исполнения нельзя передать другому процессу через IPC.

Обработка исключений

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

Чтобы получить сведения о последнем исключении потока исполнения, в обработчике исключений нужно вызвать функцию KnThreadGetLastException().

Отвязывание потоков исполнения от прерываний

Чтобы отвязать поток исполнения от прерывания, нужно вызвать функцию KnThreadDetachIrq(). (Подробнее об использовании функции KnThreadDetachIrq() см. "Управление обработкой прерываний (irq.h)".)

После отвязывания от прерывания поток исполнения получает класс планирования и приоритет, которые были у этого потока исполнения до привязки к прерыванию.

Привязка потоков исполнения к процессорам (вычислительным ядрам)

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

Чтобы создавать, корректировать и выполнять другие операции с масками сходства, нужно использовать API, определенный в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.

Чтобы задать маску сходства потока исполнения, нужно вызвать функцию KnThreadSetAffinityByHandle().

Завершение потоков исполнения

Завершение потока исполнения представляет собой его перманентное удаление из планировщика. Поток исполнения завершается в следующих случаях:

  • Осуществлен выход из функции, выполняемой потоком исполнения.

    Должен быть осуществлен выход оператором return из корневой (не из вложенной) функции, выполняемой потоком исполнения.

  • Вызвана функция KnThreadTerminateByHandle() или KnThreadExit().

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

  • Завершился или перешел в "замороженное" состояние процесс.

    О "замороженном" состоянии процесса см. "Управление процессами (низкоуровневый API task_api.h)".

Коды завершения потоков исполнения определяются разработчиком решения на базе KasperskyOS . Эти коды нужно указывать в параметре code функций KnThreadTerminateByHandle() и KnThreadExit(), а также при вызове оператора return в функции, выполняемой потоком исполнения. Чтобы получить код завершения потока исполнения, нужно вызвать функцию KnThreadWaitByHandle().

Получение адреса TCB и задание базового адреса TLS потоков исполнения

Блок управления потоком исполнения (англ. Thread Control Block, TCB) – структура, содержащая сведения о потоке исполнения, которые используются ядром для управления этим потоком исполнения. Тип структуры определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK. TCB содержит базовый адрес локальной памяти потока исполнения (TLS). Получить адрес TCB позволяет функция KnThreadGetTcb(). Задать базовый адрес TLS позволяет функция KnThreadSetTls(). Эти функции предназначены для использования библиотекой libc.

Получение сведений о потоке исполнения

Получить базовый адрес и размер стека потока исполнения, а также идентификатор потока исполнения (TID) позволяет функция KnThreadGetInfoByHandle(). Эта функция предназначена для использования библиотекой libc.

Освобождение ресурсов завершившихся потоков исполнения

Ресурсами потока исполнения являются его стек, контекст и TCB. Чтобы ресурсы потока исполнения были освобождены после его завершения, нужно до или после завершения этого потока исполнения закрыть его дескриптор вызовом функции KnHandleClose(), которая объявлена в заголовочном файле sysroot-*-kos/include/coresrv/handle/handle_api.h из состава KasperskyOS SDK. (Исключением является начальный поток процесса, ресурсы которого освобождаются без вызова функции KnHandleClose(), если начальный поток не создавал свой дескриптор вызовом функции KnThreadOpenCurrent().) Также ресурсы потоков исполнения освобождаются при завершении процесса, в который они входят.

Сведения о функциях API

Функции thread_api.h

Функция

Сведения о функции

KnThreadCreateByHandle()

Назначение

Создает поток исполнения.

Параметры

  • [out,optional] thread – указатель на дескриптор потока исполнения. Если указать RTL_NULL, дескриптор будет закрыт автоматически после создания потока исполнения.
  • [in] priority – приоритет потока исполнения.
  • [in,optional] stackSize – размер стека потока исполнения в байтах или 0, чтобы был использован размер по умолчанию, заданный при создании процесса.
  • [in] startRoutine – параметр, который должен иметь значение RTL_NULL.
  • [in] routine – указатель на функцию, выполняемую потоком исполнения.
  • [in,optional] context – указатель на параметры, передаваемые функции, заданной через параметр routine, или RTL_NULL, если этой функции не требуется передавать параметры.
  • [in] flags – флаги, задающие параметры создания потока исполнения.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре flags можно указать следующие флаги:

  • ThreadFlagCreateSuspended – создание потока исполнения в заблокированном состоянии.
  • ThreadFlagCreateSchedOther – создание стандартного потока исполнения.
  • ThreadFlagCreateSchedFifo – создание потока исполнения реального времени с классом планирования FIFO.
  • ThreadFlagCreateSchedRR – создание потока исполнения реального времени с классом планирования RR.

По умолчанию создается стандартный поток исполнения.

Дескрипторы потоков исполнения нельзя передавать между процессами через IPC.

KnThreadOpenCurrent()

Назначение

Создает дескриптор вызывающего потока исполнения.

Параметры

  • [out] thread – указатель на дескриптор потока исполнения.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadGetPriorityByHandle()

Назначение

Позволяет получить приоритет потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [out] priority – указатель на приоритет потока исполнения.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadSetPriorityByHandle()

Назначение

Задает приоритет потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] priority – приоритет потока исполнения.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadSuspendCurrent()

Назначение

Блокирует вызывающий поток исполнения.

Параметры

Нет.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadResumeByHandle()

Назначение

Возобновляет исполнение заблокированного потока.

Параметры

  • [in] thread – дескриптор потока исполнения.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadTerminateByHandle()

Назначение

Завершает поток исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] code – код завершения потока исполнения.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadExit()

Назначение

Завершает вызывающий поток исполнения.

Параметры

  • [in] code – код завершения потока исполнения.

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

Код ошибки.

KnThreadGetInfoByHandle()

Назначение

Позволяет получить сведения о потоке исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [out] info – указатель на структуру, содержащую базовый адрес стека потока исполнения и его размер в байтах, а также идентификатор потока исполнения (TID).

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadWaitByHandle()

Назначение

Блокирует вызывающий поток исполнения до завершения заданного потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] msDelay – время ожидания завершения потока исполнения в миллисекундах или INFINITE_TIMEOUT, что задать неограниченное время ожидания.
  • [out] exitCode – указатель на код завершения потока исполнения.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnSleep()

Назначение

Блокирует вызывающий поток исполнения на заданное время.

Параметры

  • [in] mdelay – время блокировки потока исполнения в миллисекундах.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadGetTcb()

Назначение

Позволяет получить адрес блока управления потоком исполнения (TCB) для вызывающего потока исполнения.

Параметры

Нет.

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

Указатель на TCB. Тип данных для хранения TCB определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

KnThreadSetTls()

Назначение

Задает базовый адрес локальной памяти потока исполнения (TLS) для вызывающего потока исполнения.

Параметры

  • [in] tls – указатель на TLS.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadDetachIrq()

Назначение

Отвязывает вызывающий поток исполнения от прерывания, обрабатываемого в его контексте.

Параметры

Нет.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadSetExceptionHandler()

Назначение

Регистрирует функцию обработки исключений для вызывающего потока исполнения.

Параметры

  • [in,optional] handler – идентификатор функции обработки исключений или RTL_NULL, чтобы дерегистрировать предыдущую зарегистрированную функцию обработки исключений без регистрации новой. Тип параметра определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

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

Идентификатор предыдущей зарегистрированной функции обработки исключений или RTL_NULL при ее отсутствии. Тип возвращаемого значения определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

KnThreadGetLastException()

Назначение

Позволяет получить сведения о последнем исключении вызывающего потока исполнения.

Параметры

  • [out] exception – указатель на структуру, содержащую сведения об исключении. Тип структуры определен в заголовочном файле sysroot-*-kos/include/thread/tcbpage.h из состава KasperskyOS SDK.

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

Нет.

KnThreadGetAffinityByHandle()

Назначение

Позволяет получить маску сходства потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [out] mask – указатель на структуру, содержащую маску сходства потока исполнения. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadSetAffinityByHandle()

Назначение

Задает маску сходства потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] mask – указатель на структуру, содержащую маску сходства потока исполнения. Тип структуры определен в заголовочном файле sysroot-*-kos/include/rtl/cpuset.h из состава KasperskyOS SDK.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

KnThreadGetSchedPolicyByHandle()

Назначение

Позволяет получить сведения о классе планирования потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [out] policy – указатель на класс планирования потока исполнения. Тип данных для хранения класса планирования потока исполнения определен в заголовочном файле sysroot-*-kos/include/thread/tidtype.h из состава KasperskyOS SDK.
  • [out,optional] param – указатель на параметры класса планирования потока исполнения или RTL_NULL.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

В параметре param можно указать RTL_NULL, если не требуется получать параметры класса планирования потока исполнения.

В параметре param необходимо указать RTL_NULL, если класс планирования потока исполнения не имеет параметров.

KnThreadSetSchedPolicyByHandle()

Назначение

Задает класс планирования и приоритет потока исполнения.

Параметры

  • [in] thread – дескриптор потока исполнения.
  • [in] policy – класс планирования потока исполнения. Тип параметра определен в заголовочном файле sysroot-*-kos/include/thread/tidtype.h из состава KasperskyOS SDK.
  • [in] prio – приоритет потока исполнения.
  • [in,optional] param – указатель на параметры класса планирования потока исполнения или RTL_NULL.

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

В случае успеха возвращает rcOk, иначе возвращает код ошибки.

Дополнительные сведения

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

В параметре param необходимо указать RTL_NULL, если класс планирования потока исполнения не имеет параметров.