ipc_sched.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * Mach Operating System
  3. * Copyright (c) 1993, 1992,1991,1990 Carnegie Mellon University
  4. * All Rights Reserved.
  5. *
  6. * Permission to use, copy, modify and distribute this software and its
  7. * documentation is hereby granted, provided that both the copyright
  8. * notice and this permission notice appear in all copies of the
  9. * software, derivative works or modified versions, and any portions
  10. * thereof, and that both notices appear in supporting documentation.
  11. *
  12. * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13. * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14. * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15. *
  16. * Carnegie Mellon requests users of this software to return to
  17. *
  18. * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
  19. * School of Computer Science
  20. * Carnegie Mellon University
  21. * Pittsburgh PA 15213-3890
  22. *
  23. * any improvements or extensions that they make and grant Carnegie Mellon
  24. * the rights to redistribute these changes.
  25. */
  26. #include <glue/gnulinux.h>
  27. #include <linux/printk.h>
  28. #include <linux/sched.h>
  29. #include <linux/sched/signal.h>
  30. #include <mach/message.h>
  31. #include <kern/counters.h>
  32. #include "cpu_number.h"
  33. #include <kern/debug.h>
  34. #include <kern/lock.h>
  35. #include <kern/mach_clock.h>
  36. #include <kern/thread.h>
  37. #include <kern/sched_prim.h>
  38. #include <kern/processor.h>
  39. #include <kern/thread_swap.h>
  40. #include <kern/ipc_sched.h>
  41. #if 0
  42. #include <machine/machspl.h> /* for splsched/splx */
  43. #include <machine/pmap.h>
  44. #endif
  45. #define linux_current get_current()
  46. //from darlinghq
  47. typedef unsigned long spl_t;
  48. extern unsigned long duct_ml_irqsave_setenabled (boolean_t enable){}
  49. extern void duct_ml_irqrestore (unsigned long flags){}
  50. #define splhigh() duct_ml_irqsave_setenabled (FALSE)
  51. #define splsched() duct_ml_irqsave_setenabled (FALSE)
  52. #define splclock() duct_ml_irqsave_setenabled (FALSE)
  53. #define splx(flags) duct_ml_irqrestore (flags)
  54. #define spllo() duct_ml_irqsave_setenabled (TRUE)
  55. /*
  56. * These functions really belong in kern/sched_prim.c.
  57. */
  58. /*
  59. * Routine: thread_go
  60. * Purpose:
  61. * Start a thread running.
  62. * Conditions:
  63. * IPC locks may be held.
  64. */
  65. void
  66. thread_go(
  67. thread_t thread)
  68. {
  69. int state;
  70. spl_t s;
  71. s = splsched();
  72. thread_lock(thread);
  73. //XXX: reset_timeout_check(&thread->timer);
  74. state = thread->state;
  75. switch (state & TH_SCHED_STATE) {
  76. case TH_WAIT | TH_SUSP | TH_UNINT:
  77. case TH_WAIT | TH_UNINT:
  78. case TH_WAIT:
  79. /*
  80. * Sleeping and not suspendable - put
  81. * on run queue.
  82. */
  83. thread->state = (state &~ TH_WAIT) | TH_RUN;
  84. thread->wait_result = THREAD_AWAKENED;
  85. //FIXME: thread_setrun(thread, TRUE);
  86. break;
  87. case TH_WAIT | TH_SUSP:
  88. case TH_RUN | TH_WAIT:
  89. case TH_RUN | TH_WAIT | TH_SUSP:
  90. case TH_RUN | TH_WAIT | TH_UNINT:
  91. case TH_RUN | TH_WAIT | TH_SUSP | TH_UNINT:
  92. /*
  93. * Either already running, or suspended.
  94. */
  95. thread->state = state & ~TH_WAIT;
  96. thread->wait_result = THREAD_AWAKENED;
  97. break;
  98. default:
  99. /*
  100. * Not waiting.
  101. */
  102. break;
  103. }
  104. thread_unlock(thread);
  105. splx(s);
  106. }
  107. /*
  108. * Routine: thread_will_wait
  109. * Purpose:
  110. * Assert that the thread intends to block.
  111. */
  112. void
  113. thread_will_wait(
  114. thread_t thread)
  115. {
  116. spl_t s;
  117. s = splsched();
  118. thread_lock(thread);
  119. assert(thread->wait_result = -1); /* for later assertions */
  120. thread->state |= TH_WAIT;
  121. thread_unlock(thread);
  122. splx(s);
  123. }
  124. /*
  125. * Routine: thread_will_wait_with_timeout
  126. * Purpose:
  127. * Assert that the thread intends to block,
  128. * with a timeout.
  129. */
  130. void
  131. thread_will_wait_with_timeout(
  132. thread_t thread,
  133. mach_msg_timeout_t msecs)
  134. {
  135. natural_t ticks = convert_ipc_timeout_to_ticks(msecs);
  136. spl_t s;
  137. s = splsched();
  138. thread_lock(thread);
  139. assert(thread->wait_result = -1); /* for later assertions */
  140. thread->state |= TH_WAIT;
  141. //FIXME: set_timeout(&thread->timer, ticks);
  142. thread_unlock(thread);
  143. splx(s);
  144. }
  145. #if MACH_HOST
  146. #define check_processor_set(thread) \
  147. (current_processor()->processor_set == (thread)->processor_set)
  148. #else /* MACH_HOST */
  149. #define check_processor_set(thread) TRUE
  150. #endif /* MACH_HOST */
  151. #if NCPUS > 1
  152. #define check_bound_processor(thread) \
  153. ((thread)->bound_processor == PROCESSOR_NULL || \
  154. (thread)->bound_processor == current_processor())
  155. #else /* NCPUS > 1 */
  156. #define check_bound_processor(thread) TRUE
  157. #endif /* NCPUS > 1 */
  158. kern_return_t thread_unblock(thread_t thread,kern_return_t wresult)
  159. {
  160. thread->wait_result = wresult;
  161. thread->state &= ~(TH_WAIT|TH_UNINT);
  162. if (!(thread->state & TH_RUN))
  163. thread->state |= TH_RUN;
  164. #if 0
  165. if (thread->wait_timer_is_set)
  166. {
  167. if (timer_call_cancel(&thread->wait_timer))
  168. thread->wait_timer_active--;
  169. thread->wait_timer_is_set = FALSE;
  170. }
  171. #endif
  172. struct task_struct* t = thread->linux_task;
  173. if (t != NULL)
  174. {
  175. wake_up_process(t);
  176. return KERN_SUCCESS;
  177. }
  178. return KERN_FAILURE;
  179. }
  180. void thread_block(continuation_t continuation)
  181. {
  182. thread_t thread = current_thread();
  183. //processor_t myprocessor = cpu_to_processor(cpu_number());
  184. //thread_t new_thread;
  185. spl_t s;
  186. check_simple_locks();
  187. s = splsched();
  188. #if FAST_TAS
  189. {
  190. extern void recover_ras();
  191. if (csw_needed(thread, myprocessor))
  192. recover_ras(thread);
  193. }
  194. #endif /* FAST_TAS */
  195. #if MACH_SCHED
  196. ast_off(cpu_number(), AST_BLOCK);
  197. do
  198. new_thread = thread_select(myprocessor);
  199. while (!thread_invoke(thread, continuation, new_thread));
  200. #endif
  201. thread_lock(thread);
  202. assert(thread->linux_task == linux_current);
  203. thread->state = TH_WAIT;
  204. printk(KERN_ERR "thread will block %x %x\n",thread,linux_current);
  205. #define current linux_current
  206. set_current_state(TASK_INTERRUPTIBLE);
  207. #undef current
  208. while ((thread->state & TH_WAIT) && linux_current->state != TASK_RUNNING)
  209. {
  210. thread_unlock(thread);
  211. /// printk("about to schedule - my state: %d\n", thread->linux_task->state);
  212. schedule();
  213. thread_lock(thread);
  214. if (signal_pending(linux_current))
  215. {
  216. //TODO set thread is interrupted
  217. thread->state |= TH_SIGNALED;
  218. break;
  219. }
  220. }
  221. thread_unlock(thread);
  222. printk(KERN_ERR "thread did block %x %x\n",thread,linux_current);
  223. splx(s);
  224. if(continuation)
  225. {
  226. printk(KERN_DEBUG "continuation invoke\n");
  227. void (*cont)(void) = continuation;
  228. cont();
  229. }
  230. }