forked from Lephenixnoir/gint
673 lines
24 KiB
C
673 lines
24 KiB
C
#ifndef GINT_THREAD
|
|
# define GINT_THREAD
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdarg.h>
|
|
|
|
/* define the jmp_buf type */
|
|
#include <gint/std/setjmp.h>
|
|
|
|
/* Define the default context switching frequency */
|
|
#ifndef THREAD_SCHEDULER_FREQUENCY
|
|
# define THREAD_SCHEDULER_FREQUENCY 16
|
|
#endif
|
|
|
|
/* Define the default thread stack size */
|
|
#ifndef THREAD_STACK_SIZE
|
|
# define THREAD_STACK_SIZE (4 * 1024)
|
|
#endif
|
|
|
|
/* Define the default kernel idle thread's stack size */
|
|
#ifndef THREAD_IDLE_STACK_SIZE
|
|
# define THREAD_IDLE_STACK_SIZE 32
|
|
#endif
|
|
|
|
|
|
//---
|
|
// Thread attribute interface
|
|
//---
|
|
/* define the thread wartermark, used to check if the mutex is valid */
|
|
#define THREAD_ATTR_WATERMARK (~0xdeadbeef)
|
|
|
|
/* define the fundamental data type and alias for thread attribute */
|
|
struct thread_attr_s {
|
|
struct {
|
|
enum {
|
|
THREAD_ATTR_JOINABLE = 0,
|
|
THREAD_ATTR_DETACHED = 1,
|
|
} detach;
|
|
enum {
|
|
THREAD_ATTR_LONGJMP_DISABLE = 0,
|
|
THREAD_ATTR_LONGJMP_ENABLE = 1,
|
|
} longjmp;
|
|
} state;
|
|
struct {
|
|
uint32_t watermark;
|
|
} private;
|
|
};
|
|
typedef struct thread_attr_s thread_attr_t;
|
|
|
|
/* thread_attr_init(): Initialize thread attribute object
|
|
|
|
This function initializes the thread attributes object pointed to by ATTR
|
|
with default attribute values. After this call, individual attributes of the
|
|
object can be set using various related functions formatted like
|
|
"thread_attr_*()" and then the object can be used in one or more
|
|
"thread_create()" calls that create threads.
|
|
|
|
@return
|
|
* negative value if ATTR is NULL
|
|
* 0 if success */
|
|
extern int thread_attr_init(thread_attr_t *attr);
|
|
|
|
/* thread_attr_setdetachstate() and thread_attr_getdetachstate()
|
|
|
|
The "thread_attr_setdetachstate()" function sets the detach state attribute
|
|
of the thread attributes object referred to by attr to the value specified
|
|
in detachstate.
|
|
|
|
The detach state attribute determines whether a thread created using the
|
|
thread attributes object attr will be created in a joinable or a detached
|
|
state.
|
|
|
|
The following values may be specified in detachstate:
|
|
- THREAD_ATTR_DETACHED
|
|
Threads that are created using ATTR will be created in a detached state.
|
|
- THREAD_ATTR_JOINABLE
|
|
Threads that are created using attr will be created in a joinable state.
|
|
|
|
The default setting of the detach state attribute in a newly initialized
|
|
thread attributes object is THREAD_ATTR_JOINABLE.
|
|
|
|
The "thread_attr_getdetachstate()" returns the detach state attribute of
|
|
the thread attributes object attr in the buffer pointed to by detachstate.
|
|
|
|
@return
|
|
* negative value if ATTR is NULL or uninitialized
|
|
* 0 if success */
|
|
extern int thread_attr_setdetachstate(thread_attr_t *attr, int detachstate);
|
|
extern int thread_attr_getdetachstate(thread_attr_t *attr, int *detachstate);
|
|
|
|
|
|
/* thread_attr_enablelongjmp() thread_attr_getlongjmpstatus()
|
|
|
|
This feature is CUSTOM to the Gint kernel. It will allow, when a thread with
|
|
this attribute die, instead of release its memories and removed it from the
|
|
scheduler, allow it to perform a "longjmp()" and return ("rewinds") to the
|
|
"thread_create()" function involved to create the current thread. The
|
|
original "thread_create()" will return the special value:
|
|
THREAD_CREATE_LONGJMP_RETURN.
|
|
|
|
In the case of Gint, this feature is very useful because the "main" function
|
|
can be threaded and we can return the to "dark-side" of the kernel to manage
|
|
destructors or to recall the main function again. We cann allow this while
|
|
continuing running (potential) threaded drivers that can continue working
|
|
while being isolated from the Gint "bootstrap" part.
|
|
|
|
The following values may be specified in "status":
|
|
- THREAD_ATTR_LONGJMP_ENABLE
|
|
Enable the longjmp() when the thread come to the end.
|
|
- THREAD_ATTR_LONGJMP_DISABLE
|
|
Disable the longjmp() when the thread come to the end.
|
|
|
|
@return
|
|
* negative value if ATTR is NULL or uninitialized
|
|
* 0 if success */
|
|
extern int thread_attr_enablelongjmp(thread_attr_t *attr, int status);
|
|
extern int thread_attr_getlongjmpstatus(thread_attr_t *attr, int *status);
|
|
|
|
/* thread_attr_destroy(): Destroy thread attribute object
|
|
|
|
When a thread attributes object is no longer required, it should be destroyed
|
|
using the "pthread_attr_destroy()" function. Destroying a thread attributes
|
|
object has no effect on threads that were created using that object.
|
|
|
|
Once a thread attributes object has been destroyed, it can be reinitialized
|
|
using "thread_attr_init()". Any other use of a destroyed thread attributes
|
|
object has undefined results.
|
|
|
|
@return
|
|
* negative value if ATTR is NULL or uninitialized
|
|
* 0 if success */
|
|
extern int thread_attr_destroy(thread_attr_t *attr);
|
|
|
|
|
|
|
|
|
|
//---
|
|
// Signals interface
|
|
//
|
|
// A “signal” is a software interrupt delivered to a process. The operating
|
|
// system uses signals to report exceptional situations to an executing
|
|
// program. Some signals report errors such as references to invalid
|
|
// memory addresses; others report asynchronous events, such as
|
|
// disconnection of a phone line.
|
|
//
|
|
// If you anticipate an event that causes signals, you can define a handler
|
|
// function and tell the operating system to run it when that particular
|
|
// type of signal arrives.
|
|
//
|
|
// Finally, one thread can send a signal to another process; this allows a
|
|
// parent thread to abort a child, or two related thread to communicate
|
|
// and synchronize.
|
|
//
|
|
//---
|
|
/* Define thread signal set type */
|
|
typedef uint32_t sigset_t;
|
|
|
|
/* Define signals handler type */
|
|
typedef void (*sighandler_t)(int);
|
|
|
|
/* Define fake signal functions. */
|
|
#define SIG_ERR ((sighandler_t) -1) /* Error return. */
|
|
#define SIG_DFL ((sighandler_t) 0) /* Default action. */
|
|
#define SIG_IGN ((sighandler_t) 1) /* Ignore signal. */
|
|
|
|
/* Define the number of signals availbable */
|
|
#define NSIG 19
|
|
|
|
/* Define all signum
|
|
(note: All signals are not currently supported, but will be in near future)*/
|
|
#define SIGKILL 0 /* (unblockable) Killed */
|
|
#define SIGSTOP 1 /* (unblockable) Stop */
|
|
#define SIGTERM 2 /* (unblockable) Termination request. */
|
|
#define SIGCONT 3 /* Continue. */
|
|
#define SIGTRAP 4 /* Trace/breakpoint trap. */
|
|
#define SIGILL 5 /* Illegal instruction. */
|
|
#define SIGTSTP 6 /* Keyboard stop. */
|
|
#define SIGABRT 7 /* Abnormal termination. */
|
|
#define SIGCHLD 8 /* Child terminated or stopped. */
|
|
#define SIGPOLL 9 /* Pollable event occurred (System V). */
|
|
#define SIGVTALRM 10 /* Virtual timer expired. */
|
|
#define SIGPROF 11 /* Profiling timer expired. */
|
|
#define SIGUSR1 12 /* User-defined signal 1. */
|
|
#define SIGUSR2 13 /* User-defined signal 2. */
|
|
#define SIGHUP 14 /* hang up. */
|
|
#define SIGINT 15 /* interruption */
|
|
#define SIGBUS 16 /* bus error */
|
|
#define SIGFPE 17 /* fata aritmetic error */
|
|
#define SIGSEGV 18 /* segmentation violation */
|
|
|
|
|
|
|
|
|
|
//---
|
|
// User thread interface
|
|
//---
|
|
/* define special return value with the thread_create() function */
|
|
#define THREAD_CREATE_LONGJMP_RETURN (0xd1ceca5e)
|
|
|
|
/* Define thread ID alias */
|
|
typedef uint32_t thread_t;
|
|
|
|
/* cpu_ctx: whole SH3-based CPU hardware context definition */
|
|
struct cpu_ctx {
|
|
uint32_t reg[16];
|
|
uint32_t gbr;
|
|
uint32_t macl;
|
|
uint32_t mach;
|
|
uint32_t ssr;
|
|
uint32_t spc;
|
|
uint32_t pr;
|
|
};
|
|
|
|
/* struct thread: Thread structure definition */
|
|
struct thread {
|
|
/* hardware context */
|
|
struct cpu_ctx context;
|
|
|
|
/* thread configuration */
|
|
struct thread_attr_s attr;
|
|
|
|
/* signals information */
|
|
struct {
|
|
sighandler_t handler[NSIG];
|
|
sigset_t pending;
|
|
sigset_t blocking;
|
|
} signals;
|
|
|
|
/* thread scheduler information */
|
|
struct {
|
|
/* thread status */
|
|
enum {
|
|
THREAD_STATUS_PAUSED = 0,
|
|
THREAD_STATUS_RUNNING = 1,
|
|
THREAD_STATUS_ZOMBIE = 2,
|
|
THREAD_STATUS_DEAD = 3
|
|
} status;
|
|
|
|
/* thread identifier */
|
|
thread_t id;
|
|
|
|
/* hierarchical information */
|
|
struct thread *next;
|
|
} scheduler;
|
|
|
|
/* private information */
|
|
struct {
|
|
uintptr_t stack; /* original stack address */
|
|
uintptr_t ret; /* saved exit value */
|
|
jmp_buf jmpbuf; /* longjmp feature */
|
|
struct thread *sibling; /* sibling thread list */
|
|
struct thread *child; /* child thread list */
|
|
struct thread *parent; /* thread parent address */
|
|
} private;
|
|
};
|
|
|
|
/* thread_create(): Create a new thread
|
|
|
|
This function creates a new thread which starts execution by invoking
|
|
"start_routine()"; You can passe many argument as you want and
|
|
all args is passed as argument of start_routine().
|
|
|
|
The new thread terminates in one of the following ways:
|
|
- It calls "thread_exit()", specifying an exit status value that is
|
|
available to another thread in the same process that calls
|
|
"thread_join()"
|
|
- It returns from start_routine(). This is equivalent to calling
|
|
"thread_exit()" with the value supplied in the return statement.
|
|
- It is canceled (see "thread_cancel()").
|
|
- If one thread with the special THREAD_ATTR_MAIN_THREAD die. In this case,
|
|
all thread created with this special (custom) attribute will be killed
|
|
|
|
The "attr" argument points to a pthread_attr_t structure whose contents
|
|
are used at thread creation time to determine attributes for the new thread;
|
|
this structure is initialized using "thread_attr_init()" and related
|
|
functions. If "attr" is NULL, then the thread is created with default
|
|
attributes.
|
|
|
|
Before returning, a successful call to "thread_create()" stores the ID of
|
|
the new thread in the buffer pointed to by "thread"; this identifier is used
|
|
to refer to the thread in subsequent calls to other "thread_*" functions.
|
|
|
|
@return:
|
|
* negative value if error occurs
|
|
* 0 if success
|
|
*/
|
|
extern int thread_create(thread_t *thread,
|
|
thread_attr_t *attr, void *start_routine, ...);
|
|
|
|
/* Makes sure an argument is always provided, for va_arg() and for definite the
|
|
last arguments sended by the user */
|
|
#define THREAD_CREATE_ARG_END_WATERMARK (0xdeb0cad0)
|
|
#define thread_create(...) thread_create(__VA_ARGS__,\
|
|
THREAD_CREATE_ARG_END_WATERMARK)
|
|
|
|
/* thread_join(): Waits for the thread specified by thread to terminate
|
|
|
|
This function waits for the thread specified by thread to terminate.
|
|
If that thread has already terminated, then "thread_join()" returns
|
|
immediately. The thread specified by THREAD must be joinable.
|
|
|
|
If RETVAL is not NULL, then "thread_join()" copies the exit status of the
|
|
target thread (i.e., the value that the target thread supplied to
|
|
"thread_exit()") into the location pointed to by RETVAL. If the target thread
|
|
was canceled, then THREAD_CANCELED is placed in the location pointed to by
|
|
RETVAL.
|
|
|
|
If multiple threads simultaneously try to join with the same thread, the
|
|
results are undefined. If the thread calling "thread_join()" is canceled,
|
|
then the target thread will remain joinable (i.e., it will not be detached).
|
|
|
|
The "thread_tryjoin()" function have the same behaviour that the
|
|
"thread_join()" excet that it will not block the current thread and returns
|
|
directly if the wanted thread is busy or unjoinable.
|
|
|
|
@return:
|
|
* negative value if error occurs
|
|
* 0 if success */
|
|
extern int thread_join(thread_t thread, void **retvel);
|
|
extern int thread_tryjoin(thread_t thread, void **retval);
|
|
|
|
/* thread_exit(): Terminate the calling thread
|
|
|
|
This function will terminates the calling thread and returns a value via
|
|
retval that (if the thread is joinable) is available to another thread in the
|
|
same process that calls "thread_join()".
|
|
|
|
Any clean-up handlers established by pthread_cleanup_push(3) that have not
|
|
yet been popped, are popped (in the reverse of the order in which they were
|
|
pushed) and executed. If the thread has any thread-specific data, then, after
|
|
the clean-up handlers have been executed, the corresponding destructor
|
|
functions are called, in an unspecified order.
|
|
|
|
When a thread terminates, process-shared resources (e.g., mutexes, condition
|
|
variables, semaphores, and file descriptors) are not released. */
|
|
extern void thread_exit(void *retval);
|
|
|
|
/* thread_kill(): Send signal to a thread
|
|
|
|
This fucntion will raise any signals to any thread. The value of the thread
|
|
can have special value:
|
|
* if thread is positive then signal is sent to the thread with the ID
|
|
specified by thread.
|
|
* if thread is equals 0, then signal is sent to threads which have the
|
|
calling has parent.
|
|
|
|
@return:
|
|
* negative value if error occurs
|
|
* 0 if success */
|
|
extern int thread_kill(thread_t thread, int sig);
|
|
|
|
/* thread_signal(): sets the disposition of the signal signum to handler, which
|
|
is either SIG_IGN, SIG_DFL, or the address of a
|
|
programmer-defined function (a "signal handler").
|
|
|
|
This part provides a simple interface for establishing an action for a
|
|
particular signal.
|
|
|
|
If the signal signum is delivered to the process, then one of the following
|
|
happens:
|
|
- If the disposition is set to SIG_IGN, then the signal is ignored.
|
|
- If the disposition is set to SIG_DFL, then the default action associated
|
|
with the signal
|
|
- If the disposition is set to a function, then first either the disposition
|
|
is reset to SIG_DFL, or the signal is blocked, and then handler is called
|
|
with argument signum. If invocation of the handler caused the signal to
|
|
be blocked, then the signal is unblocked upon return from the handler.
|
|
|
|
The signals SIGKILL and SIGSTOP cannot be caught or ignored.
|
|
|
|
@return
|
|
the previous value of the signal handler, or SIG_ERR on error. */
|
|
extern void (*thread_signal(int signum, void (*handler)(int)))(int);
|
|
|
|
/* thread_terminate(): KERNEL-ONLY: destroy a thread
|
|
|
|
This function will destroy a thread regardless of its attributes, scheduler
|
|
status, ... This function is used by the kernel to remove definitively a
|
|
thread. */
|
|
extern int thread_terminate(struct thread *thread);
|
|
|
|
|
|
|
|
|
|
//---
|
|
// Thread mutex interface
|
|
//
|
|
// To have better control of resources and how threads access them, Gint
|
|
// implements a "mutex" object, which can help avoir race conditions and
|
|
// other concurrency issues. The term mutex refers to mutual exclusion.
|
|
//---
|
|
/* define the thread wartermark, used to check if the mutex is valid */
|
|
#define THREAD_MUTEX_WATERMARK 0xdeadbeef
|
|
|
|
/* mutex returnable value */
|
|
enum
|
|
{
|
|
thread_mutex_retval_success = 0,
|
|
thread_mutex_retval_busy = 1,
|
|
thread_mutex_retval_error = 2,
|
|
thread_mutex_retval_nomem = 3,
|
|
thread_mutex_retval_timeout = 4
|
|
};
|
|
|
|
/* mutex type */
|
|
enum
|
|
{
|
|
thread_mutex_type_plain = (1 << 1), /* non-recursive */
|
|
thread_mutex_type_recursive = (1 << 2), /* support recursive */
|
|
thread_mutex_type_timed = (2 << 3) /* support timeout */
|
|
};
|
|
|
|
/* define the fundamental data type and alias for thread mutex */
|
|
struct thread_mutex_s
|
|
{
|
|
uint32_t watermark;
|
|
uint32_t lock;
|
|
uint8_t type;
|
|
thread_t owner;
|
|
struct {
|
|
int id;
|
|
int abord;
|
|
} timer;
|
|
};
|
|
typedef struct thread_mutex_s thread_mutex_t;
|
|
|
|
|
|
/* thread_mutex_init(): Creates a new mutex object with type TYPE.
|
|
|
|
This function will initialize the mutex MUTEX using the type TYPE. The type
|
|
define the behaviour of the mutex, basically, you have:
|
|
- thread_mutex_type_plain
|
|
A mutex that does not support timeout, or test and return
|
|
- thread_mutex_type_recursive
|
|
A mutex that support recursive locking, which mean that the the owning
|
|
thread can lock it more than once without causing deadlock
|
|
- thread_mutex_type_timed
|
|
A mutex that supports timeout
|
|
|
|
Not all combinations of mutex types are valid for the TYPE argument.
|
|
Valid uses of mutex types for the TYPE argument are:
|
|
- thread_mutex_type_plain
|
|
A non-recursive mutex that does not support timeout
|
|
- thread_mutex_type_timed
|
|
A non-recursive mutex that does support timeout
|
|
- thread_mutex_type_plain | thread_mutex_type_timed
|
|
A recursive mutex that does not support timeout
|
|
- thread_mutex_type_timed | thread_mutex_type_timed
|
|
A recursive mutex that does support timeout
|
|
|
|
@return
|
|
* thread_mutex_retval_success If successful initialized
|
|
* thread_mutex_retval_error If error occur */
|
|
extern int thread_mutex_init(thread_mutex_t *mutex, int type);
|
|
|
|
/* thread_mutex_lock(): Block the current thread until the mutex is unlocked.
|
|
|
|
This function will bock the calling thread until the mutex is locked.
|
|
The behaviour is undefined if the current thread has already locked the
|
|
mutex and the mutex is not recursive.
|
|
|
|
Prior calls to "thread_mutex_unlock()" to the same mutex syncronize-with
|
|
this operations (if this operation success), and all lock/unlock operations
|
|
on any given mutex form a single total order (similar to the modification
|
|
order of an atomic).
|
|
|
|
@return:
|
|
* thread_mutex_retval_success If lock was obtained
|
|
* thread_mutex_retval_error If error occur */
|
|
extern int thread_mutex_lock(thread_mutex_t *mutex);
|
|
|
|
/* thread_mutex_timedlock(): Block the current thread until the mutex is
|
|
locked or until the time TIME has been reached.
|
|
|
|
This function will bock the calling thread until the mutex is locked or if
|
|
the time TIME (millisecond) has been reached. If the current has been
|
|
already locked the mutex and the mutex is not recursive, or if the mutex
|
|
does not support timeout an error will be returned.
|
|
|
|
Prior calls to "thread_mutex_unlock()" to the same mutex syncronize-with
|
|
this operations (if this operation success), and all lock/unlock operations
|
|
on any given mutex form a single total order (similar to the modification
|
|
order of an atomic).
|
|
|
|
@return:
|
|
* thread_mutex_retval_success if the lock was obtained
|
|
* thread_mutex_retval_error if error occur */
|
|
extern int thread_mutex_timedlock(thread_mutex_t *mutex, uint64_t delay_us);
|
|
|
|
/* thread_mutex_trylock(): Try to lock the mutex without blocking.
|
|
|
|
This function tries to lock the mutex without blocking. It return
|
|
immediately if the mutex is already locked.
|
|
|
|
Prior calls to "thread_mutex_unlock()" to the same mutex syncronize-with
|
|
this operations (if this operation success), and all lock/unlock operations
|
|
on any given mutex form a single total order (similar to the modification
|
|
order of an atomic).
|
|
|
|
@return:
|
|
* thread_mutex_retval_success if the lock was obtained
|
|
* thread_mutex_retval_busy if the mutex is already locked
|
|
* thread_mutex_retval_error if error occur */
|
|
extern int thread_mutex_trylock(thread_mutex_t *mutex);
|
|
|
|
/* thread_mutex_unlock(): Unlocks the mutex
|
|
|
|
This function synchronize-with subsequent "thread_mutex_lock()",
|
|
"thread_mutext_trylock()" and "thread_mutex_timedlock()" calls on the same
|
|
mutex. All lock/unlock operations on any given mutex form a signle total
|
|
order (similar to the modification order of an atomic).
|
|
|
|
@return:
|
|
* thread_mutex_retval_success if unlocked
|
|
* thread_mutex_retval_busy if not locked but need other unlock call
|
|
* thread_mutex_retval_error if error occur */
|
|
extern int thread_mutex_unlock(thread_mutex_t *mutex);
|
|
|
|
/* thread_mutex_destroy(): Destroy the mutex.
|
|
|
|
This function will destroy the mutex. If there are any thread waiting on the
|
|
mutex, the behaviour is undefined. */
|
|
extern void thread_mutex_destroy(thread_mutex_t *mutex);
|
|
|
|
|
|
|
|
|
|
//---
|
|
// Thread atomic operation
|
|
//---
|
|
/* thread_atomic_start(): Start atomic operation
|
|
|
|
This function will block interruptions and exception until
|
|
"thread_atomic_stop()" is called. This is really useful when you need to
|
|
secure some tricky part of code (like driver kernel-level implementation).
|
|
|
|
But be carefull: your code executed after this function SHOULD be
|
|
EXCEPTION-SAFE ! Otherwise, a crash will occur and Gint can do nothing to
|
|
avoid it because is hardware specific. If you need to secure shared data,
|
|
use mutex instead.
|
|
|
|
This implementation is recursive-safe and will return:
|
|
* SR value when you enter in "atomic" operation (first call)
|
|
* 0 if you are already in a "atomic" operation (x call)
|
|
To return to the "normal" operation, you should call "thread_atomic_stop()"
|
|
as many time as you have involved with "thread_atomic_start()". */
|
|
extern uint32_t thread_atomic_start(void);
|
|
|
|
/* thread_atomic_stop(): Stop atomic opration
|
|
|
|
This function will try to return to the "normal" mode and will return:
|
|
* negative value If error occur
|
|
* 0 If you are alwayrs in "atomic" mode
|
|
* the restored SR value If you are returned to the "clasic" mode */
|
|
extern uint32_t thread_atomic_stop(void);
|
|
|
|
|
|
|
|
|
|
//---
|
|
// Signals management (kernel-level)
|
|
//---
|
|
enum {
|
|
thread_signals_deliver_retval_running = 0,
|
|
thread_signals_deliver_retval_stopped = 1,
|
|
thread_signals_deliver_retval_dead = 2,
|
|
};
|
|
|
|
/* Macros for constructing status values. */
|
|
#define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
|
|
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
|
|
|
|
/* thread_signals_raise(): Raise a signal
|
|
|
|
This function will raise a signal for a given thread. This function is used
|
|
to raise kernel-based signals like SIGKILL. */
|
|
extern int thread_signals_raise(struct thread *thread, int sig);
|
|
|
|
/* thread_signals_deliver_pending(): Deliver all pending signals
|
|
|
|
This function is KERNEL-ONLY and SHOULD NEVER be called because it is
|
|
exclusively reserved for the internal thread scheduler. (see
|
|
<gint/thread/scheduler.c> for more information). */
|
|
extern int thread_signals_pending_deliver(struct thread *thread);
|
|
|
|
/* thread_signals_replace(): Replace current signal handler
|
|
|
|
This function will replace the signum signal handler with the new handler.
|
|
This part is used by the "thread_kill()" function. */
|
|
extern void (*thread_signals_replace(struct thread *thread,
|
|
int signum, void (*handler)(int)))(int);
|
|
|
|
/* thread_signals_sigreturn(): KERNEL-ONLY: Signals return handler
|
|
|
|
This function is involved when an custom signals handler come to the end. It
|
|
will restore previous context and stack then it will invalidate the current
|
|
thread to force the scheudler to not save the current thread context; this
|
|
mecanism will restore the previous context. */
|
|
extern void thread_signals_sigreturn(void);
|
|
|
|
|
|
|
|
//---
|
|
// Idle thread interface
|
|
//---
|
|
/* thread_idle_initialize(): Initialize the idle thread */
|
|
extern void thread_idle_init(void);
|
|
extern void thread_idle_uninit(void);
|
|
|
|
/* thread_idle_get(): Return the idle thread address */
|
|
extern struct thread *thread_idle_get(void);
|
|
|
|
|
|
|
|
|
|
//---
|
|
// Scheduler interface (kernel-only)
|
|
//---
|
|
/* thread_sched_initialize(): Initialize the scheduler */
|
|
extern void thread_sched_init(void);
|
|
extern void thread_sched_uninit(void);
|
|
|
|
/* thread_sched_start() / thread_sched_stop: Control the scheduler timer */
|
|
extern void thread_sched_start(void);
|
|
extern void thread_sched_stop(void);
|
|
|
|
/* thread_sched_add(): thread_sched_remove(): handle internal thread queue */
|
|
extern int thread_sched_add(struct thread *thread);
|
|
extern int thread_sched_remove(struct thread *thread);
|
|
|
|
/* thread_sched_find(): Find a thread strcuture using his ID */
|
|
extern struct thread *thread_sched_find(thread_t thread);
|
|
|
|
/* thread_sched_get_current(): Get the current thread context */
|
|
extern struct thread *thread_sched_get_current(void);
|
|
|
|
/* thread_sched_get_counter(): Return the number of thread in the queue */
|
|
extern int thread_sched_get_counter(void);
|
|
|
|
/* thread_sched_invalidate(): Invalidate the current thread.
|
|
|
|
This function will invalidate the current thread, it means that the current
|
|
thread will not be saved on the next schedule. This is really useful for the
|
|
signals' management to restore previously saved thread context.
|
|
|
|
You SHOULD never use it. */
|
|
extern void thread_sched_invalidate(void);
|
|
|
|
|
|
|
|
|
|
//---
|
|
// Kernel thread interface
|
|
//---
|
|
|
|
/* thread_kernel_terminate_trampoline(): Termination trampoline code.
|
|
|
|
This function is automatically involved when a thread return from his main
|
|
procedure and will invoke the "thread_exit()" function with the returned
|
|
value.
|
|
|
|
You SHOULD never use it. */
|
|
extern void thread_kernel_terminate_trampoline(void);
|
|
|
|
/* thread_kernel_yield(): Cause the calling thread to relinquish the CPU */
|
|
extern void thread_kernel_yield(void);
|
|
|
|
/* thread_kernel_exit(): Terminate the calling thread */
|
|
extern void thread_kernel_exit(void *retval);
|
|
|
|
#endif /* GINT_THREAD */
|