//------------------------------------------//
// 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));
}
Ejemplo n.º 2
0
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;
}