123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*
- * Mach Operating System
- * Copyright (c) 1993, 1992,1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
- #include <glue/gnulinux.h>
- #include <linux/printk.h>
- #include <linux/sched.h>
- #include <linux/sched/signal.h>
- #include <mach/message.h>
- #include <kern/counters.h>
- #include "cpu_number.h"
- #include <kern/debug.h>
- #include <kern/lock.h>
- #include <kern/mach_clock.h>
- #include <kern/thread.h>
- #include <kern/sched_prim.h>
- #include <kern/processor.h>
- #include <kern/thread_swap.h>
- #include <kern/ipc_sched.h>
- #if 0
- #include <machine/machspl.h> /* for splsched/splx */
- #include <machine/pmap.h>
- #endif
- #define linux_current get_current()
- //from darlinghq
- typedef unsigned long spl_t;
- extern unsigned long duct_ml_irqsave_setenabled (boolean_t enable){}
- extern void duct_ml_irqrestore (unsigned long flags){}
- #define splhigh() duct_ml_irqsave_setenabled (FALSE)
- #define splsched() duct_ml_irqsave_setenabled (FALSE)
- #define splclock() duct_ml_irqsave_setenabled (FALSE)
- #define splx(flags) duct_ml_irqrestore (flags)
- #define spllo() duct_ml_irqsave_setenabled (TRUE)
- /*
- * These functions really belong in kern/sched_prim.c.
- */
- /*
- * Routine: thread_go
- * Purpose:
- * Start a thread running.
- * Conditions:
- * IPC locks may be held.
- */
- void
- thread_go(
- thread_t thread)
- {
- int state;
- spl_t s;
- s = splsched();
- thread_lock(thread);
- //XXX: reset_timeout_check(&thread->timer);
- state = thread->state;
- switch (state & TH_SCHED_STATE) {
- case TH_WAIT | TH_SUSP | TH_UNINT:
- case TH_WAIT | TH_UNINT:
- case TH_WAIT:
- /*
- * Sleeping and not suspendable - put
- * on run queue.
- */
- thread->state = (state &~ TH_WAIT) | TH_RUN;
- thread->wait_result = THREAD_AWAKENED;
- //FIXME: thread_setrun(thread, TRUE);
- break;
- case TH_WAIT | TH_SUSP:
- case TH_RUN | TH_WAIT:
- case TH_RUN | TH_WAIT | TH_SUSP:
- case TH_RUN | TH_WAIT | TH_UNINT:
- case TH_RUN | TH_WAIT | TH_SUSP | TH_UNINT:
- /*
- * Either already running, or suspended.
- */
- thread->state = state & ~TH_WAIT;
- thread->wait_result = THREAD_AWAKENED;
- break;
- default:
- /*
- * Not waiting.
- */
- break;
- }
- thread_unlock(thread);
- splx(s);
- }
- /*
- * Routine: thread_will_wait
- * Purpose:
- * Assert that the thread intends to block.
- */
- void
- thread_will_wait(
- thread_t thread)
- {
- spl_t s;
- s = splsched();
- thread_lock(thread);
- assert(thread->wait_result = -1); /* for later assertions */
- thread->state |= TH_WAIT;
- thread_unlock(thread);
- splx(s);
- }
- /*
- * Routine: thread_will_wait_with_timeout
- * Purpose:
- * Assert that the thread intends to block,
- * with a timeout.
- */
- void
- thread_will_wait_with_timeout(
- thread_t thread,
- mach_msg_timeout_t msecs)
- {
- natural_t ticks = convert_ipc_timeout_to_ticks(msecs);
- spl_t s;
- s = splsched();
- thread_lock(thread);
- assert(thread->wait_result = -1); /* for later assertions */
- thread->state |= TH_WAIT;
- //FIXME: set_timeout(&thread->timer, ticks);
- thread_unlock(thread);
- splx(s);
- }
- #if MACH_HOST
- #define check_processor_set(thread) \
- (current_processor()->processor_set == (thread)->processor_set)
- #else /* MACH_HOST */
- #define check_processor_set(thread) TRUE
- #endif /* MACH_HOST */
- #if NCPUS > 1
- #define check_bound_processor(thread) \
- ((thread)->bound_processor == PROCESSOR_NULL || \
- (thread)->bound_processor == current_processor())
- #else /* NCPUS > 1 */
- #define check_bound_processor(thread) TRUE
- #endif /* NCPUS > 1 */
- kern_return_t thread_unblock(thread_t thread,kern_return_t wresult)
- {
- thread->wait_result = wresult;
- thread->state &= ~(TH_WAIT|TH_UNINT);
- if (!(thread->state & TH_RUN))
- thread->state |= TH_RUN;
-
- #if 0
- if (thread->wait_timer_is_set)
- {
- if (timer_call_cancel(&thread->wait_timer))
- thread->wait_timer_active--;
- thread->wait_timer_is_set = FALSE;
- }
- #endif
-
- struct task_struct* t = thread->linux_task;
- if (t != NULL)
- {
- wake_up_process(t);
- return KERN_SUCCESS;
- }
- return KERN_FAILURE;
- }
- void thread_block(continuation_t continuation)
- {
- thread_t thread = current_thread();
- //processor_t myprocessor = cpu_to_processor(cpu_number());
- //thread_t new_thread;
- spl_t s;
- check_simple_locks();
- s = splsched();
- #if FAST_TAS
- {
- extern void recover_ras();
- if (csw_needed(thread, myprocessor))
- recover_ras(thread);
- }
- #endif /* FAST_TAS */
- #if MACH_SCHED
- ast_off(cpu_number(), AST_BLOCK);
- do
- new_thread = thread_select(myprocessor);
- while (!thread_invoke(thread, continuation, new_thread));
- #endif
-
- thread_lock(thread);
- assert(thread->linux_task == linux_current);
- thread->state = TH_WAIT;
- printk(KERN_ERR "thread will block %x %x\n",thread,linux_current);
- #define current linux_current
- set_current_state(TASK_INTERRUPTIBLE);
- #undef current
- while ((thread->state & TH_WAIT) && linux_current->state != TASK_RUNNING)
- {
- thread_unlock(thread);
- /// printk("about to schedule - my state: %d\n", thread->linux_task->state);
- schedule();
- thread_lock(thread);
- if (signal_pending(linux_current))
- {
- //TODO set thread is interrupted
- thread->state |= TH_SIGNALED;
- break;
- }
- }
- thread_unlock(thread);
- printk(KERN_ERR "thread did block %x %x\n",thread,linux_current);
- splx(s);
-
- if(continuation)
- {
- printk(KERN_DEBUG "continuation invoke\n");
- void (*cont)(void) = continuation;
- cont();
- }
- }
|