/* Switch execution transparently to thread TO.  The thread FROM,
   which must be the current thread, will be halted.  */
void
switch_thread (l4_thread_id_t from, l4_thread_id_t to)
{
  void *current_stack;
  /* FIXME: Figure out how much we need.  Probably only one return
     address.  */
  char small_sub_stack[16];
  unsigned int i;

/* FIXME: FROM is an argument to force gcc to evaluate it before the
   thread switch.  Maybe this can be done better, but it's
   magical, so be careful.  */

  /* Save the machine context.  */
  __asm__ __volatile__ ("pusha");
  __asm__ __volatile__ ("pushf");

  /* Start the TO thread.  It will be eventually become a clone of our
     thread.  */
  current_stack = __thread_stack_pointer ();
  l4_start_sp_ip (to, (l4_word_t) current_stack,
		  (l4_word_t) &&thread_switch_entry);
  
  /* We need a bit of extra space on the stack for
     l4_thread_switch.  */
  __thread_set_stack_pointer (small_sub_stack + sizeof (small_sub_stack));

  /* We can't use while(1), because then gcc will become clever and
     optimize away everything after thread_switch_entry.  */
  for (i = 1; i; i++)
    l4_thread_switch (to);

 thread_switch_entry:
  /* Restore the machine context.  */
  __asm__ __volatile__ ("popf");
  __asm__ __volatile__ ("popa");

  /* The thread TO continues here.  */
  l4_stop (from);
}
Example #2
0
int
cthread_sp(void)
{
	return (int) __thread_stack_pointer ();
}