KallistiOS
##version##
|
Threading support. More...
#include <sys/cdefs.h>
#include <kos/tls.h>
#include <arch/types.h>
#include <arch/irq.h>
#include <arch/arch.h>
#include <sys/queue.h>
#include <sys/reent.h>
Go to the source code of this file.
Data Structures | |
struct | kthread |
Structure describing one running thread. More... | |
Macros | |
#define | PRIO_MAX 4096 |
Maximal thread priority. This macro defines the maximum value for a thread's priority. Note that the larger this number, the lower the priority of the thread. More... | |
#define | PRIO_DEFAULT 10 |
Default thread priority. Threads are created by default with the priority specified. More... | |
#define | THD_DEFAULTS 0 |
Defaults: no flags. More... | |
#define | THD_USER 1 |
Thread runs in user mode. More... | |
#define | THD_QUEUED 2 |
Thread is in the run queue. More... | |
#define | THD_DETACHED 4 |
Thread is detached. More... | |
#define | STATE_ZOMBIE 0x0000 |
Waiting to die. More... | |
#define | STATE_RUNNING 0x0001 |
Process is "current". More... | |
#define | STATE_READY 0x0002 |
Ready to be scheduled. More... | |
#define | STATE_WAIT 0x0003 |
Blocked on a genwait. More... | |
#define | STATE_FINISHED 0x0004 |
Finished execution. More... | |
#define | THD_MODE_NONE -1 |
Threads not running. More... | |
#define | THD_MODE_COOP 0 |
Cooperative threading mode. More... | |
#define | THD_MODE_PREEMPT 1 |
Preemptive threading mode. More... | |
Typedefs | |
typedef struct kthread | kthread_t |
Structure describing one running thread. More... | |
Functions | |
int | thd_block_now (irq_context_t *mycxt) |
Block the current thread. More... | |
irq_context_t * | thd_choose_new () |
Find a new thread to swap in. More... | |
kthread_t * | thd_by_tid (tid_t tid) |
Given a thread ID, locates the thread structure. More... | |
void | thd_add_to_runnable (kthread_t *t, int front_of_line) |
Enqueue a process in the runnable queue. More... | |
int | thd_remove_from_runnable (kthread_t *thd) |
Removes a thread from the runnable queue, if it's there. More... | |
kthread_t * | thd_create (int detach, void *(*routine)(void *param), void *param) |
Create a new thread. More... | |
int | thd_destroy (kthread_t *thd) |
Brutally kill the given thread. More... | |
void | thd_exit (void *rv) __noreturn |
Exit the current thread. More... | |
void | thd_schedule (int front_of_line, uint64 now) |
Force a thread reschedule. More... | |
void | thd_schedule_next (kthread_t *thd) |
Force a given thread to the front of the queue. More... | |
void | thd_pass () |
Throw away the current thread's timeslice. More... | |
void | thd_sleep (int ms) |
Sleep for a given number of milliseconds. More... | |
int | thd_set_prio (kthread_t *thd, prio_t prio) |
Set a thread's priority value. More... | |
kthread_t * | thd_get_current () |
Retrieve the current thread's kthread struct. More... | |
const char * | thd_get_label (kthread_t *thd) |
Retrieve the thread's label. More... | |
void | thd_set_label (kthread_t *thd, const char *label) |
Set the thread's label. More... | |
const char * | thd_get_pwd (kthread_t *thd) |
Retrieve the thread's current working directory. More... | |
void | thd_set_pwd (kthread_t *thd, const char *pwd) |
Set the thread's current working directory. More... | |
int * | thd_get_errno (kthread_t *thd) |
Retrieve a pointer to the thread errno. More... | |
struct _reent * | thd_get_reent (kthread_t *thd) |
Retrieve a pointer to the thread reent struct. More... | |
int | thd_set_mode (int mode) |
Change threading modes. More... | |
int | thd_join (kthread_t *thd, void **value_ptr) |
Wait for a thread to exit. More... | |
int | thd_detach (kthread_t *thd) |
Detach a joinable thread. More... | |
int | thd_pslist (int(*pf)(const char *fmt,...)) |
Print a list of all threads using the given print function. More... | |
int | thd_pslist_queue (int(*pf)(const char *fmt,...)) |
Print a list of all queued threads using the given print function. More... | |
int | thd_init (int mode) |
Initialize the threading system. More... | |
void | thd_shutdown () |
Shutdown the threading system. More... | |
Variables | |
int | thd_mode |
Are threads cooperative or preemptive? More... | |
kthread_t * | thd_current |
The currently executing thread. More... | |
vuint32 | jiffies |
"Jiffy" count. More... | |
Threading support.
This file contains the interface to the threading system of KOS. Timer interrupts are used to reschedule threads within the system while in preemptive mode. There is also some support for a cooperative threading mode (where each thread must manually give up its timeslice to swap out threads).
The thread scheduler itself is a relatively simplistic priority scheduler. There is no provision for priorities to erode over time, so keep that in mind. That practically means that if you have 2 high priority threads that are always runnable and one low priority thread that is always runnable, the low priority thread will never actually run (since it will never get to the front of the run queue because of the high priority threads).
The scheduler supports two distinct types of threads: joinable and detached threads. A joinable thread is one that can return a value to the creating thread (or for that matter, any other thread that wishes to join it). A detached thread is one taht is completely detached from the rest of the system and cannot return values by "normal" means. Detached threads automatically clean up all of the internal resources associated with the thread when it exits. Joinable threads, on the other hand, must keep some state available for the ability to return values. To make sure that all memory allocated by the thread's internal structures gets freed, you must either join with the thread (with thd_join()) or detach it (with thd_detach()). The old KOS threading system only had what would be considered detached threads.
#define PRIO_DEFAULT 10 |
Default thread priority. Threads are created by default with the priority specified.
#define PRIO_MAX 4096 |
Maximal thread priority. This macro defines the maximum value for a thread's priority. Note that the larger this number, the lower the priority of the thread.
Structure describing one running thread.
Each thread has one of this structure assigned to it, which hold all the data associated with the thread. There are various functions to manipulate the data in here, so you shouldn't generally do so manually.
void thd_add_to_runnable | ( | kthread_t * | t, |
int | front_of_line | ||
) |
Enqueue a process in the runnable queue.
This function adds a thread to the runnable queue after the process group of the same priority if front_of_line is zero, otherwise queues it at the front of its priority group. Generally, you will not have to do this manually.
t | The thread to queue. |
front_of_line | Set to 1 to put this thread in front of other threads of the same priority, 0 to put it behind the other threads (normal behavior). |
int thd_block_now | ( | irq_context_t * | mycxt | ) |
Block the current thread.
Blocks the calling thread and performs a reschedule as if a context switch timer had been executed. This is useful for, e.g., blocking on sync primitives. The param 'mycxt' should point to the calling thread's context block. This is implemented in arch-specific code.
The meaningfulness of the return value depends on whether the unblocker set a return value or not.
mycxt | The IRQ context of the calling thread. |
Given a thread ID, locates the thread structure.
tid | The thread ID to retrieve. |
irq_context_t* thd_choose_new | ( | ) |
Find a new thread to swap in.
This function looks at the state of the system and returns a new thread context to swap in. This is called from thd_block_now() and from the preemptive context switcher. Note that thd_current might be NULL on entering this function, if the caller blocked itself.
It is assumed that by the time this returns, the irq_srt_addr and thd_current will be updated.
kthread_t* thd_create | ( | int | detach, |
void *(*)(void *param) | routine, | ||
void * | param | ||
) |
Create a new thread.
This function creates a new kernel thread with default parameters to run the given routine. The thread will terminate and clean up resources when the routine completes if the thread is created detached, otherwise you must join the thread with thd_join() to clean up after it.
detach | Set to 1 to create a detached thread. Set to 0 to create a joinable thread. |
routine | The function to call in the new thread. |
param | A parameter to pass to the function called. |
int thd_destroy | ( | kthread_t * | thd | ) |
Brutally kill the given thread.
This function kills the given thread, removing it from the execution chain, cleaning up thread-local data and other internal structures. You should never call this function on the current thread. In general, you shouldn't call this function at all.
thd | The thread to destroy. |
0 | On success. |
int thd_detach | ( | kthread_t * | thd | ) |
Detach a joinable thread.
This function switches the specified thread's mode from THD_MODE_JOINABLE to THD_MODE_DETACHED. This will ensure that the thread cleans up all of its internal resources when it exits.
thd | The joinable thread to detach. |
void thd_exit | ( | void * | rv | ) |
Exit the current thread.
This function ends the execution of the current thread, removing it from all execution queues. This function will never return to the thread. Returning from the thread's function is equivalent to calling this function.
rv | The return value of the thread. |
kthread_t* thd_get_current | ( | ) |
Retrieve the current thread's kthread struct.
int* thd_get_errno | ( | kthread_t * | thd | ) |
Retrieve a pointer to the thread errno.
This function retrieves a pointer to the errno value for the thread. You should generally just use the errno variable to access this.
thd | The thread to retrieve from. |
const char* thd_get_label | ( | kthread_t * | thd | ) |
Retrieve the thread's label.
thd | The thread to retrieve from. |
const char* thd_get_pwd | ( | kthread_t * | thd | ) |
Retrieve the thread's current working directory.
This function retrieves the working directory of a thread. Generally, you will want to use either fs_getwd() or one of the standard C functions for doing this, but this is here in case you need it when the thread isn't active for some reason.
thd | The thread to retrieve from. |
struct _reent* thd_get_reent | ( | kthread_t * | thd | ) |
Retrieve a pointer to the thread reent struct.
This function is used to retrieve some internal state that is used by newlib to provide a reentrant libc.
thd | The thread to retrieve from. |
int thd_init | ( | int | mode | ) |
Initialize the threading system.
This is normally done for you by default when KOS starts. This will also initialize all the various synchronization primitives.
mode | One of the Threading system modes values. |
-1 | If threads are already initialized. |
0 | On success. |
int thd_join | ( | kthread_t * | thd, |
void ** | value_ptr | ||
) |
Wait for a thread to exit.
This function "joins" a joinable thread. This means effectively that the calling thread blocks until the speified thread completes execution. It is invalid to join a detached thread, only joinable threads may be joined.
thd | The joinable thread to join. |
value_ptr | A pointer to storage for the thread's return value, or NULL if you don't care about it. |
void thd_pass | ( | ) |
Throw away the current thread's timeslice.
This function manually yields the current thread's timeslice to the system, forcing a reschedule to occur.
int thd_pslist | ( | int(*)(const char *fmt,...) | pf | ) |
Print a list of all threads using the given print function.
pf | The printf-like function to print with. |
0 | On success. |
int thd_pslist_queue | ( | int(*)(const char *fmt,...) | pf | ) |
Print a list of all queued threads using the given print function.
pf | The printf-like function to print with. |
0 | On success. |
int thd_remove_from_runnable | ( | kthread_t * | thd | ) |
Removes a thread from the runnable queue, if it's there.
This function removes a thread from the runnable queue, if it is currently in that queue. Generally, you shouldn't have to do this manually, as waiting on synchronization primitives and the like will do this for you if needed.
thd | The thread to remove from the runnable queue. |
0 | On success, or if the thread isn't runnable. |
void thd_schedule | ( | int | front_of_line, |
uint64 | now | ||
) |
Force a thread reschedule.
This function is the thread scheduler, and is generally called from a timer interrupt, at least in preemptive mode. You will most likely never have a reason to call this function directly.
For most cases, you'll want to set front_of_line to zero, but read the comments in kernel/thread/thread.c for more info, especially if you need to guarantee low latencies. This function just updates irq_srt_addr and thd_current. Set 'now' to non-zero if you want to use a particular system time for checking timeouts.
front_of_line | Set to 0, unless you have a good reason not to. |
now | Set to 0, unless you have a good reason not to. |
void thd_schedule_next | ( | kthread_t * | thd | ) |
Force a given thread to the front of the queue.
This function promotes the given thread to be the next one that will be swapped in by the scheduler. This function is only callable inside an interrupt context (it simply returns otherwise).
void thd_set_label | ( | kthread_t * | thd, |
const char * | label | ||
) |
Set the thread's label.
This function sets the label of a thread, which is simply a human-readable string that is used to identify the thread. These labels aren't used for anything internally, and you can give them any label you want. These are mainly seen in the printouts from thd_pslist() or thd_pslist_queue().
thd | The thread to set the label of. |
label | The string to set as the label. |
int thd_set_mode | ( | int | mode | ) |
Change threading modes.
This function changes the current threading mode of the system.
mode | One of the Threading system modes values. |
Set a thread's priority value.
This function is used to change the priority value of a thread. If the thread is scheduled already, it will be rescheduled with the new priority value.
thd | The thread to change the priority of. |
prio | The priority value to assign to the thread. |
0 | On success. |
void thd_set_pwd | ( | kthread_t * | thd, |
const char * | pwd | ||
) |
Set the thread's current working directory.
This function will set the working directory of a thread. Generally, you will want to use either fs_chdir() or the standard C chdir() function to do this, but this is here in case you need to do it while the thread isn't active for some reason.
thd | The thread to set the working directory of. |
pwd | The directory to set as active. |
void thd_shutdown | ( | ) |
Shutdown the threading system.
This is done for you by the normal shutdown procedure of KOS. This will also shutdown all the various synchronization primitives.
void thd_sleep | ( | int | ms | ) |
Sleep for a given number of milliseconds.
This function puts the current thread to sleep for the specified amount of time. The thread will be removed from the runnable queue until the given number of milliseconds passes. That is to say that the thread will sleep for at least the given number of milliseconds. If another thread is running, it will likely sleep longer.
ms | The number of milliseconds to sleep. |
vuint32 jiffies |
"Jiffy" count.
This variable counts the number of context switches done by the threading system. Do not manipulate this variable directly!
kthread_t* thd_current |
The currently executing thread.
Do not manipulate this variable directly!
int thd_mode |
Are threads cooperative or preemptive?
Do not modify this variable directly. Instead, use the thd_set_mode() function to switch threading modes.