From f5baaf48e3e82b1caf9f5cd1207d4d6feba3a2e5 Mon Sep 17 00:00:00 2001 From: Thomas Bertschinger Date: Mon, 15 Jan 2024 23:41:02 -0700 Subject: move Rust sources to top level, C sources into c_src This moves the Rust sources out of rust_src/ and into the top level. Running the bcachefs executable out of the development tree is now: $ ./target/release/bcachefs command or $ cargo run --profile release -- command instead of "./bcachefs command". Building and installing is still: $ make && make install Signed-off-by: Thomas Bertschinger Signed-off-by: Kent Overstreet --- c_src/linux/sched.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 c_src/linux/sched.c (limited to 'c_src/linux/sched.c') diff --git a/c_src/linux/sched.c b/c_src/linux/sched.c new file mode 100644 index 00000000..1c7198d2 --- /dev/null +++ b/c_src/linux/sched.c @@ -0,0 +1,133 @@ + +#include +#include +#include +#include + +/* hack for mips: */ +#define CONFIG_RCU_HAVE_FUTEX 1 +#include + +#include +#include +#include + +__thread struct task_struct *current; + +void __put_task_struct(struct task_struct *t) +{ + pthread_join(t->thread, NULL); + free(t); +} + +/* returns true if process was woken up, false if it was already running */ +int wake_up_process(struct task_struct *p) +{ + int ret = p->state != TASK_RUNNING; + + p->state = TASK_RUNNING; + futex(&p->state, FUTEX_WAKE|FUTEX_PRIVATE_FLAG, + INT_MAX, NULL, NULL, 0); + return ret; +} + +void schedule(void) +{ + int v; + + rcu_quiescent_state(); + + while ((v = READ_ONCE(current->state)) != TASK_RUNNING) + futex(¤t->state, FUTEX_WAIT|FUTEX_PRIVATE_FLAG, + v, NULL, NULL, 0); +} + +struct process_timer { + struct timer_list timer; + struct task_struct *task; +}; + +static void process_timeout(struct timer_list *t) +{ + struct process_timer *timeout = + container_of(t, struct process_timer, timer); + + wake_up_process(timeout->task); +} + +long schedule_timeout(long timeout) +{ + struct process_timer timer; + unsigned long expire; + + switch (timeout) + { + case MAX_SCHEDULE_TIMEOUT: + /* + * These two special cases are useful to be comfortable + * in the caller. Nothing more. We could take + * MAX_SCHEDULE_TIMEOUT from one of the negative value + * but I' d like to return a valid offset (>=0) to allow + * the caller to do everything it want with the retval. + */ + schedule(); + goto out; + default: + /* + * Another bit of PARANOID. Note that the retval will be + * 0 since no piece of kernel is supposed to do a check + * for a negative retval of schedule_timeout() (since it + * should never happens anyway). You just have the printk() + * that will tell you if something is gone wrong and where. + */ + if (timeout < 0) { + fprintf(stderr, "schedule_timeout: wrong timeout " + "value %lx\n", timeout); + current->state = TASK_RUNNING; + goto out; + } + } + + expire = timeout + jiffies; + + timer.task = current; + timer_setup_on_stack(&timer.timer, process_timeout, 0); + mod_timer(&timer.timer, expire); + schedule(); + del_timer_sync(&timer.timer); + + timeout = expire - jiffies; +out: + return timeout < 0 ? 0 : timeout; +} + +__attribute__((constructor(101))) +static void sched_init(void) +{ + struct task_struct *p = malloc(sizeof(*p)); + + memset(p, 0, sizeof(*p)); + + p->state = TASK_RUNNING; + atomic_set(&p->usage, 1); + init_completion(&p->exited); + + current = p; + + rcu_init(); + rcu_register_thread(); +} + +#ifndef SYS_getrandom +#include +#include +#include +int urandom_fd; + +__attribute__((constructor(101))) +static void rand_init(void) +{ + urandom_fd = open("/dev/urandom", O_RDONLY); + BUG_ON(urandom_fd < 0); +} +#endif -- cgit v1.2.3