X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=linux%2Fsched.c;h=1c7198d279bc9f534c946f2f56b65011a88ff452;hb=HEAD;hp=cc614b123ba36408176b70293204ec5e7d0725b6;hpb=8aaf7d913a382291f2770e6ce72a8919d5441bef;p=bcachefs-tools-debian diff --git a/linux/sched.c b/linux/sched.c index cc614b1..1c7198d 100644 --- a/linux/sched.c +++ b/linux/sched.c @@ -1,9 +1,13 @@ +#include #include #include +#include + +/* hack for mips: */ +#define CONFIG_RCU_HAVE_FUTEX 1 +#include -#include -#include #include #include #include @@ -19,38 +23,41 @@ void __put_task_struct(struct task_struct *t) /* returns true if process was woken up, false if it was already running */ int wake_up_process(struct task_struct *p) { - int ret; + int ret = p->state != TASK_RUNNING; - pthread_mutex_lock(&p->lock); - ret = p->state != TASK_RUNNING; p->state = TASK_RUNNING; - - pthread_cond_signal(&p->wait); - pthread_mutex_unlock(&p->lock); - + futex(&p->state, FUTEX_WAKE|FUTEX_PRIVATE_FLAG, + INT_MAX, NULL, NULL, 0); return ret; } void schedule(void) { - rcu_quiescent_state(); + int v; - pthread_mutex_lock(¤t->lock); - - while (current->state != TASK_RUNNING) - pthread_cond_wait(¤t->wait, ¤t->lock); + rcu_quiescent_state(); - pthread_mutex_unlock(¤t->lock); + while ((v = READ_ONCE(current->state)) != TASK_RUNNING) + futex(¤t->state, FUTEX_WAIT|FUTEX_PRIVATE_FLAG, + v, NULL, NULL, 0); } -static void process_timeout(unsigned long __data) +struct process_timer { + struct timer_list timer; + struct task_struct *task; +}; + +static void process_timeout(struct timer_list *t) { - wake_up_process((struct task_struct *)__data); + struct process_timer *timeout = + container_of(t, struct process_timer, timer); + + wake_up_process(timeout->task); } long schedule_timeout(long timeout) { - struct timer_list timer; + struct process_timer timer; unsigned long expire; switch (timeout) @@ -74,7 +81,7 @@ long schedule_timeout(long timeout) * that will tell you if something is gone wrong and where. */ if (timeout < 0) { - printk(KERN_ERR "schedule_timeout: wrong timeout " + fprintf(stderr, "schedule_timeout: wrong timeout " "value %lx\n", timeout); current->state = TASK_RUNNING; goto out; @@ -83,94 +90,25 @@ long schedule_timeout(long timeout) expire = timeout + jiffies; - setup_timer(&timer, process_timeout, (unsigned long)current); - mod_timer(&timer, expire); + timer.task = current; + timer_setup_on_stack(&timer.timer, process_timeout, 0); + mod_timer(&timer.timer, expire); schedule(); - del_timer_sync(&timer); + del_timer_sync(&timer.timer); timeout = expire - jiffies; out: return timeout < 0 ? 0 : timeout; } -unsigned long __msecs_to_jiffies(const unsigned int m) -{ - /* - * Negative value, means infinite timeout: - */ - if ((int)m < 0) - return MAX_JIFFY_OFFSET; - return _msecs_to_jiffies(m); -} - -u64 nsecs_to_jiffies64(u64 n) -{ -#if (NSEC_PER_SEC % HZ) == 0 - /* Common case, HZ = 100, 128, 200, 250, 256, 500, 512, 1000 etc. */ - return div_u64(n, NSEC_PER_SEC / HZ); -#elif (HZ % 512) == 0 - /* overflow after 292 years if HZ = 1024 */ - return div_u64(n * HZ / 512, NSEC_PER_SEC / 512); -#else - /* - * Generic case - optimized for cases where HZ is a multiple of 3. - * overflow after 64.99 years, exact for HZ = 60, 72, 90, 120 etc. - */ - return div_u64(n * 9, (9ull * NSEC_PER_SEC + HZ / 2) / HZ); -#endif -} - -unsigned long nsecs_to_jiffies(u64 n) -{ - return (unsigned long)nsecs_to_jiffies64(n); -} - -unsigned int jiffies_to_msecs(const unsigned long j) -{ -#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) - return (MSEC_PER_SEC / HZ) * j; -#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) - return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); -#else -# if BITS_PER_LONG == 32 - return (HZ_TO_MSEC_MUL32 * j) >> HZ_TO_MSEC_SHR32; -# else - return (j * HZ_TO_MSEC_NUM) / HZ_TO_MSEC_DEN; -# endif -#endif -} - -unsigned int jiffies_to_usecs(const unsigned long j) -{ - /* - * Hz usually doesn't go much further MSEC_PER_SEC. - * jiffies_to_usecs() and usecs_to_jiffies() depend on that. - */ - BUILD_BUG_ON(HZ > USEC_PER_SEC); - -#if !(USEC_PER_SEC % HZ) - return (USEC_PER_SEC / HZ) * j; -#else -# if BITS_PER_LONG == 32 - return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32; -# else - return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN; -# endif -#endif -} - __attribute__((constructor(101))) static void sched_init(void) { struct task_struct *p = malloc(sizeof(*p)); - mlockall(MCL_CURRENT|MCL_FUTURE); - memset(p, 0, sizeof(*p)); p->state = TASK_RUNNING; - pthread_mutex_init(&p->lock, NULL); - pthread_cond_init(&p->wait, NULL); atomic_set(&p->usage, 1); init_completion(&p->exited); @@ -180,7 +118,7 @@ static void sched_init(void) rcu_register_thread(); } -#ifndef __NR_getrandom +#ifndef SYS_getrandom #include #include #include