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; }
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++; } }
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); } }
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; }
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 ()); }
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; }
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); } }
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); } }
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."); }
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); } }
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; }
/* 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; }
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; } }
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 = ▮ 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; } }
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; }
/* 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); } }
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); }
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; }
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; }