The API is defined in the header file sysroot-*-kos/include/coresrv/thread/thread_api.h from the KasperskyOS SDK.
Main capabilities of the API:
Information about API functions is provided in the table below.
The libkos library also provides a high-level API for thread management. It is recommended to use this specific API. The low-level API should be used only if the high-level API does not have sufficient capabilities.
Creating a thread Thread scheduler classes and priorities
To create a thread, call the KnThreadCreateByHandle() function. You can use the flags parameter of this function for the created thread to define the following scheduler classes:
The priority of a standard thread can take values ranging from 0 to 15. The higher the priority of a standard thread, the larger the quantum allocated to this thread and the more frequently these quanta are allocated. One standard thread with a high priority can occupy multiple consecutive places in the thread queue. Standard threads cannot supersede other standard threads or real-time threads, regardless of their respective priorities. If a real-time thread appears in the queue, the current standard thread immediately transfers control to the real-time thread. If there are no real-time threads in the queue, the current standard thread transfers control to the next standard thread if the current one is terminated, becomes locked, uses up its quantum or gives it up to the next standard thread.
The priority of a real-time thread can take values ranging from 0 to 31. Higher-priority real-time threads supersede lower-priority real-time threads. Real-time threads also supersede standard threads, regardless of their respective priorities. Control is transferred from the current real-time thread to the next real-time thread in the queue in the following cases:
Until the real-time thread with a FIFO scheduler class is terminated, locked, or superseded by a real-time thread with a higher priority, it can retain control indefinitely and not transfer control to the next real-time thread.
A real-time thread with an RR scheduler class that is not terminated, locked, or superseded by a higher-priority real-time thread transfers control to the next one upon expiry of its quantum if the next one is a real-time thread with the same priority. Otherwise, it transfers control to itself again.
A real-time thread can give up its quantum to the next one in the queue if the next one is a real-time thread with the same priority. Otherwise, it transfers control to itself again.
Execution of lower-priority real-time threads begins only after each of the real-time threads with a higher priority is terminated or locked. Real-time threads with the same priority form a queue based on the FIFO principle.
To get the thread scheduler class, call the KnThreadGetSchedPolicyByHandle() function.
To change the thread scheduler class, call the KnThreadSetSchedPolicyByHandle() function. This function also changes the size of the quantum allocated to a real-time thread with an RR scheduler class. This value is the only parameter of a real-time thread RR scheduler class that has a default value of 10 ms but can take values ranging from 2 ms to 100 ms. The scheduler class of standard threads and the scheduler class of FIFO real-time threads do not have parameters.
To get the thread priority, call the KnThreadGetPriorityByHandle() function.
To get the maximum and minimum possible priority of threads with the specified scheduler class, call the KnThreadGetPriorityRange() function.
To change the priority of a thread, call the KnThreadSetSchedPolicyByHandle() or KnThreadSetPriorityByHandle() function.
After a thread is attached to an interrupt, the thread becomes a real-time thread with a FIFO scheduler class and a priority higher than 31, irrespective of the specific scheduler class and priority this thread had before it was attached to the interrupt. Managing interrupt processing (irq.h).)
Some API functions cannot be applied for a thread that is attached to an interrupt. These functions include KnThreadGetPriorityByHandle(), KnThreadSetPriorityByHandle(), KnThreadGetAffinityByHandle(), KnThreadSetAffinityByHandle(), KnThreadGetSchedPolicyByHandle(), and KnThreadSetSchedPolicyByHandle(). Also, some functions of this API and other APIs of the libkos library cannot be called from a thread that is attached to an interrupt. These functions include KnSleep(), KnThreadSuspendCurrent(), KnThreadWaitByHandle(), KnFutexWait(), KnNoticeGetEvent(), KnCmConnect(), KnCmListen(), KnAuRead(), and KnSamplingProfiler*().
Creating a thread handle
A thread handle is created whenever a thread is created by the KnThreadCreateByHandle() function call. A thread (including the initial thread) can also create its own handle by calling the KnThreadOpenCurrent() function.
A thread handle cannot be transferred to another process via IPC.
Handling exceptions
To register an exception handling function for a thread, call the KnThreadSetExceptionHandler() function. This function deregisters the previous exception handling function and returns its ID. By saving this ID, you can subsequently register the previous exception handling function again.
To get information about the last exception of a thread, call the KnThreadGetLastException() function in the exception handler.
Detaching a thread from an interrupt
To detach a thread from an interrupt, call the KnThreadDetachIrq() function. (For more details about using the KnThreadDetachIrq() function, see Managing interrupt processing (irq.h).)
After a thread is detached from an interrupt, the thread receives the scheduler class and priority that it had before it was attached to the interrupt.
Attaching a thread to processors (processor cores)
By default, a thread may be executed on all processors (processor cores). To restrict the set of processors (processor cores) that can be used to execute a thread, change the affinity mask of this thread. An affinity mask is a bit mask indicating which specific processors or processor cores must execute the thread.
To get a thread affinity mask, call the KnThreadGetAffinityByHandle() function.
To adjust affinity masks and perform other operations with them, use the API that is defined in the header file sysroot-*-kos/include/rtl/cpuset.h from the KasperskyOS SDK.
To define a thread affinity mask, call the KnThreadSetAffinityByHandle() function.
Terminating a thread
When a thread is terminated, it is permanently deleted from the scheduler. A thread is terminated in the following cases:
The root function (not a nested function) performed by the thread must be exited by the return operator.
KnThreadTerminateByHandle() or KnThreadExit() function is called.The KnThreadTerminateByHandle() function terminates the thread only if this thread was locked by calling the KnThreadSuspendCurrent() function or if it has been in a locked state since it was created.
The KnThreadExit() function terminates the thread even if the function is called from a nested function instead of the root function executed by the thread.
For details about the "frozen" state, see Managing processes (low-level API task_api.h).
Thread exit codes are defined by the developer of the KasperskyOS-based solution. These codes should be specified in the code parameter of the KnThreadTerminateByHandle() and KnThreadExit() functions, and when calling the return operator in the function executed by the thread. To get the thread exit code, call the KnThreadWaitByHandle() function.
Locking and resuming a thread
To lock a thread, call the KnThreadSuspendCurrent() function.
To resume a thread that has been locked since it was created or was locked due to a call of the KnThreadSuspendCurrent() function, call the KnThreadResumeByHandle() function.
To lock a thread until another thread completes, call the KnThreadWaitByHandle() function.
To lock a thread for a defined amount of time, call the KnSleep() function.
Getting the TCB
A thread control block (TCB) is a structure containing thread information that is used by the kernel to manage this specific thread. The TCB contains the base address of the TLS. The KnThreadGetTcb() function gets the TCB address. This function is intended for use by the libc library.
Getting thread information
To get the current thread's TID, call the KnThreadCurrent() function.
The KnThreadGetInfoByHandle() function gets the base address and stack limit of the thread, TID, and the TLS base address. This function is intended for use by the libc library.
Freeing resources of a terminated thread
Resources of a thread include its stack, context, and TCB. To ensure that the resources of a thread are freed after the thread is terminated, you must close its handle before or after termination of the thread except for the following cases:
KnThreadCreateByHandle() function automatically closes the handle of the created thread if it is called with the RTL_NULL value in the thread parameter.KnThreadOpenCurrent() function).Resources of threads are also freed upon termination of the process that includes these threads.
Information about API functions
thread_api.h functions
Function |
Information about the function |
|---|---|
|
Purpose Creates a thread. Parameters
Returned values If successful, the function returns Additional information In the
|
|
Purpose Creates the handle of the calling thread. Parameters
Returned values If successful, the function returns |
|
Purpose Gets the maximum and minimum possible priority of threads with the specified scheduler class. Parameters
Returned values If successful, the function returns Additional information In the
|
|
Purpose Gets the priority of a thread. Parameters
Returned values If successful, the function returns |
|
Purpose Defines the priority of a thread. Parameters
Returned values If successful, the function returns |
|
Purpose Locks the calling thread. Parameters N/A Returned values If successful, the function returns |
|
Purpose Resumes execution of a locked thread. Parameters
Returned values If successful, the function returns |
|
Purpose Terminates the locked thread. Parameters
Returned values If successful, the function returns |
|
Purpose Terminates the calling thread. Parameters
Returned values Error code. |
|
Purpose Gets information about a thread. Parameters
Returned values If successful, the function returns |
|
Purpose Locks the calling thread until the defined thread is terminated. Parameters
Returned values If successful, the function returns Returns Additional information Non-blocking call if the |
|
Purpose Locks the calling thread for the specified duration. Parameters
Returned values If successful, the function returns Additional information Non-blocking call if the |
|
Purpose Gets the TID for the calling thread. Parameters N/A Returned values TID for the calling thread. The type of returned value is defined in the header file |
|
Purpose Gets the TCB address for the calling thread. Parameters N/A Returned values Pointer to the TCB for the calling thread. The data type for TCB storage is defined in the header file |
|
Purpose Detaches the calling thread from the interrupt handled in its context. Parameters N/A Returned values If successful, the function returns |
|
Purpose Registers the exception handling function for the calling thread. Parameters
Returned values ID of the previously registered exception handling function if one exists, otherwise |
|
Purpose Gets information about the last exception of the calling thread. Parameters
Returned values N/A |
|
Purpose Gets a thread affinity mask. Parameters
Returned values If successful, the function returns |
|
Purpose Sets a thread affinity mask. Parameters
Returned values If successful, the function returns |
|
Purpose Gets information about the thread scheduler class. Parameters
Returned values If successful, the function returns Additional information In the In the |
|
Purpose Defines the scheduler class and priority of the thread. Parameters
Returned values If successful, the function returns Additional information In the
In the In the |