#ifndef _LINUX_SCHED_H_
#define _LINUX_SCHED_H_
#include <linux/capability.h>
#include <linux/threads.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/jiffies.h>
#include <linux/rbtree.h>
#include <linux/thread_info.h>
#include <linux/cpumask.h>
#include <linux/errno.h>
#include <linux/mm_types.h>
#include <linux/preempt.h>
#include <asm/page.h>
#include <linux/smp.h>
#include <linux/compiler.h>
#include <linux/completion.h>
#include <linux/pid.h>
#include <linux/rcupdate.h>
#include <linux/rculist.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/hrtimer.h>
#include <linux/llist.h>
#include <linux/gfp.h>
#include <asm/processor.h>
#include <linux/spinlock.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <sys/signal2.h>
#include <machine/cpu.h>
struct seq_file;
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
#define MAX_SCHEDULE_TIMEOUT LONG_MAX
#define TASK_COMM_LEN MAXCOMLEN
struct task_struct {
struct thread *dfly_td;
volatile long state;
struct mm_struct *mm;
int prio;
unsigned long kt_flags;
int (*kt_fn)(void *data);
void *kt_fndata;
int kt_exitvalue;
char comm[TASK_COMM_LEN];
atomic_t usage_counter;
pid_t pid;
struct spinlock kt_spin;
};
#define __set_current_state(state_value) current->state = (state_value);
#define set_current_state(state_value) \
do { \
__set_current_state(state_value); \
mb(); \
} while (0)
static inline long
schedule_timeout(signed long timeout)
{
int timo, flags, error;
unsigned long time_before, time_after;
long slept, ret = 0;
if (timeout < 0) {
kprintf("schedule_timeout(): timeout cannot be negative\n");
current->state = TASK_RUNNING;
return 0;
}
timo = timeout >= INT_MAX || timeout == MAX_SCHEDULE_TIMEOUT
? 0
: timeout;
spin_lock(¤t->kt_spin);
switch (current->state) {
case TASK_INTERRUPTIBLE:
flags = PCATCH;
break;
case TASK_UNINTERRUPTIBLE:
flags = 0;
break;
case TASK_RUNNING:
spin_unlock(¤t->kt_spin);
return timeout;
default:
panic("unreachable state %ld\n", current->state);
}
time_before = ticks;
error = ssleep(current, ¤t->kt_spin, flags, "lstim", timo);
time_after = ticks;
ret = 0;
if (error != EWOULDBLOCK) {
if (timeout == MAX_SCHEDULE_TIMEOUT) {
ret = MAX_SCHEDULE_TIMEOUT;
} else {
slept = time_after - time_before;
ret = timeout - slept;
if (ret <= 0)
ret = 1;
}
}
spin_unlock(¤t->kt_spin);
current->state = TASK_RUNNING;
return ret;
}
static inline void
schedule(void)
{
(void)schedule_timeout(MAX_SCHEDULE_TIMEOUT);
}
static inline signed long
schedule_timeout_uninterruptible(signed long timeout)
{
__set_current_state(TASK_UNINTERRUPTIBLE);
return schedule_timeout(timeout);
}
static inline long
io_schedule_timeout(signed long timeout)
{
return schedule_timeout(timeout);
}
static inline uint64_t
local_clock(void)
{
struct timespec ts;
getnanouptime(&ts);
return (ts.tv_sec * NSEC_PER_SEC) + ts.tv_nsec;
}
static inline void
yield(void)
{
lwkt_yield();
}
static inline int
wake_up_process(struct task_struct *tsk)
{
long ostate;
smp_wmb();
spin_lock(&tsk->kt_spin);
ostate = tsk->state;
tsk->state = TASK_RUNNING;
spin_unlock(&tsk->kt_spin);
if (ostate != TASK_RUNNING)
wakeup(tsk);
return 1;
}
static inline int
signal_pending(struct task_struct *p)
{
struct thread *t = p->dfly_td;
if (t->td_lwp == NULL)
return 0;
return CURSIG(t->td_lwp);
}
static inline int
fatal_signal_pending(struct task_struct *p)
{
struct thread *t = p->dfly_td;
sigset_t pending_set;
if (t->td_lwp == NULL)
return 0;
pending_set = lwp_sigpend(t->td_lwp);
return SIGISMEMBER(pending_set, SIGKILL);
}
static inline int
signal_pending_state(long state, struct task_struct *p)
{
if (state & TASK_INTERRUPTIBLE)
return (signal_pending(p));
else
return (fatal_signal_pending(p));
}
static inline int
cond_resched(void)
{
lwkt_yield();
return 0;
}
static inline int
send_sig(int sig, struct proc *p, int priv)
{
ksignal(p, sig);
return 0;
}
static inline void
set_need_resched(void)
{
}
static inline bool
need_resched(void)
{
return any_resched_wanted();
}
static inline int
sched_setscheduler_nocheck(struct task_struct *ts,
int policy, const struct sched_param *param)
{
return 0;
}
static inline int
pagefault_disabled(void)
{
return (curthread->td_flags & TDF_NOFAULT);
}
static inline void
mmgrab(struct mm_struct *mm)
{
atomic_inc(&mm->mm_count);
}
#endif