コード例 #1
0
ファイル: thread.c プロジェクト: rafalcieslak/wifire-os
static void demo_thread_1() {
    int times = 3;

    kprintf("Thread '%s' started.\n", thread_self()->td_name);

    do {
        thread_switch_to(td2);
        kprintf("Thread '%s' running.\n", thread_self()->td_name);
    } while (--times);

    thread_switch_to(td0);
}
コード例 #2
0
ファイル: init.c プロジェクト: virtuoso/koowaldah
void __init kern_start()
{
	struct thread *main_thread;

	mach_start();

	kprintf("Starting Koowaldah v%s kernel.\n", VERSION_STRING);

	/* memory allocation machinery: zones, buddy allocator, slices */
	init_mem_info();
	paging_init();
	galloc_init();

	kqueue_init();

	timers_init();

	sched0_load();
	scheduler_init();
	main_thread = thread_create(&kernel_main_thread, "GOD", NULL);
	if (!main_thread) {
		kprintf("Failed to create main kernel thread\n");
		bug();
	}
	thread_switch_to(main_thread);

	bug();
}
コード例 #3
0
ファイル: thread.c プロジェクト: rafalcieslak/wifire-os
static void demo_thread_2() {
    int times = 3;

    kprintf("Thread '%s' started.\n", thread_self()->td_name);

    do {
        thread_switch_to(td1);
        kprintf("Thread '%s' running.\n", thread_self()->td_name);
    } while (--times);

    panic("This line need not be reached!");
}
コード例 #4
0
ファイル: thread.c プロジェクト: rafalcieslak/wifire-os
int main() {
    kprintf("Thread '%s' started.\n", thread_self()->td_name);

    td0 = thread_self();
    td1 = thread_create("first", demo_thread_1, NULL);
    td2 = thread_create("second", demo_thread_2, NULL);

    thread_switch_to(td1);

    kprintf("Thread '%s' running.\n", thread_self()->td_name);

    assert(td0 == thread_get_by_tid(td0->td_tid));
    assert(td1 == thread_get_by_tid(td1->td_tid));
    assert(td2 == thread_get_by_tid(td2->td_tid));
    assert(NULL == thread_get_by_tid(1234));

    thread_dump_all();

    thread_delete(td2);
    thread_delete(td1);

    return 0;
}
コード例 #5
0
ファイル: syscall.c プロジェクト: G4bzh/rhinos
PRIVATE u8_t syscall_receive(struct thread* th_receiver, struct proc* proc_sender)
{
  struct thread* th_available = NULL;

  /* Set receive state */
  th_receiver->ipc.state |= SYSCALL_IPC_RECEIVING;

  /* Set thread to receive from (can be NULL) */
  th_receiver->ipc.recv_from = proc_sender;

  /* Find a thread sending to me */
  th_available = syscall_find_waiting_sender(th_receiver->proc, proc_sender);
 
  /* A matching sender found ? */
  if ( th_available != NULL )
    {
      /* Copy message from sender to receiver */ 
      syscall_copymsg(th_available,th_receiver);
 
      arch_printf("%u receives a message from %u\n",th_receiver->proc->pid,th_available->proc->pid);

      /* Unblock sender */
      th_available->state = THREAD_READY;

      /* Set end of sending */
      th_available->ipc.state &= ~SYSCALL_IPC_SENDING;

      /* Remove sender from receiver waiting list et set it as ready for scheduling */
      LLIST_REMOVE(th_receiver->proc->wait_list, th_available);
      sched_enqueue(SCHED_READY_QUEUE, th_available);

      arch_printf("%u unblock  %u from its wait list\n",th_receiver->proc->pid,th_available->proc->pid);

      /* End of reception */
      th_receiver->ipc.state &= ~SYSCALL_IPC_RECEIVING;
      
    }
  else
    {
      /* No matching sender found: blocked waiting for a sender */
      th_receiver->state = THREAD_BLOCKED;

      /* Sched queues manipulation */
      sched_dequeue(SCHED_READY_QUEUE, th_receiver);
      sched_enqueue(SCHED_BLOCKED_QUEUE, th_receiver);

      arch_printf("%u blocked cause no message available\n",th_receiver->proc->pid);

      /* Current thread (receiver) is blocked, need scheduling */
      struct thread* th;
      th = sched_elect();
      
      /* Change address space */
      if (th->proc)
	{
	  arch_switch_addrspace(th->proc->addrspace);
	}  
      
      thread_switch_to(th);
      
    }
  
  return IPC_SUCCESS;
}
コード例 #6
0
ファイル: syscall.c プロジェクト: G4bzh/rhinos
PRIVATE u8_t syscall_send(struct thread* th_sender, struct proc* proc_receiver)
{

  struct thread* th_receiver;
  
  /* There must be a receiver - No broadcast allow */
  if ( proc_receiver == NULL )
    {
      arch_printf("send failed 1\n");
      return IPC_FAILURE;
    }

  /* Check for deadlock */
  if (syscall_deadlock(th_sender->proc,proc_receiver) == IPC_FAILURE)
    {
      arch_printf("deadlock\n");
      return IPC_FAILURE;
    }

  /* No deadlock here, set state */
  th_sender->ipc.state |= SYSCALL_IPC_SENDING;

  /* Set destination */
  th_sender->ipc.send_to = proc_receiver;

  /* Get a thread willing to receive the message */
  th_receiver = syscall_find_receiver(proc_receiver,th_sender->proc);

  if (th_receiver != NULL)
    {
      /* Found a thread ! copy message from sender to receiver */
      syscall_copymsg(th_sender,th_receiver);

      arch_printf("%u sends a message to %u\n",th_sender->proc->pid,proc_receiver->pid);
  
      /* Set end of reception */
      th_receiver->ipc.state &= ~SYSCALL_IPC_RECEIVING;

      /* Ready for scheduling */
      th_receiver->state = THREAD_READY;

      /* Scheduler queues manipulations */
      sched_dequeue(SCHED_BLOCKED_QUEUE, th_receiver);
      sched_enqueue(SCHED_READY_QUEUE, th_receiver);
      arch_printf("%u unblock %u after send\n",th_sender->proc->pid,proc_receiver->pid);
       

      /* Message is delivered to receiver, set end of sending */
      th_sender->ipc.state &= ~SYSCALL_IPC_SENDING;

       /* Scheduler queues manipulations (blocks sender) */
      sched_dequeue(SCHED_READY_QUEUE, th_sender);
      sched_enqueue(SCHED_BLOCKED_QUEUE, th_sender);
  
    }
  else
    {
      /* No receiving thread, enqueue in wait list */
      sched_dequeue(SCHED_READY_QUEUE, th_sender);
      LLIST_ADD(proc_receiver->wait_list,th_sender);
  
      arch_printf("%u in wait list of  %u\n",th_sender->proc->pid,proc_receiver->pid);
      
    }
  
  /* Sender is blocked, waiting for message processing (must be unblocked via notify) */
  arch_printf("%u block after send\n",th_sender->proc->pid);
  th_sender->state = THREAD_BLOCKED;

  /* In any cases, current thread (sender) is blocked, so scheduling is needing */
  struct thread* th;
  th = sched_elect();

 /* Change address space */
  if (th->proc)
    {
      arch_switch_addrspace(th->proc->addrspace);
    }  

  thread_switch_to(th);

  return IPC_SUCCESS;
}