//------------------------------------------// // Software_Create // // Description: Function used to create // // software threads only. Used if creating // // a hardware thread fails. // //------------------------------------------// Huint software_create ( hthread_t * tid, hthread_attr_t * attr, Huint func_id, void * arg) { void * func; // --------------------------------------------- // Make sure tables are setup // --------------------------------------------- if (!table_initialized_flag) { // Assert flag table_initialized_flag = 1; // Init thread table init_thread_table(&global_thread_table); // Load entries with app-specific data load_my_table(); // Init function-to-accelerator table init_func_2_acc_table(); #ifdef ICAP // Initialize mutexes, ICAP, and bitfiles // for Partial Reconfiguration. init_PR_data(); #endif } #ifdef DEBUG_DISPATCH printf("Software thread\n"); #endif // Create a native/software thread on the host processor func = lookup_handle(&global_thread_table, func_id, TYPE_HOST); // Increment thread counter thread_counter++; return (hthread_create(tid, attr, func, arg)); }
int main(void) { int c; int light=0; // set the clocking to run directly from the crystal. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ); // initialize the OLED display and display "IR Sensor Demo" on the OLED screen. RIT128x96x4Init(1000000); // enable peripherals SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // initialize peripherals. uart_init(); led_init(); // prepare thread table init_thread_table(); init_thread(threadUART); init_thread(threadOLED); init_thread(threadLED); // init systick systick_init(); // register SVC handler IntRegister(FAULT_SVCALL, schedule); // enable global Interrupts IntMasterEnable(); // kick off this wild ride yield(); exit(0); }
Huint microblaze_create( hthread_t * tid, hthread_attr_t * attr, Huint func_id, void * arg, Huint ublaze) { Huint ret; void * func; assert(attr!=NULL); // Efficient NULL pointer check // --------------------------------------------- // Make sure tables are initialized // --------------------------------------------- if (table_initialized_flag == 0) { // Assert flag table_initialized_flag = 1; // Init thread table init_thread_table(&global_thread_table); // Load entries with app-specific data load_my_table(); // Init function-to-accelerator table init_func_2_acc_table(); } // --------------------------------------------- // Check if that specific MB is free // --------------------------------------------- if( !get_utilized_flags((void *) hwti_array[ublaze])) { // Create a native thread printf("Microblaze %d is either not Free or does not exist!\n",ublaze); func = lookup_handle(&global_thread_table, func_id, TYPE_HOST); if (func == (void*)TABLE_INIT) { ret = TABLE_INIT; } else { // Ignore passed in attribute #ifdef DEBUG_DISPATCH printf("Creating Native Thread!\n"); #endif ret = hthread_create(tid, NULL, func, arg); } } // --------------------------------------------- // Otherwise create a hetero thread // --------------------------------------------- else { // Create a heterogeneous thread func = lookup_handle(&global_thread_table, func_id, slave_table[ublaze].processor_type); if (func == (void*)TABLE_INIT) { ret = TABLE_INIT; } else { // Create thread hetero using V-HWTI[found] #ifdef DEBUG_DISPATCH printf("Creating Hetero Thread (CPU#%d)!\n",ublaze); #endif hthread_attr_init(attr); hthread_attr_sethardware( attr, (void*)hwti_array[ublaze] ); ret = hthread_create(tid, attr, func, arg); } } return ret; }
// (SMART) Dynamic thread creation function Huint dynamic_create_smart( hthread_t * tid, hthread_attr_t * attr, Huint func_id, void * arg) { Huint ret; void * func; // Efficient NULL pointer check assert(attr!=NULL); // --------------------------------------------- // Make sure tables are initialized // --------------------------------------------- if (table_initialized_flag == 0) { // Assert flag table_initialized_flag = 1; // Init thread table init_thread_table(&global_thread_table); // Load entries with app-specific data load_my_table(); // Init function-to-accelerator table init_func_2_acc_table(); } // --------------------------------------------- // Look for any free heterogeneous processors // --------------------------------------------- int i = 0; int found = NOT_FOUND; for (i = 0; i < NUM_AVAILABLE_HETERO_CPUS; i++) { if( get_utilized_flags((void *) &i)) { // Mark CPU that was found, and break out of loop found = i; break; } } // --------------------------------------------- // Create a native thread if no hetero CPUs are free // --------------------------------------------- if (found == NOT_FOUND) { // Create a native/software thread on MB func = lookup_handle(&global_thread_table, func_id, TYPE_HOST); if (func == (void*)TABLE_INIT) { ret = TABLE_INIT; } else { // Ignore passed in attribute #ifdef DEBUG_DISPATCH printf("Creating Native Thread!\n"); #endif ret = hthread_create(tid, NULL, func, arg); } } // --------------------------------------------- // Otherwise create a hetero thread // --------------------------------------------- else { // Create a heterogeneous thread func = lookup_handle(&global_thread_table, func_id, slave_table[found].processor_type); if (func == (void*)TABLE_INIT) { ret = TABLE_INIT; } else { // Create thread hetero using V-HWTI[found] #ifdef DEBUG_DISPATCH printf("Creating Hetero Thread (CPU#%d)!\n",found); #endif hthread_attr_init(attr); hthread_attr_sethardware( attr, (void*)hwti_array[found] ); ret = hthread_create(tid, attr, func, arg); } } return ret; }
//--------------------------------------------------------------------------------------------// // Thread Create // Description: This function encapsulates all of the thread create functions (i.e. dynamic // create smart, microblaze create, hthread create, etc. // Arguments: // 1) Thread ID - Thread ID returned by the OS. Assigned during hthread_setup(). // 2) Thread Attribute - Attribute structure for the thread // 3) Function ID - The function number the thread will execute // 4) Argument - Argument to be passed to the function // 5) Type - The type of thread you want to be created. (i.e. Software, dynamic_hw, etc. // 6) Dma Length - the length of the parameter, arg. Passing a zero indicates no DMA'ing // // NOTE: DMA LENGTH IS NOT USED AT THIS TIME. //--------------------------------------------------------------------------------------------// Huint thread_create( hthread_t * tid, hthread_attr_t * attr, Huint func_id, void * arg, Huint type, Huint dma_length) { Huint ret; void * func; assert(attr!=NULL); // Efficient NULL pointer check // --------------------------------------------- // Make sure tables are initialized // --------------------------------------------- if (!table_initialized_flag) { // Assert flag table_initialized_flag = 1; // Init thread table init_thread_table(&global_thread_table); // Load entries with app-specific data load_my_table(); // Init function-to-accelerator table init_func_2_acc_table(); // Initialize mutexes, ICAP, and bitfiles // for Partial Reconfiguration. init_PR_data(); } // Check if we have not passed our threshold // TODO: Remove? //while( (NUM_AVAILABLE_HETERO_CPUS - get_num_free_slaves() + thread_counter) > (NUM_AVAILABLE_HETERO_CPUS + SW_THREAD_COUNT)) //hthread_yield(); //-------------------------------- // Is this a software thread? //-------------------------------- if (type == SOFTWARE_THREAD) { // Create a native/software thread on the host processor // Make sure user didn't call hthread_attr_sethardware() if (attr->hardware) { #ifdef DEBUG_DISPATCH printf("Your thread attribute is set for hardware but"); printf(" you are creating a software thread!\n"); #endif ret = FAILURE; } else ret = software_create(tid, attr, func_id, arg); //------------------------------------------------------------ // For hardware threads, should we dynamically schedule them? //------------------------------------------------------------ } else if(type == DYNAMIC_HW) { // Identify a slave processor the best fits our needs (i.e., is // available, is available and has an accelerator we want, etc.) Hint slave_num = find_best_match(func_id); // If we did not find any processors available. if (slave_num == MAGIC_NUMBER) { #ifdef DEBUG_DISPATCH printf("No Free Slaves:Creating software thread\n"); #endif ret = software_create(tid, NULL, func_id, arg); } else { // Grab the function handle according to the processor type. func = lookup_handle(&global_thread_table, func_id, slave_table[slave_num].processor_type); #ifdef DEBUG_DISPATCH printf("Creating Hetero Thread (CPU#%d)!\n",slave_num); #endif // -------------------------------------------------------------- // // Write extra parameters for PR functionality // // -------------------------------------------------------------- // // Write pointer for first_used_accelerator so slave can update the table. // This assumes that for a particular function (id), slaves will also have // the same first accelerator used. _hwti_set_first_accelerator_ptr( (Huint) hwti_array[slave_num], (Huint) &func_2_acc_table[func_id]); // -------------------------------------------------------------- // // Create the hardware thread using better target // // -------------------------------------------------------------- // hthread_attr_sethardware( attr, (void*)hwti_array[slave_num] ); ret = hthread_create(tid, attr, func, arg); } //------------------------------------------------------- // For hardware threads, we will statically schedule them //------------------------------------------------------- } else { // Determine the exact slave processor number Huint slave_num = type + STATIC_HW_OFFSET; // Check if valid slave number. Since 'slave_num' is // and unsigned int, it cannot be negative, right? if (slave_num >= NUM_AVAILABLE_HETERO_CPUS) { #ifdef DEBUG_DISPATCH printf("Invalid slave number: %d\n", slave_num); printf("Creating a software thread instead\n"); #endif ret = software_create(tid, NULL, func_id, arg); } // If that slave number exists, is it Free? if (_hwti_get_utilized_flag(hwti_array[slave_num]) == FLAG_HWTI_UTILIZED) { #ifdef DEBUG_DISPATCH printf("Slave number %d is busy! Creating software thread\n", slave_num); #endif ret = software_create(tid, NULL, func_id, arg); } else { #ifdef DEBUG_DISPATCH printf("Creating Hetero Thread (CPU#%d)!\n",slave_num); #endif // -------------------------------------------------------------- // // Write extra parameters for PR functionality // // -------------------------------------------------------------- // // Write pointer for first_used_accelerator so slave can update the table. // This assumes that for a particular function (id), slaves will also have // the same first accelerator used. _hwti_set_first_accelerator_ptr( (Huint) hwti_array[slave_num], (Huint) &func_2_acc_table[func_id]); // Grab the function according to the processor type func = lookup_handle(&global_thread_table, func_id, slave_table[slave_num].processor_type); // -------------------------------------------------------------- // // Create the hardware thread using slave num // // -------------------------------------------------------------- // hthread_attr_sethardware( attr, (void*)hwti_array[slave_num] ); ret = hthread_create(tid, attr, func, arg); } } return ret; }