]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - linux/sched.c
Merge pull request #229 from g2p/cli-symlink
[bcachefs-tools-debian] / linux / sched.c
index 11480f3cefd452169a7bcca04f5b3f7ec5842c3f..1c7198d279bc9f534c946f2f56b65011a88ff452 100644 (file)
@@ -1,8 +1,13 @@
 
+#include <stdio.h>
 #include <string.h>
+#include <sys/mman.h>
+#include <linux/futex.h>
+
+/* hack for mips: */
+#define CONFIG_RCU_HAVE_FUTEX 1
+#include <urcu/futex.h>
 
-#include <linux/math64.h>
-#include <linux/printk.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
@@ -18,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();
-
-       pthread_mutex_lock(&current->lock);
+       int v;
 
-       while (current->state != TASK_RUNNING)
-               pthread_cond_wait(&current->wait, &current->lock);
+       rcu_quiescent_state();
 
-       pthread_mutex_unlock(&current->lock);
+       while ((v = READ_ONCE(current->state)) != TASK_RUNNING)
+               futex(&current->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)
@@ -73,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;
@@ -82,82 +90,17 @@ 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)
 {
@@ -166,8 +109,6 @@ static void sched_init(void)
        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);
 
@@ -176,3 +117,17 @@ static void sched_init(void)
        rcu_init();
        rcu_register_thread();
 }
+
+#ifndef SYS_getrandom
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+int urandom_fd;
+
+__attribute__((constructor(101)))
+static void rand_init(void)
+{
+       urandom_fd = open("/dev/urandom", O_RDONLY);
+       BUG_ON(urandom_fd < 0);
+}
+#endif