static int e_cond_broadcast(lua_State *L) { cyg_cond_t *cond; cond = (cyg_cond_t *) check_user_data(L, 1, E_COND); cyg_cond_broadcast(cond); return 0; }
static void entry2( cyg_addrword_t data ) { cyg_mutex_lock( &m0 ); { while( 3 != m0d ) { cyg_cond_wait( &cvar0 ); } CHECK( 3 == m0d++ ); cyg_cond_broadcast( &cvar1 ); } cyg_mutex_unlock( &m0 ); finish( (cyg_ucount8)data ); }
static void entry1( cyg_addrword_t data ) { cyg_mutex_lock( &m0 ); { CHECK( cyg_mutex_trylock( &m1 ) ); { } cyg_mutex_unlock( &m1 ); } cyg_mutex_unlock( &m0 ); cyg_mutex_lock( &m0 ); { CHECK( 0 == m0d++ ); cyg_cond_broadcast( &cvar0 ); } cyg_mutex_unlock( &m0 ); cyg_mutex_lock( &m0 ); { while( 1 == m0d ) cyg_cond_wait( &cvar0 ); CHECK( 2 == m0d++ ); cyg_cond_signal( &cvar0 ); while( 3 == m0d ) cyg_cond_wait( &cvar1 ); } cyg_mutex_unlock( &m0 ); finish( (cyg_ucount8)data ); }
void controller( cyg_addrword_t id ) { cyg_priority_t pri; int i; cyg_mutex_init( &worker_mutex ); cyg_cond_init( &worker_cv, &worker_mutex ); // 1 thread, it is running, it calls BREAKME(); // +++ Thread status returned: // +++ 1 thread, running, is the current one breakme(); // Create N more threads; they are all suspended after creation. Adjust // the priorities of all the threads to lower than the controlling thread. // Make them all be distinct priorities as far as possible. BREAKME(); // +++ 1 thread, running, + N suspended ones of different prios. for( i = 1; i < THREADS; i++ ) { pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE; cyg_thread_create(pri, worker, (cyg_addrword_t)i, "worker", (void *)(&thread_stack[i]), STACKSIZE, &thread_handle[i], &thread[i]); } breakme(); // Adjust the priorities of all the threads to lower than the controlling // thread. Make them all be THE SAME priority. BREAKME(); // +++ 1 thread, running, + N suspended ones of same prio. for( i = 1; i < THREADS; i++ ) { cyg_thread_set_priority( thread_handle[i], WORKER_PRI ); } breakme(); // Release all the N threads, BREAKME(); // +++ 1 thread, running, + N ready ones of same prio. for( i = 1; i < THREADS; i++ ) { cyg_thread_resume( thread_handle[i] ); } breakme(); // Adjust the priorities of all the threads, lower than the controlling // thread. Make them all be distinct priorities as far as possible. // BREAKME(); // +++ 1 thread, running, + N ready ones of different prios. for( i = 1; i < THREADS; i++ ) { pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE; cyg_thread_set_priority( thread_handle[i], pri ); } breakme(); // Command all the N threads to sleep; switch my own priority to lower // than theirs so that they all run and sleep, then I get back in and // BREAKME(); // +++ 1 thread, running, + N sleeping ones of different prios. worker_state = WORKER_STATE_WAIT; cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO ); breakme(); // Make them all be THE SAME priority; BREAKME(); // +++ 1 thread, running, + N sleeping ones of same prio. for( i = 1; i < THREADS; i++ ) { cyg_thread_set_priority( thread_handle[i], WORKER_PRI ); } breakme(); // Wake them all up, they'll loop once and sleep again; I get in and // BREAKME(); // +++ 1 thread, running, + N sleeping ones of same prio. cyg_cond_broadcast( &worker_cv ); breakme(); // Adjust the priorities of all the threads, higher than the controlling // thread. Make them all be distinct priorities as far as possible. // BREAKME(); // +++ 1 thread, running, + N sleeping ones of different prios. for( i = 1; i < THREADS; i++ ) { pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE; cyg_thread_set_priority( thread_handle[i], pri ); } breakme(); // Wake them all up, they'll loop once and sleep again; I get in and // BREAKME(); // +++ 1 thread, running, + N sleeping ones of different prios. cyg_cond_broadcast( &worker_cv ); breakme(); // Set them all the same prio, set me to the same prio, BREAKME(); // +++ 1 running, + N sleeping, *all* the same prio. for( i = 0; i < THREADS; i++ ) { cyg_thread_set_priority( thread_handle[i], WORKER_PRI ); } breakme(); // Wake them all up, they'll loop once and sleep again; I get in and // BREAKME(); repeatedly until they have all slept again. // +++ 1 running, + some sleeping, some ready, *all* the same prio. cyg_cond_broadcast( &worker_cv ); // cyg_thread_yield(); do { breakme(); } while( workers_asleep != THREADS-1 ); breakme(); // Suspend some of the threads, BREAKME(); // +++ 1 running, + some sleeping, some suspended, *all* the same prio. for( i = 1; i < THREADS; i++ ) { // suspend every 3rd thread if( 0 == (i % 3) ) cyg_thread_suspend( thread_handle[i] ); } breakme(); // Change the prios all different, change my prio to highest , BREAKME(); // +++ 1 running, + some sleeping, some suspended, different prios. cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_HI ); for( i = 1; i < THREADS; i++ ) { pri = CONTROLLER_PRI_HI + 1 + i % WORKER_PRI_RANGE; cyg_thread_set_priority( thread_handle[i], pri ); } breakme(); // Wake up all the threads, BREAKME(); // +++ 1 running, + some ready, some suspended/ready, different prios. cyg_cond_broadcast( &worker_cv ); breakme(); // Change my prio to lowest, let all the threads run, BREAKME(). // +++ 1 running + some sleeping, some suspended/ready, different prios. cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO ); breakme(); // Resume all the threads, BREAKME(); // +++ 1 running, + N ready, different prios. for( i = 1; i < THREADS; i++ ) { cyg_thread_resume( thread_handle[i] ); } breakme(); // Command some of the N threads to call BREAKME(); themselves (then sleep // again). Change my prio to low, so that they all get to run and hit the // breakpoint. // +++ A different one running every time, others in a mixture of // ready and sleeping states. worker_state = WORKER_STATE_BREAK; cyg_cond_broadcast( &worker_cv ); cyg_thread_set_priority( thread_handle[0], CONTROLLER_PRI_LO ); breakme(); // Command all the threads to exit; switch my own priority to lower // than theirs so that they all run and exit, then I get back in and // BREAKME(); // +++ 1 thread, running, + N dormant ones. worker_state = WORKER_STATE_EXIT; cyg_cond_broadcast( &worker_cv ); breakme(); #if 0 // Cannot do this yet... // Destroy some of the N threads to invalidate their IDs. Re-create them // with new IDs, so that we get IDs 1,2,4,6,8,11,12,13,14,15 in use instead // of 1,2,3,4,5,6,7,8,9, if you see what I mean. Do all the above again. // Loop forever, or whatever... #endif breakme(); CYG_TEST_PASS_FINISH("GDB Thread test OK"); }
//----------------------------------------- // eCos HW scheduling thread //----------------------------------------- void reconos_hw_scheduler(cyg_addrword_t data) { cyg_bool_t retval; rthread_attr_t *t_r; // thread to reconfigure rthread_attr_t *t_y; // yielding thread reconos_slot_t *s_f; // free slot reconos_bitstream_t *t_r_bit; // bitstream for t_r in s_f #ifdef UPBFUN_RECONOS_CHECK_HWTHREAD_SIGNATURE uint32 signature; // hardware thread signature volatile int z; // counter to delay DCR access #endif #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: created\n"); #endif // loop forever for (;;) { // wait for signal (reschedule request) retval = cyg_semaphore_wait( &reconos_hwsched_semaphore ); CYG_ASSERT(retval, "cyg_semaphore_wait returned false"); #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: wakeup\n"); #endif // lock scheduling mutex if (!cyg_mutex_lock(&reconos_hwsched_mutex)) { CYG_FAIL("mutex lock failed, aborting thread\n"); } else { #ifdef UPBDBG_RECONOS_DEBUG { int i; for (i = 0; i < NUM_OSIFS; i++) { dump_slot( &reconos_slots[i] ); } } #endif // find thread t_r that wants to run (FIXME: no priorities or // queuing!) t_r = reconos_hwthread_list; while ( t_r != NULL && ((t_r->flags & RTHREAD_ATTR_RECONFIGURE) == 0) ) { t_r = t_r->next; } if (t_r == NULL) { // no hw threads to reconfigure, nothing to do #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: no threads to reconfigure\n"); #endif // clear all yield requests! while (num_global_yield_requests) { pop_yield_request(); } } else { #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: found thread @ 0x%08X to reconfigure\n", (uint32)t_r); #endif CYG_ASSERT( t_r->flags & RTHREAD_ATTR_IS_DYNAMIC, "trying to load a static thread" ); // find free slot s_f s_f = find_free_slot( t_r ); if ( s_f == NULL ) { // no free slot // try to find thread that yields in a slot we have a // bitstream for #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: no free slots\n"); #endif t_y = reconos_hwthread_list; while ( t_y != NULL && ( ( (t_y->flags & RTHREAD_ATTR_YIELDS ) == 0) || ( get_bit_for_slot( t_r, t_y->slot ) == NULL ) ) ) { t_y = t_y->next; } if (t_y == NULL) { // no yielding thread #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: no yielding threads, sending yield requests to slots\n"); #endif // ask all slots to yield // FIXME: this will also ask slots that t_r possibly // doesn't have a bitstream for push_yield_request(); } else { // if found CYG_ASSERT( t_y->flags & RTHREAD_ATTR_IS_DYNAMIC, "trying to replace a static thread" ); CYG_ASSERT( t_y->slot, "trying to replace a not-resident thread" ); #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: found yielding thread @ 0x%08X in slot %d\n", (uint32)t_y, t_y->slot->num); #endif // use t_y's slot as s_f s_f = t_y->slot; // clear yield flag of t_y t_y->flags = t_y->flags & ~RTHREAD_ATTR_YIELDS; // remove t_y from s_f s_f->thread = NULL; t_y->slot = NULL; s_f->state = FREE; } } else { #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: found free slot %d\n", s_f->num); #endif } if ( s_f != NULL) { // if we found a free slot // one way or the other // get bitstream for t_r in s_f t_r_bit = get_bit_for_slot( t_r, s_f ); CYG_ASSERT( t_r_bit, "no bitstream" ); CYG_ASSERT( s_f->state == FREE || s_f->thread->flags & RTHREAD_ATTR_IS_DYNAMIC, "slot not free or present thread is static" ); #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: configuring thread @ 0x%08X into slot %d using bitstream '%s'\n", (uint32)t_r, s_f->num, t_r_bit->filename); #endif // configure t_r into s_f // NOTE: we don't need to synchronize this with the // slot's mutex, since the slot is yielding and will // not perform any hardware operations while the // scheduling mutex is locked // disable bus macros (just in case) osif_set_busmacro(s_f, OSIF_DATA_BUSMACRO_DISABLE); #ifdef UPBHWR_VIRTEX4_ICAP icap_load( t_r_bit->data, t_r_bit->size ); #endif #ifdef UPBFUN_RECONOS_ECAP_NET ecap_load( t_r_bit ); #endif #ifdef UPBFUN_RECONOS_CHECK_HWTHREAD_SIGNATURE // reset thread, enable busmacros, reset again (to // retrieve signature), read signature, and disable // busmacros osif_reset( s_f ); cyg_thread_delay(1); osif_set_busmacro(s_f, OSIF_DATA_BUSMACRO_ENABLE); // cyg_thread_delay(1); osif_reset( s_f ); cyg_thread_delay(1); osif_read_hwthread_signature(s_f, &signature); // cyg_thread_delay(1); // osif_set_busmacro(s_f, OSIF_DATA_BUSMACRO_DISABLE); // cyg_thread_delay(1); #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: read signature: 0x%08X, expected: 0x%08X.\n", signature, t_r->circuit->signature); #endif // check whether the signatures match CYG_ASSERT(signature == t_r->circuit->signature, "hwthread signatures don't match"); #endif // assign thread to slot and set slot state to READY s_f->thread = t_r; t_r->slot = s_f; s_f->state = READY; // clear t_r's RECONFIGURE bit t_r->flags = t_r->flags & ~RTHREAD_ATTR_RECONFIGURE; // wake any threads waiting for a scheduling change cyg_cond_broadcast( &reconos_hwsched_condvar ); // clear one yield request pop_yield_request(); } } #ifdef UPBDBG_RECONOS_DEBUG diag_printf("hw_sched: done\n"); #endif // unlock scheduling mutex cyg_mutex_unlock(&reconos_hwsched_mutex); } // if (mutex_lock) } // for (;;) }
/** * @brief This function removes the card. * * @param priv A pointer to card * @return WLAN_STATUS_SUCCESS */ static int wlan_remove_card(void *card) { wlan_private *priv = &w99702_priv_data0; wlan_adapter *Adapter; //struct net_device *dev; struct cyg_netdevtab_entry *dev; struct eth_drv_sc *sc; union iwreq_data wrqu; ENTER(); if (!priv) { LEAVE(); return WLAN_STATUS_SUCCESS; } Adapter = priv->adapter; if (!Adapter) { LEAVE(); return WLAN_STATUS_SUCCESS; } dev = priv->wlan_dev.netdev; sc = (struct eth_drv_sc *)dev->device_instance; // wake_up_interruptible(&Adapter->ds_awake_q); cyg_cond_broadcast(&Adapter->ds_cond_q); if (Adapter->CurCmd) { diag_printf("Wake up current cmdwait_q\n"); // wake_up_interruptible(&Adapter->CurCmd->cmdwait_q); cyg_flag_setbits( &Adapter->CurCmd->cmdwait_flag_q, 3 ); } Adapter->CurCmd = NULL; if (Adapter->PSMode == Wlan802_11PowerModeMAX_PSP) { Adapter->PSMode = Wlan802_11PowerModeCAM; PSWakeup(priv, HostCmd_OPTION_WAITFORRSP); } if (Adapter->IsDeepSleep == TRUE) { Adapter->IsDeepSleep = FALSE; sbi_exit_deep_sleep(priv); } memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); /* Disable interrupts on the card as we cannot handle them after RESET */ sbi_disable_host_int(priv); PrepareAndSendCommand(priv, HostCmd_CMD_802_11_RESET, 0, 0, 0, NULL); cyg_thread_delay(20); //udelay(200*1000); #ifdef ENABLE_PM pm_unregister(wlan_pm_dev); #endif /* Flush all the packets upto the OS before stopping */ // wlan_send_rxskbQ(priv); eth_drv_dsr(0, 0, (cyg_addrword_t)sc); cleanup_txqueues(priv); // os_stop_queue(priv); // os_carrier_off(priv); Adapter->SurpriseRemoved = TRUE; /* Stop the thread servicing the interrupts */ //wake_up_interruptible(&priv->MainThread.waitQ); cyg_flag_setbits( &priv->MainThread.waitQ_flag_q, 1 ); #ifdef REASSOCIATION //wake_up_interruptible(&priv->ReassocThread.waitQ); cyg_flag_setbits( &priv->ReassocThread.waitQ_flag_q, 1 ); #endif /* REASSOCIATION */ #ifdef PROC_DEBUG wlan_debug_remove(priv); #endif // wlan_proc_remove(priv); diag_printf("unregester dev\n"); sbi_unregister_dev(priv); diag_printf("Free Adapter\n"); wlan_free_adapter(priv); /* Last reference is our one */ // diag_printf("refcnt = %d\n", atomic_read(&dev->refcnt)); // diag_printf("netdev_finish_unregister: %s%s.\n", dev->name, // (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style"); // unregister_netdev(dev); diag_printf("Unregister finish\n"); priv->wlan_dev.netdev = NULL; //free_netdev(dev); //wlanpriv = NULL; LEAVE(); return WLAN_STATUS_SUCCESS; }