Exemple #1
0
int if_boot_interface(ifnet *i)
{
	int err;

	// create the receive thread
	i->rx_thread = thread_create_kernel_thread("net_rx_thread", &if_rx_thread, i);
	if(i->rx_thread < 0) {
		err = i->rx_thread;
		goto err1;
	}
	thread_set_priority(i->rx_thread, THREAD_MAX_RT_PRIORITY - 2);

	// create the transmit thread
	i->tx_thread = thread_create_kernel_thread("net_tx_thread", &if_tx_thread, i);
	if(i->tx_thread < 0) {
		err = i->tx_thread;
		goto err2;
	}
	thread_set_priority(i->tx_thread, THREAD_MAX_RT_PRIORITY - 2);

	// start the threads
	thread_resume_thread(i->rx_thread);
	thread_resume_thread(i->tx_thread);

	return NO_ERROR;

err2:
	thread_kill_thread_nowait(i->rx_thread);
err1:
	return err;
}
Exemple #2
0
void
test_priority_fifo (void) 
{
  struct simple_thread_data data[THREAD_CNT];
  struct lock lock;
  int *output, *op;
  int i, cnt;

  /* This test does not work with the MLFQS. */
  ASSERT (selected_scheduler != SCH_MLFQS);

  /* Make sure our priority is the default. */
  ASSERT (thread_get_priority () == PRI_DEFAULT);

  msg ("%d threads will iterate %d times in the same order each time.",
       THREAD_CNT, ITER_CNT);
  msg ("If the order varies then there is a bug.");

  output = op = malloc (sizeof *output * THREAD_CNT * ITER_CNT * 2);
  ASSERT (output != NULL);
  lock_init (&lock);

  thread_set_priority (PRI_DEFAULT + 2);
  for (i = 0; i < THREAD_CNT; i++) 
    {
      char name[16];
      struct simple_thread_data *d = data + i;
      snprintf (name, sizeof name, "%d", i);
      d->id = i;
      d->iterations = 0;
      d->lock = &lock;
      d->op = &op;
      thread_create (name, PRI_DEFAULT + 1, simple_thread_func, d);
    }

  thread_set_priority (PRI_DEFAULT);
  /* All the other threads now run to termination here. */
  ASSERT (lock.holder == NULL);

  cnt = 0;
  for (; output < op; output++) 
    {
      struct simple_thread_data *d;

      ASSERT (*output >= 0 && *output < THREAD_CNT);
      d = data + *output;
      if (cnt % THREAD_CNT == 0)
        printf ("(priority-fifo) iteration:");
      printf (" %d", d->id);
      if (++cnt % THREAD_CNT == 0)
        printf ("\n");
      d->iterations++;
    }
}
Exemple #3
0
static void priceil_set(mtx_t * mtx)
{
    if (MTX_OPT(mtx, MTX_OPT_PRICEIL)) {
        mtx->pri.p_saved = thread_get_priority(current_thread->id);
        thread_set_priority(current_thread->id, mtx->pri.p_lock);
    }
}
Exemple #4
0
static int
hc_init_callback(void *hooks, void *hc_cookie)
{
	usb_hc *hc;

	SHOW_FLOW(1, "cookie %p", hc_cookie);

	hc = (usb_hc *)kmalloc(sizeof(usb_hc));
	if(!hc)
		return ERR_NO_MEMORY;

	memset(hc, 0, sizeof(*hc));

	hc->hooks = hooks;
	hc->hc_cookie = hc_cookie;

	// add it to the list of host controllers
	hc->next = usb->hc_list;
	usb->hc_list = hc;

	// create an enumerator thread
	hc->enumerator_thread = thread_create_kernel_thread("usb bus enumerator", &usb_enumerator_thread, hc);
	thread_set_priority(hc->enumerator_thread, THREAD_MIN_RT_PRIORITY);
	thread_resume_thread(hc->enumerator_thread);

	return NO_ERROR;
}
Exemple #5
0
static int ui_menu_item_down()
{
	thread_set_priority(HIGHEST_PRIORITY);

	if (menu_chosen_item == (menu_item_number - 1)) {
		menu_chosen_item = 0;
	} else {
		menu_chosen_item++;
	}

	/* redraw the menu with new highlight item */
	ui_menu_redraw(MENU_HIGHLIGHT_DOWN);

    thread_set_priority(DEFAULT_PRIORITY);
	return 0;
}
void test_priority_donate_lower(void) {

  struct lock lock;

  /* This test does not work with the MLFQS. */
  ASSERT(!thread_mlfqs);

  /* Make sure our priority is the default. */
  ASSERT(thread_get_priority () == PRI_DEFAULT);

  lock_init(&lock);
  lock_acquire(&lock);
  thread_create("acquire", PRI_DEFAULT + 10, acquire_thread_func, &lock);

  msg("Main thread should have priority %d.  Actual priority: %d.", PRI_DEFAULT + 10, thread_get_priority ());

  msg("Lowering base priority...");

  thread_set_priority(PRI_DEFAULT - 10);

  msg("Main thread should have priority %d.  Actual priority: %d.", PRI_DEFAULT + 10, thread_get_priority ());
  
  lock_release(&lock);

  msg("acquire must already have finished.");

  msg("Main thread should have priority %d.  Actual priority: %d.", PRI_DEFAULT - 10, thread_get_priority ());

}
Exemple #7
0
static int ui_menu_item_up()
{
	thread_set_priority(HIGHEST_PRIORITY);

	if (menu_chosen_item == 0) {
		menu_chosen_item = menu_item_number - 1;
	} else {
		menu_chosen_item--;
	}

	/* redraw the menu with new highlight item */
	ui_menu_redraw(MENU_HIGHLIGHT_UP);

	thread_set_priority(DEFAULT_PRIORITY);
	return 0;
}
Exemple #8
0
void
test_priority_sema (void) 
{
  int i;
  
  /* This test does not work with the MLFQS. */
  ASSERT (!thread_mlfqs);

  sema_init (&sema, 0);
  thread_set_priority (PRI_MIN);


  for (i = 0; i < 10; i++) 
    {
      int priority = PRI_DEFAULT - (i + 3) % 10 - 1;
      char name[16];
      snprintf (name, sizeof name, "priority %d", priority);
      thread_create (name, priority, priority_sema_thread, NULL);
    }


  for (i = 0; i < 10; i++) 
    {
      sema_up (&sema);
      msg ("Back in main thread."); 
    }
}
/* Set the voice thread priority */
void voice_thread_set_priority(int priority)
{
    if (priority > PRIORITY_VOICE)
        priority = PRIORITY_VOICE;

    thread_set_priority(voice_thread_id, priority);
}
void
test_priority_condvar (void) 
{
  int i;
  
  /* This test does not work with the MLFQS. */
  ASSERT (!thread_mlfqs);

  lock_init (&lock);
  cond_init (&condition);

  thread_set_priority (PRI_MIN);
  for (i = 0; i < 10; i++) 
    {
      int priority = PRI_DEFAULT - (i + 7) % 10 - 1;
      char name[16];
      snprintf (name, sizeof name, "priority %d", priority);
      thread_create (name, priority, priority_condvar_thread, NULL);
    }

  for (i = 0; i < 10; i++) 
    {
      lock_acquire (&lock);
      msg ("Signaling...");
      cond_signal (&condition, &lock);
      lock_release (&lock);
    }
}
Exemple #11
0
static void priceil_restore(mtx_t * mtx)
{
    if (MTX_OPT(mtx, MTX_OPT_PRICEIL)) {
        /*
         * RFE There is a very rare race condition if some other thread tries to
         * set a new priority for this thread just after this if clause.
         */
        if (thread_get_priority(current_thread->id) == mtx->pri.p_lock)
            thread_set_priority(current_thread->id, mtx->pri.p_saved);
    }
}
Exemple #12
0
void
test_priority_change (void) 
{
  /* This test does not work with the MLFQS. */
  ASSERT (!thread_mlfqs);
  msg ("Creating a high-priority thread 2.");
  thread_create ("thread 2", PRI_DEFAULT + 1, changing_thread, NULL);
  msg ("Thread 2 should have just lowered its priority.");
  thread_set_priority (PRI_DEFAULT - 2);
  msg ("Thread 2 should have just exited.");
}
Exemple #13
0
static void if_rx_thread(void *args)
{
    ifnet *i = args;
    cbuf *b;

    t_current_set_name("IF Recv");
#if IF_PRIO
    thread_set_priority(i->rx_thread, THREAD_MAX_RT_PRIORITY - 2);
#endif
    //if(i->fd < 0)        return -1;

    for(;;) {
        ssize_t len;

        //len = sys_read(i->fd, i->rx_buf, 0, sizeof(i->rx_buf));
        len = i->dev->dops.read(i->dev, i->rx_buf, sizeof(i->rx_buf));

#if 0||NET_CHATTY
        dprintf("if_rx_thread: got ethernet packet, size %ld\n", (long)len);
#endif
        if(len < 0) {
            thread_snooze(10000);
            continue;
        }
        if(len == 0)
            continue;

#if LOSE_RX_PACKETS
        if(rand() % 100 < LOSE_RX_PERCENTAGE) {
            dprintf("if_rx_thread: purposely lost packet, size %d\n", len);
            continue;
        }
#endif

        // check to see if we have a link layer address attached to us
        if(!i->link_addr) {
#if 1||NET_CHATTY
            dprintf("if_rx_thread: dumping packet because of no link address (%p)\n", i);
#endif
            continue;
        }

        // for now just move it over into a cbuf
        b = cbuf_get_chain(len);
        if(!b) {
            dprintf("if_rx_thread: could not allocate cbuf to hold ethernet packet\n");
            continue;
        }
        cbuf_memcpy_to_chain(b, 0, i->rx_buf, len);

        i->link_input(b, i);
    }

}
Exemple #14
0
void io_thread_init_functor::operator()() const
{
#ifdef NOVA_TT_PRIORITY_RT
    int priority = thread_priority_interval_rt().first;
    thread_set_priority_rt(priority);
#else
    int priority = thread_priority_interval().second;
    thread_set_priority(priority);
#endif

    name_thread("Network Send");
}
thread_t *
thread_create (
    thread_init_func initial_function,
    unsigned long stack_size,
    void *init_arg)
{
  thread_t *thr;

  assert (_main_thread != NULL);

  if (stack_size == 0)
    stack_size = THREAD_STACK_SIZE;

#if (SIZEOF_VOID_P == 8)
  stack_size *= 2;
#endif
#if defined (__x86_64 ) && defined (SOLARIS)
  /*GK: the LDAP on that platform requires that */
  stack_size *= 2;
#endif

  /* Any free threads with the right stack size? */
  for (thr = (thread_t *) _deadq.thq_head.thr_next;
       thr != (thread_t *) &_deadq.thq_head;
       thr = (thread_t *) thr->thr_hdr.thr_next)
    {
      if (thr->thr_stack_size >= stack_size)
	break;
    }

  if (thr == (thread_t *) &_deadq.thq_head)
    {
      /* No free fiber, create a new one */
      thr = thread_allocate ();
      _fiber_for_thread (thr, stack_size);
      _thread_num_total++;
    }
  else
    {
      /* Set new context for the thread */
      memcpy (thr->thr_context, thr->thr_init_context, sizeof (jmp_buf));
    }

  thr->thr_initial_function = initial_function;
  thr->thr_initial_argument = init_arg;
  thread_set_priority (thr, NORMAL_PRIORITY);
  _thread_init_attributes (thr);
  _fiber_status (thr, RUNNABLE);

  return thr;
}
Exemple #16
0
/* inline since branch is chosen at compile time */
static inline void usb_slave_mode(bool on)
{
#ifdef USE_ROCKBOX_USB
    int rc;

    if (on)
    {
        trigger_cpu_boost();
#ifdef HAVE_PRIORITY_SCHEDULING
        thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME);
#endif
        usb_attach();
    }
    else /* usb_state == USB_INSERTED (only!) */
    {
#ifndef USB_DETECT_BY_DRV
        usb_enable(false);
#endif
#ifdef HAVE_PRIORITY_SCHEDULING
        thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM);
#endif
        /* Entered exclusive mode */
        rc = disk_mount_all();
        if (rc <= 0) /* no partition */
            panicf("mount: %d",rc);

        cancel_cpu_boost();
    }
#else /* !USE_ROCKBOX_USB */
    if (on)
    {
        /* until we have native mass-storage mode, we want to reboot on
           usb host connect */
        try_reboot();
    }
#endif /* USE_ROCKBOX_USB */
}
int
shell_main (void)
{
  printf ("Shell starting...\n");
  for (;;) 
    {
      char command[80];

      /* Read command. */
      printf ("$> ");
      read_line (command, sizeof command);
      
      /* Execute command. */
      if (!strcmp (command, "exit"))
        break;
      else if (!memcmp (command, "run ", 4))
       {
	 userprog = 0;
         if (!memcmp (command + 4, "mlfqs", 4))
            thread_mlfqs = true;
         run_test (command + 4);
         thread_mlfqs = false;
	 userprog = 1;
         thread_set_priority (PRI_DEFAULT);
       }
      else if (!memcmp (command, "cd ", 3)) 
        chdir (command + 3);
      else if (command[0] == '\0') 
        {
          /* Empty command. */
        }
      else
        {
#ifdef USERPROG
          int pid = process_execute (command);
          if (pid != -1)
           {
             int status = process_wait (pid);
             printf ("%s: exit(%d)\n", command, status);
           }
          else
            printf ("exec failed\n");
#endif
        }
    }

  printf ("Shell exiting.");
  return 0;
}
Exemple #18
0
static void if_tx_thread(void *args)
{
    ifnet *i = args;
    cbuf *buf;
    ssize_t len;

    t_current_set_name("IF Xmit");

#if IF_PRIO
    thread_set_priority(i->tx_thread, THREAD_MAX_RT_PRIORITY - 2);
#endif
    //if(i->fd < 0)        return -1;


//printf("if %x tx thread inited", i);
    for(;;) {
        sem_acquire(i->tx_queue_sem);
//printf("if %x tx thread gogo\n", i);

        for(;;) {
            // pull a packet out of the queue
            mutex_lock(&i->tx_queue_lock);
            buf = fixed_queue_dequeue(&i->tx_queue);
            mutex_unlock(&i->tx_queue_lock);
            if(!buf)
                break;

#if LOSE_TX_PACKETS
            if(rand() % 100 < LOSE_TX_PERCENTAGE) {
                cbuf_free_chain(buf);
                continue;
            }
#endif

            // put the cbuf chain into a flat buffer
            len = cbuf_get_len(buf);
            cbuf_memcpy_from_chain(i->tx_buf, buf, 0, len);

            cbuf_free_chain(buf);

#if 0||NET_CHATTY
            dprintf("if_tx_thread: sending packet size %ld\n", (long)len);
#endif
            //sys_write(i->fd, i->tx_buf, 0, len);
            i->dev->dops.write(i->dev, i->tx_buf, len);
        }
    }
}
/*
 *  The main thread must call this function to convert itself into a thread.
 */
thread_t *
thread_initial (unsigned long stack_size)
{
  if (_main_thread)
    return _main_thread;
  else
    {
      NEW_VARZ (thread_t, thr);
      _main_thread = thr;
      thr->thr_status = RUNNING;
      thr->thr_sem = semaphore_allocate (0);
      thr->thr_schedule_sem = semaphore_allocate (0);
      _thread_init_attributes (thr);
      thread_set_priority (thr, NORMAL_PRIORITY);
      return thr;
    }
}
Exemple #20
0
void giveup_priority(){
	/*
	int temp;
	int max=thread_current()->absolute_priority;
	struct list_elem *e;
	if(!list_empty(&thread_current()->lock_list)){
	for(e=list_begin(&thread_current()->lock_list);e!=list_end (&thread_current()->lock_list);
	           e = list_next (e))
	{
		struct lock* lock_=list_entry(e,struct lock,elem);
		if(!list_empty(&lock_->semaphore.waiters))
		{
			temp=(list_entry(list_max(&lock_->semaphore.waiters,thread_max_priority,NULL), struct thread, elem))->priority;
			if(temp > max)
				max=temp;
		}
	}
	}*/
	//thread_current()->priority=max;
	thread_set_priority(thread_current()->absolute_priority);
}
void
test_priority_donate_chain (void) 
{
  int i;
  struct lock locks[NESTING_DEPTH - 1];
  struct lock_pair lock_pairs[NESTING_DEPTH];

  /* This test does not work with the MLFQS. */
  ASSERT (!thread_mlfqs);

  thread_set_priority (PRI_MIN);

  for (i = 0; i < NESTING_DEPTH - 1; i++)
    lock_init (&locks[i]);

  lock_acquire (&locks[0]);
  msg ("%s got lock.", thread_name ());

  for (i = 1; i < NESTING_DEPTH; i++)
    {
      char name[16];
      int thread_priority;

      snprintf (name, sizeof name, "thread %d", i);
      thread_priority = PRI_MIN + i * 3;
      lock_pairs[i].first = i < NESTING_DEPTH - 1 ? locks + i: NULL;
      lock_pairs[i].second = locks + i - 1;

      thread_create (name, thread_priority, donor_thread_func, lock_pairs + i);
      msg ("%s should have priority %d.  Actual priority: %d.",
          thread_name (), thread_priority, thread_get_priority ());

      snprintf (name, sizeof name, "interloper %d", i);
      thread_create (name, thread_priority - 1, interloper_thread_func, NULL);
    }

  lock_release (&locks[0]);
  msg ("%s finishing with priority %d.", thread_name (),
                                         thread_get_priority ());
}
/* Releases LOCK, which must be owned by the current thread.

   An interrupt handler cannot acquire a lock, so it does not
   make sense to try to release a lock within an interrupt
   handler. */
void
lock_release (struct lock *lock) 
{
  ASSERT (lock != NULL);
  ASSERT (lock_held_by_current_thread (lock));

  ASSERT (lock != NULL);
  ASSERT (lock_held_by_current_thread (lock));

  lock->holder = NULL;
  
  /* Added for priority donation. */
  struct thread *highest_waiter;
  highest_waiter = lock->highest_waiter;
  lock->highest_waiter = NULL;
  
  sema_up (&lock->semaphore);
  
  /* Added for priority donation. */
  if (highest_waiter != NULL)
  {
    if (!list_empty (&thread_current ()->waiting_threads))
    {
      list_remove (&highest_waiter->waiting_elem);
      highest_waiter->waiting_for = NULL;

      if (!list_empty (&thread_current ()->waiting_threads))
      {
        struct thread *highest_priority_thread = list_entry (list_begin (&thread_current ()->waiting_threads), 
			struct thread, waiting_elem);
	thread_revert_priority (highest_priority_thread->priority);
      }
      else
      {
        int old_priority = thread_current ()->priority_orig;
	thread_current ()->priority_orig = -1;
	thread_set_priority (old_priority);
      }
    }
/*
 *  The main thread must call this function to convert itself into a fiber.
 */
thread_t *
thread_initial (unsigned long stack_size)
{
  static unsigned int marker = THREAD_STACK_MARKER;

  if (_current_fiber)
    return _current_fiber;
  else
    {
      NEW_VARZ (thread_t, thr);

      assert (_current_fiber == NULL);
      _main_thread = _current_fiber = thr;

      _sched_init ();

      if (stack_size == 0)
	stack_size = MAIN_STACK_SIZE;

#if (SIZEOF_VOID_P == 8)
      stack_size *= 2;
#endif
#if defined (__x86_64 ) && defined (SOLARIS)
  /*GK: the LDAP on that platform requires that */
  stack_size *= 2;
#endif

      thr->thr_stack_marker = &marker;
      thr->thr_sem = semaphore_allocate (0);
      thr->thr_schedule_sem = semaphore_allocate (0);
      thread_set_priority (thr, NORMAL_PRIORITY);
      _thread_init_attributes (thr);
      _fiber_for_thread (thr, stack_size);

      _fiber_status (thr, RUNNING);

      return thr;
    }
}
Exemple #24
0
void a_main (void) {

    struct remote_state rstate;
    memset(&rstate, 0, sizeof(rstate));

    //init mutexes and set period for bluethooth monitoring
    if (mutex_create(&rstate.mutex) != 0) error();
    // I think we will need a mutex for the roomba too.
   // if (mutex_create(&rstate.roomba_lock)!=0) error();

    rstate.period.tv_nsec = 10000000ULL;
    rstate.bluetooth_uart = 1;
    rstate.light_sensor_threshold = calculate_light_threshold();

    // Setup UART
    struct uart_opt uopt;
    memset(&uopt, 0, sizeof(uopt));
    uopt.baud = 9600;
    if (uart_init(rstate.bluetooth_uart, uopt) != 0) error();

    // Roomba
    uart_t roomba_uart = 2;

    if (roomba_create(&rstate.roomba, roomba_uart) != 0) error();
    if (roomba_safe_mode(&rstate.roomba) != 0) error();

    if (thread_set_priority(thread_self(), 0)!=0) error();

    if (roomba_song_load_death(&rstate.roomba, SONG_NUMBER_DEATH) != 0) error();

    //start the roomba test func
    if (thread_create(0, roomba_job, 0, &rstate)!=0) error();

    if (thread_create(0, sensor_job, 0, &rstate) !=0) error();

    //turn main thread into uart (bluethooth) thread
    handle_bluetooth(&rstate);

}
static bool lazy_initialize(void) {
  assert(alarms == NULL);

  pthread_mutex_init(&monitor, NULL);

  alarms = list_new(NULL);
  if (!alarms) {
    LOG_ERROR("%s unable to allocate alarm list.", __func__);
    return false;
  }

  struct sigevent sigevent;
  memset(&sigevent, 0, sizeof(sigevent));
  sigevent.sigev_notify = SIGEV_THREAD;
  sigevent.sigev_notify_function = (void (*)(union sigval))timer_callback;
  if (timer_create(CLOCK_ID, &sigevent, &timer) == -1) {
    LOG_ERROR("%s unable to create timer: %s", __func__, strerror(errno));
    return false;
  }

  alarm_expired = semaphore_new(0);
  if (!alarm_expired) {
    LOG_ERROR("%s unable to create alarm expired semaphore", __func__);
    return false;
  }

  callback_thread_active = true;
  callback_thread = thread_new("alarm_callbacks");
  if (!callback_thread) {
    LOG_ERROR("%s unable to create alarm callback thread.", __func__);
    return false;
  }

  thread_set_priority(callback_thread, CALLBACK_THREAD_PRIORITY_HIGH);
  thread_post(callback_thread, callback_dispatch, NULL);
  return true;
}
Exemple #26
0
/* Releases LOCK, which must be owned by the current thread.

   An interrupt handler cannot acquire a lock, so it does not
   make sense to try to release a lock within an interrupt
   handler. */
void
lock_release (struct lock *lock) 
{
  ASSERT (lock != NULL);
  ASSERT (lock_held_by_current_thread (lock));

  //enum intr_level old_level;
  //old_level = intr_disable();

  //PRE LOCK HOLDER MUST BE THE LOWER ONE , AND HIGHER ONE IS STILL WAITING FOR THE LOWER ONE
  //THE HIGHER ONE 'S CURRENT PRIORITY IS LOWER ONE'S
  if (thread_mlfqs)
  { //roozbeh
	//no need for checking priority donations
    lock->holder = NULL;
 	sema_up (&lock->semaphore);
  }
   else
  {
    struct thread *cur = thread_current();

  //NEW
  //duc: remove lock from list and remove lock holder from lock
    lock->holder = NULL;
    list_remove(&lock->elem);
  /*if any priority change to the donee happends inside the donation,it will save it and restore it after donation finished */
  /*been_donated_aux==is_any_priority_change_when_this_thread_is_in_the_case_of_donation*/
    if (cur-> been_donated_aux)
    {
	  thread_set_priority(cur->saved_priority);
	  cur->been_donated_aux = false;
    }
    sema_up(&lock->semaphore);

    take_back_donation(cur);
  }
}
Exemple #27
0
void
test_alarm_priority (void) 
{
  int i;
  
  /* This test does not work with the MLFQS. */
  ASSERT (!enable_mlfqs);

  wake_time = timer_ticks () + 5 * TIMER_FREQ;
  sema_init (&wait_sema, 0);
  
  for (i = 0; i < 10; i++) 
    {
      int priority = (i + 5) % 10 + PRI_DEFAULT + 1;
      char name[16];
      snprintf (name, sizeof name, "priority %d", priority);
      thread_create (name, priority, alarm_priority_thread, NULL);
    }

  thread_set_priority (PRI_MAX);

  for (i = 0; i < 10; i++)
    sema_down (&wait_sema);
}
Exemple #28
0
void
test_alarm_priority (void)
{
  int i;

  /* This test does not work with the MLFQS. */
  ASSERT (selected_scheduler != SCH_MLFQS);

  wake_time = timer_ticks () + 5 * TIMER_FREQ;
  sema_init (&wait_sema, 0);

  for (i = 0; i < 10; i++)
    {
      int priority = PRI_DEFAULT - (i + 5) % 10 - 1;
      char name[16];
      snprintf (name, sizeof name, "priority %d", priority);
      thread_create (name, priority, alarm_priority_thread, NULL);
    }

  thread_set_priority (PRI_MIN);

  for (i = 0; i < 10; i++)
    sema_down (&wait_sema);
}
thread_t *
thread_create (
    thread_init_func initial_function,
    unsigned long stack_size,
    void *initial_argument)
{
  thread_t *thr;
  int rc;

  assert (_main_thread != NULL);

  if (stack_size == 0)
    stack_size = THREAD_STACK_SIZE;

#if (SIZEOF_VOID_P == 8)
  stack_size *= 2;
#endif
#if defined (__x86_64 ) && defined (SOLARIS)
  /*GK: the LDAP on that platform requires that */
  stack_size *= 2;
#endif
#ifdef HPUX_ITANIUM64
  stack_size += 8 * 8192;
#endif

  stack_size = ((stack_size / 8192) + 1) * 8192;

#if defined (PTHREAD_STACK_MIN)
  if (stack_size < PTHREAD_STACK_MIN)
    {
      stack_size = PTHREAD_STACK_MIN;
    }
#endif
  /* Any free threads with the right stack size? */
  Q_LOCK ();
  for (thr = (thread_t *) _deadq.thq_head.thr_next;
       thr != (thread_t *) &_deadq.thq_head;
       thr = (thread_t *) thr->thr_hdr.thr_next)
    {
      /* if (thr->thr_stack_size >= stack_size) */
	break;
    }
  Q_UNLOCK ();

  /* No free threads, create a new one */
  if (thr == (thread_t *) &_deadq.thq_head)
    {
#ifndef OLD_PTHREADS
      size_t os_stack_size = stack_size;
#endif
      thr = thread_alloc ();
      thr->thr_initial_function = initial_function;
      thr->thr_initial_argument = initial_argument;
      thr->thr_stack_size = stack_size;
      if (thr->thr_cv == NULL)
	goto failed;

#ifdef HPUX_ITANIUM64
      if (stack_size > PTHREAD_STACK_MIN)
        {
	  size_t s, rses;
          pthread_attr_getstacksize (&_thread_attr, &s);
	  pthread_attr_getrsestacksize_np (&_thread_attr, &rses);
	  log_error ("default rses=%d stack=%d : %m", rses,s);
	}
#endif


#ifndef OLD_PTHREADS
# if  defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
      rc = pthread_attr_setstacksize (&_thread_attr, stack_size);
      if (rc)
	{
          log_error ("Failed setting the OS thread stack size to %d : %m", stack_size);
	}
# endif

#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE)
      if (0 == pthread_attr_getstacksize (&_thread_attr, &os_stack_size))
	{
	  if (os_stack_size > 4 * 8192)
	    stack_size = thr->thr_stack_size = ((unsigned long) os_stack_size) - 4 * 8192;
	}
#endif
#ifdef HPUX_ITANIUM64
      if (stack_size > PTHREAD_STACK_MIN)
        {
	  size_t rsestack_size = stack_size / 2;
          rc = pthread_attr_setrsestacksize_np (&_thread_attr, rsestack_size);
	  if (rc)
	    {
	      log_error ("Failed setting the OS thread 'rse' stack size to %d (plain stack size set to %d) : %m", rsestack_size, stack_size);
	    }
	  thr->thr_stack_size /= 2;
	}
#endif

      rc = pthread_create ((pthread_t *) thr->thr_handle, &_thread_attr,
	  _thread_boot, thr);
      CKRET (rc);

      /* rc = pthread_detach (*(pthread_t *) thr->thr_handle); */
      /* CKRET (rc); */

#else /* OLD_PTHREAD */
      rc = pthread_attr_setstacksize (&_thread_attr, stack_size);
      CKRET (rc);

      rc = pthread_create ((pthread_t *) thr->thr_handle, _thread_attr,
	  _thread_boot, thr);
      CKRET (rc);

      /* rc = pthread_detach ((pthread_t *) thr->thr_handle); */
      /* CKRET (rc); */
#endif

      _thread_num_total++;
#if 0
      if (DO_LOG(LOG_THR))
	log_info ("THRD_0 OS threads create (%i)", _thread_num_total);
#endif
      thread_set_priority (thr, NORMAL_PRIORITY);
    }
  else
    {
      Q_LOCK ();
      thread_queue_remove (&_deadq, thr);
      _thread_num_dead--;
      Q_UNLOCK ();
      assert (thr->thr_status == DEAD);
      /* Set new context for the thread and resume it */
      thr->thr_initial_function = initial_function;
      thr->thr_initial_argument = initial_argument;
      thr->thr_status = RUNNABLE;
      rc = pthread_cond_signal ((pthread_cond_t *) thr->thr_cv);
      CKRET (rc);
/*    if (DO_LOG(LOG_THR))
	log_info ("THRD_3 OS threads reuse. Info threads - total (%ld) wait (%ld) dead (%ld)",
            _thread_num_total, _thread_num_wait, _thread_num_dead);*/
    }

  return thr;

failed:
  if (thr->thr_status == RUNNABLE)
    {
      _thread_free_attributes (thr);
      dk_free (thr, sizeof (thread_t));
    }
  return NULL;
}
Exemple #30
0
int _main( int argc, char *argv[] )
{
	//BSS is in DATA section so IOS doesnt touch it, we need to manually clear it
	//dbgprintf("memset32(%08x, 0, %08x)\n", &__bss_start, &__bss_end - &__bss_start);
	memset32(&__bss_start, 0, &__bss_end - &__bss_start);
	sync_after_write(&__bss_start, &__bss_end - &__bss_start);

	s32 ret = 0;
	u32 DI_Thread = 0;

	u8 MessageHeap[0x10];

	BootStatus(0, 0, 0);

	thread_set_priority( 0, 0x79 );	// do not remove this, this waits for FS to be ready!
	thread_set_priority( 0, 0x50 );
	thread_set_priority( 0, 0x79 );

//Disable AHBPROT
	EnableAHBProt(-1);

//Load IOS Modules
	ES_Init( MessageHeap );

//Early HID for loader
	HIDInit();

//Enable DVD Access
	write32(HW_DIFLAGS, read32(HW_DIFLAGS) & ~DI_DISABLEDVD);

	dbgprintf("Sending signal to loader\r\n");
	BootStatus(1, 0, 0);
	mdelay(10);

//Loader running, selects games
	while(1)
	{
		sync_before_read((void*)RESET_STATUS, 0x20);
		vu32 reset_status = read32(RESET_STATUS);
		if(reset_status != 0)
		{
			if(reset_status == 0x0DEA)
				break; //game selected
			else if(reset_status == 0x1DEA)
				goto DoIOSBoot; //exit
			write32(RESET_STATUS, 0);
			sync_after_write((void*)RESET_STATUS, 0x20);
		}
		HIDUpdateRegisters(1);
		mdelay(10);
	}
	ConfigSyncBeforeRead();

	u32 UseUSB = ConfigGetConfig(NIN_CFG_USB);
	SetDiskFunctions(UseUSB);

	BootStatus(2, 0, 0);
	if(UseUSB)
	{
		ret = USBStorage_Startup();
		dbgprintf("USB:Drive size: %dMB SectorSize:%d\r\n", s_cnt / 1024 * s_size / 1024, s_size);
	}
	else
	{
		s_size = PAGE_SIZE512; //manually set s_size
		ret = SDHCInit();
	}
	if(ret != 1)
	{
		dbgprintf("Device Init failed:%d\r\n", ret );
		BootStatusError(-2, ret);
		mdelay(4000);
		Shutdown();
	}

	//Verification if we can read from disc
	if(memcmp(ConfigGetGamePath(), "di", 3) == 0)
		RealDI_Init(); //will shutdown on fail

	BootStatus(3, 0, 0);
	fatfs = (FATFS*)malloca( sizeof(FATFS), 32 );

	s32 res = f_mount( fatfs, fatDevName, 1 );
	if( res != FR_OK )
	{
		dbgprintf("ES:f_mount() failed:%d\r\n", res );
		BootStatusError(-3, res);
		mdelay(4000);
		Shutdown();
	}
	
	BootStatus(4, 0, 0);

	BootStatus(5, 0, 0);

	FIL fp;
	s32 fres = f_open_char(&fp, "/bladie", FA_READ|FA_OPEN_EXISTING);
	switch(fres)
	{
		case FR_OK:
			f_close(&fp);
		case FR_NO_PATH:
		case FR_NO_FILE:
		{
			fres = FR_OK;
		} break;
		default:
		case FR_DISK_ERR:
		{
			BootStatusError(-5, fres);
			mdelay(4000);
			Shutdown();
		} break;
	}

	if(!UseUSB) //Use FAT values for SD
		s_cnt = fatfs->n_fatent * fatfs->csize;

	BootStatus(6, s_size, s_cnt);

	BootStatus(7, s_size, s_cnt);
	ConfigInit();

	if (ConfigGetConfig(NIN_CFG_LOG))
		SDisInit = 1;  // Looks okay after threading fix
	dbgprintf("Game path: %s\r\n", ConfigGetGamePath());

	BootStatus(8, s_size, s_cnt);

	memset32((void*)RESET_STATUS, 0, 0x20);
	sync_after_write((void*)RESET_STATUS, 0x20);

	memset32((void*)0x13002800, 0, 0x30);
	sync_after_write((void*)0x13002800, 0x30);
	memset32((void*)0x13160000, 0, 0x20);
	sync_after_write((void*)0x13160000, 0x20);

	memset32((void*)0x13026500, 0, 0x100);
	sync_after_write((void*)0x13026500, 0x100);

	BootStatus(9, s_size, s_cnt);

	DIRegister();
	DI_Thread = thread_create(DIReadThread, NULL, ((u32*)&__di_stack_addr), ((u32)(&__di_stack_size)) / sizeof(u32), 0x78, 1);
	thread_continue(DI_Thread);

	DIinit(true);

	BootStatus(10, s_size, s_cnt);

	GCAMInit();

	EXIInit();

	BootStatus(11, s_size, s_cnt);

	SIInit();
	StreamInit();

	PatchInit();
//Tell PPC side we are ready!
	cc_ahbMemFlush(1);
	mdelay(1000);
	BootStatus(0xdeadbeef, s_size, s_cnt);
	mdelay(1000); //wait before hw flag changes
	dbgprintf("Kernel Start\r\n");

	//write32( 0x1860, 0xdeadbeef );	// Clear OSReport area
	//sync_after_write((void*)0x1860, 0x20);

	u32 Now = read32(HW_TIMER);
	u32 PADTimer = Now;
	u32 DiscChangeTimer = Now;
	u32 ResetTimer = Now;
	u32 InterruptTimer = Now;
	USBReadTimer = Now;
	u32 Reset = 0;
	bool SaveCard = false;
	if( ConfigGetConfig(NIN_CFG_LED) )
	{
		set32(HW_GPIO_ENABLE, GPIO_SLOT_LED);
		clear32(HW_GPIO_DIR, GPIO_SLOT_LED);
		clear32(HW_GPIO_OWNER, GPIO_SLOT_LED);
	}
	set32(HW_GPIO_ENABLE, GPIO_SENSOR_BAR);
	clear32(HW_GPIO_DIR, GPIO_SENSOR_BAR);
	clear32(HW_GPIO_OWNER, GPIO_SENSOR_BAR);
	set32(HW_GPIO_OUT, GPIO_SENSOR_BAR);	//turn on sensor bar

	write32( HW_PPCIRQMASK, (1<<30) );
	write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) );

//This bit seems to be different on japanese consoles
	u32 ori_ppcspeed = read32(HW_PPCSPEED);
	if((ConfigGetGameID() & 0xFF) == 'J')
		set32(HW_PPCSPEED, (1<<17));
	else
		clear32(HW_PPCSPEED, (1<<17));

	u32 ori_widesetting = read32(0xd8006a0);
	if(IsWiiU)
	{
		if( ConfigGetConfig(NIN_CFG_WIIU_WIDE) )
			write32(0xd8006a0, 0x30000004);
		else
			write32(0xd8006a0, 0x30000002);
		mask32(0xd8006a8, 0, 2);
	}
	while (1)
	{
		_ahbMemFlush(0);

		//Does interrupts again if needed
		if(TimerDiffTicks(InterruptTimer) > 15820) //about 120 times a second
		{
			sync_before_read((void*)INT_BASE, 0x80);
			if((read32(RSW_INT) & 2) || (read32(DI_INT) & 4) || 
				(read32(SI_INT) & 8) || (read32(EXI_INT) & 0x10))
				write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq
			InterruptTimer = read32(HW_TIMER);
		}
		#ifdef PATCHALL
		if (EXI_IRQ == true)
		{
			if(EXICheckTimer())
				EXIInterrupt();
		}
		#endif
		if (SI_IRQ != 0)
		{
			if ((TimerDiffTicks(PADTimer) > 7910) || (SI_IRQ & 0x2))	// about 240 times a second
			{
				SIInterrupt();
				PADTimer = read32(HW_TIMER);
			}
		}
		if(DI_IRQ == true)
		{
			if(DiscCheckAsync())
				DIInterrupt();
			else
				udelay(200); //let the driver load data
		}
		else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */
		{
			if(TimerDiffSeconds(Now) > 2) /* after 3 second earliest */
			{
				EXISaveCard();
				SaveCard = false;
			}
		}
		else if(UseUSB && TimerDiffSeconds(USBReadTimer) > 149) /* Read random sector every 2 mins 30 secs */
		{
			DIFinishAsync(); //if something is still running
			DI_CallbackMsg.result = -1;
			sync_after_write(&DI_CallbackMsg, 0x20);
			IOS_IoctlAsync( DI_Handle, 2, NULL, 0, NULL, 0, DI_MessageQueue, &DI_CallbackMsg );
			DIFinishAsync();
			USBReadTimer = read32(HW_TIMER);
		}
		udelay(10); //wait for other threads

		//Baten Kaitos save hax
		/*if( read32(0) == 0x474B4245 )
		{
			if( read32( 0x0073E640 ) == 0xFFFFFFFF )
			{
				write32( 0x0073E640, 0 );
			}
		}*/
		if( WaitForRealDisc == 1 )
		{
			if(RealDI_NewDisc())
			{
				DiscChangeTimer = read32(HW_TIMER);
				WaitForRealDisc = 2; //do another flush round, safety!
			}
		}
		else if( WaitForRealDisc == 2 )
		{
			if(TimerDiffSeconds(DiscChangeTimer))
			{
				//identify disc after flushing everything
				RealDI_Identify(false);
				//clear our fake regs again
				sync_before_read((void*)DI_BASE, 0x40);
				write32(DI_IMM, 0);
				write32(DI_COVER, 0);
				sync_after_write((void*)DI_BASE, 0x40);
				//mask and clear interrupts
				write32( DIP_STATUS, 0x54 );
				//disable cover irq which DIP enabled
				write32( DIP_COVER, 4 );
				DIInterrupt();
				WaitForRealDisc = 0;
			}
		}

		if ( DiscChangeIRQ == 1 )
		{
			DiscChangeTimer = read32(HW_TIMER);
			DiscChangeIRQ = 2;
		}
		else if ( DiscChangeIRQ == 2 )
		{
			if ( TimerDiffSeconds(DiscChangeTimer) > 2 )
			{
				DIInterrupt();
				DiscChangeIRQ = 0;
			}
		}
		_ahbMemFlush(1);
		DIUpdateRegisters();
		#ifdef PATCHALL
		EXIUpdateRegistersNEW();
		GCAMUpdateRegisters();
		BTUpdateRegisters();
		HIDUpdateRegisters(0);
		if(DisableSIPatch == 0) SIUpdateRegisters();
		#endif
		StreamUpdateRegisters();
		CheckOSReport();
		if(EXICheckCard())
		{
			Now = read32(HW_TIMER);
			SaveCard = true;
		}
		sync_before_read((void*)RESET_STATUS, 0x20);
		vu32 reset_status = read32(RESET_STATUS);
		if (reset_status == 0x1DEA)
		{
			write32(RESET_STATUS, 0);
			sync_after_write((void*)RESET_STATUS, 0x20);
			DIFinishAsync();
			break;
		}
		if (reset_status == 0x3DEA)
		{
			if (Reset == 0)
			{
				dbgprintf("Fake Reset IRQ\n");
				write32( RSW_INT, 0x2 ); // Reset irq
				sync_after_write( (void*)RSW_INT, 0x20 );
				write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq
				Reset = 1;
			}
		}
		else if (Reset == 1)
		{
			write32( RSW_INT, 0x10000 ); // send pressed
			sync_after_write( (void*)RSW_INT, 0x20 );
			ResetTimer = read32(HW_TIMER);
			Reset = 2;
		}
		/* The cleanup is not connected to the button press */
		if (Reset == 2)
		{
			if (TimerDiffTicks(ResetTimer) > 949219) //free after half a second
			{
				write32( RSW_INT, 0 ); // done, clear
				sync_after_write( (void*)RSW_INT, 0x20 );
				Reset = 0;
			}
		}
		if(reset_status == 0x4DEA)
			PatchGame();
		if(reset_status == 0x5DEA)
		{
			SetIPL();
			PatchGame();
		}
		if(reset_status == 0x6DEA)
		{
			SetIPL_TRI();
			write32(RESET_STATUS, 0);
			sync_after_write((void*)RESET_STATUS, 0x20);
		}
		if(read32(HW_GPIO_IN) & GPIO_POWER)
		{
			DIFinishAsync();
			#ifdef PATCHALL
			BTE_Shutdown();
			#endif
			Shutdown();
		}
		//sync_before_read( (void*)0x1860, 0x20 );
		//if( read32(0x1860) != 0xdeadbeef )
		//{
		//	if( read32(0x1860) != 0 )
		//	{
		//		dbgprintf(	(char*)(P2C(read32(0x1860))),
		//					(char*)(P2C(read32(0x1864))),
		//					(char*)(P2C(read32(0x1868))),
		//					(char*)(P2C(read32(0x186C))),
		//					(char*)(P2C(read32(0x1870))),
		//					(char*)(P2C(read32(0x1874)))
		//				);
		//	}
		//	write32(0x1860, 0xdeadbeef);
		//	sync_after_write( (void*)0x1860, 0x20 );
		//}
		cc_ahbMemFlush(1);
	}
	//if( UseHID )
		HIDClose();
	IOS_Close(DI_Handle); //close game
	thread_cancel(DI_Thread, 0);
	DIUnregister();

	/* reset time */
	while(1)
	{
		sync_before_read( (void*)RESET_STATUS, 0x20 );
		if(read32(RESET_STATUS) == 0x2DEA)
			break;
		wait_for_ppc(1);
	}

	if( ConfigGetConfig(NIN_CFG_LED) )
		clear32(HW_GPIO_OUT, GPIO_SLOT_LED);

	if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) )
		EXIShutdown();

	if (ConfigGetConfig(NIN_CFG_LOG))
		closeLog();

#ifdef PATCHALL
	BTE_Shutdown();
#endif

//unmount FAT device
	free(fatfs);
	fatfs = NULL;
	f_mount(NULL, fatDevName, 1);

	if(UseUSB)
		USBStorage_Shutdown();
	else
		SDHCShutdown();

//make sure we set that back to the original
	write32(HW_PPCSPEED, ori_ppcspeed);

	if(IsWiiU)
	{
		write32(0xd8006a0, ori_widesetting);
		mask32(0xd8006a8, 0, 2);
	}
DoIOSBoot:
	sync_before_read((void*)0x13003000, 0x420);
	IOSBoot((char*)0x13003020, 0, read32(0x13003000));
	return 0;
}