2 #include <linux/futex.h>
7 #define CONFIG_RCU_HAVE_FUTEX 1
8 #include <urcu/futex.h>
10 #include <linux/math64.h>
11 #include <linux/printk.h>
12 #include <linux/rcupdate.h>
13 #include <linux/sched.h>
14 #include <linux/slab.h>
15 #include <linux/timer.h>
17 __thread struct task_struct *current;
19 void __put_task_struct(struct task_struct *t)
21 pthread_join(t->thread, NULL);
25 /* returns true if process was woken up, false if it was already running */
26 int wake_up_process(struct task_struct *p)
28 int ret = p->state != TASK_RUNNING;
30 p->state = TASK_RUNNING;
31 futex(&p->state, FUTEX_WAKE|FUTEX_PRIVATE_FLAG,
32 INT_MAX, NULL, NULL, 0);
40 rcu_quiescent_state();
42 while ((v = current->state) != TASK_RUNNING)
43 futex(¤t->state, FUTEX_WAIT|FUTEX_PRIVATE_FLAG,
47 struct process_timer {
48 struct timer_list timer;
49 struct task_struct *task;
52 static void process_timeout(struct timer_list *t)
54 struct process_timer *timeout =
55 container_of(t, struct process_timer, timer);
57 wake_up_process(timeout->task);
60 long schedule_timeout(long timeout)
62 struct process_timer timer;
67 case MAX_SCHEDULE_TIMEOUT:
69 * These two special cases are useful to be comfortable
70 * in the caller. Nothing more. We could take
71 * MAX_SCHEDULE_TIMEOUT from one of the negative value
72 * but I' d like to return a valid offset (>=0) to allow
73 * the caller to do everything it want with the retval.
79 * Another bit of PARANOID. Note that the retval will be
80 * 0 since no piece of kernel is supposed to do a check
81 * for a negative retval of schedule_timeout() (since it
82 * should never happens anyway). You just have the printk()
83 * that will tell you if something is gone wrong and where.
86 printk(KERN_ERR "schedule_timeout: wrong timeout "
87 "value %lx\n", timeout);
88 current->state = TASK_RUNNING;
93 expire = timeout + jiffies;
96 timer_setup_on_stack(&timer.timer, process_timeout, 0);
97 mod_timer(&timer.timer, expire);
99 del_timer_sync(&timer.timer);
101 timeout = expire - jiffies;
103 return timeout < 0 ? 0 : timeout;
106 __attribute__((constructor(101)))
107 static void sched_init(void)
109 struct task_struct *p = malloc(sizeof(*p));
111 mlockall(MCL_CURRENT|MCL_FUTURE);
113 memset(p, 0, sizeof(*p));
115 p->state = TASK_RUNNING;
116 atomic_set(&p->usage, 1);
117 init_completion(&p->exited);
122 rcu_register_thread();
125 #ifndef __NR_getrandom
127 #include <sys/stat.h>
128 #include <sys/types.h>
131 __attribute__((constructor(101)))
132 static void rand_init(void)
134 urandom_fd = open("/dev/urandom", O_RDONLY);
135 BUG_ON(urandom_fd < 0);