Nucleus
Barry Improved context switching and interrupt handling d46e09a (3 years, 2 months ago)
#ifndef _NUCLEUS_TASK_H
#define _NUCLEUS_TASK_H
#include <stdint.h>
#include <sys/types.h>
#include <nucleus/cpu.h>
#include <nucleus/object.h>
#include <nucleus/memory.h>
#include <nucleus/vfs.h>
typedef struct Task Task;
typedef struct Signals Signals;
/* Task priorities */
enum Priority {
NONE,
LOWEST,
LOW,
NORMAL,
HIGH,
HIGHEST,
};
/* Task states */
enum State {
RUNNING,
READY,
TERMINATED,
WAITING,
};
/* Structure for a Task */
struct Task {
Object obj;
pid_t tid, tgid;
uid_t uid, euid, suid;
gid_t gid, egid, sgid;
int status;
enum Priority priority;
enum State state;
uint32_t inCriticalSection;
uint32_t inSyscall;
uintptr_t esi, edi, ebx;
uintptr_t esp, ebp, eip;
page_dir_t pageDir;
File *executable;
VMRegion *stack;
Task *target;
ObjectList *wait;
/* Namespaces */
FileSystem *fs;
Files *files;
VirtualMemory *vm;
Signals *signals;
};
extern ObjectType taskType;
extern ObjectType signalsType;
extern Task *currentTask[];
#define current currentTask[CPUID]
/* Check if super-user */
static inline int
super_user(void)
{
return (current->euid == 0);
}
/* Enter a critical section */
static inline void
enter_critical_section(void)
{
__atomic_add_fetch(¤t->inCriticalSection, 1, __ATOMIC_RELAXED);
}
/* Exit a critical section */
static inline void
exit_critical_section(void)
{
__atomic_sub_fetch(¤t->inCriticalSection, 1, __ATOMIC_RELAXED);
}
/* Enter system call context */
static inline void
enter_syscall_context(uint32_t syscall)
{
current->inSyscall = syscall;
}
/* Exit system call context */
static inline uint32_t
exit_syscall_context(void)
{
uint32_t syscall = current->inSyscall;
current->inSyscall = 0;
return syscall;
}
void init_tasking(void);
void block_task(enum State reason, ObjectList *list);
void unblock_task(Task *task);
Task *find_task(pid_t tid);
void schedule(void);
pid_t clone(int flags);
#endif