5 #include <linux/futex.h>
8 #define CONFIG_RCU_HAVE_FUTEX 1
9 #include <urcu/futex.h>
11 #include <linux/rcupdate.h>
12 #include <linux/sched.h>
13 #include <linux/timer.h>
15 __thread struct task_struct *current;
17 void __put_task_struct(struct task_struct *t)
19 pthread_join(t->thread, NULL);
23 /* returns true if process was woken up, false if it was already running */
24 int wake_up_process(struct task_struct *p)
26 int ret = p->state != TASK_RUNNING;
28 p->state = TASK_RUNNING;
29 futex(&p->state, FUTEX_WAKE|FUTEX_PRIVATE_FLAG,
30 INT_MAX, NULL, NULL, 0);
38 rcu_quiescent_state();
40 while ((v = READ_ONCE(current->state)) != TASK_RUNNING)
41 futex(¤t->state, FUTEX_WAIT|FUTEX_PRIVATE_FLAG,
45 struct process_timer {
46 struct timer_list timer;
47 struct task_struct *task;
50 static void process_timeout(struct timer_list *t)
52 struct process_timer *timeout =
53 container_of(t, struct process_timer, timer);
55 wake_up_process(timeout->task);
58 long schedule_timeout(long timeout)
60 struct process_timer timer;
65 case MAX_SCHEDULE_TIMEOUT:
67 * These two special cases are useful to be comfortable
68 * in the caller. Nothing more. We could take
69 * MAX_SCHEDULE_TIMEOUT from one of the negative value
70 * but I' d like to return a valid offset (>=0) to allow
71 * the caller to do everything it want with the retval.
77 * Another bit of PARANOID. Note that the retval will be
78 * 0 since no piece of kernel is supposed to do a check
79 * for a negative retval of schedule_timeout() (since it
80 * should never happens anyway). You just have the printk()
81 * that will tell you if something is gone wrong and where.
84 fprintf(stderr, "schedule_timeout: wrong timeout "
85 "value %lx\n", timeout);
86 current->state = TASK_RUNNING;
91 expire = timeout + jiffies;
94 timer_setup_on_stack(&timer.timer, process_timeout, 0);
95 mod_timer(&timer.timer, expire);
97 del_timer_sync(&timer.timer);
99 timeout = expire - jiffies;
101 return timeout < 0 ? 0 : timeout;
104 __attribute__((constructor(101)))
105 static void sched_init(void)
107 struct task_struct *p = malloc(sizeof(*p));
109 memset(p, 0, sizeof(*p));
111 p->state = TASK_RUNNING;
112 atomic_set(&p->usage, 1);
113 init_completion(&p->exited);
118 rcu_register_thread();
121 #ifndef SYS_getrandom
123 #include <sys/stat.h>
124 #include <sys/types.h>
127 __attribute__((constructor(101)))
128 static void rand_init(void)
130 urandom_fd = open("/dev/urandom", O_RDONLY);
131 BUG_ON(urandom_fd < 0);