int main( int argc, char *argv[] ) { Huint sta; void* retval; hthread_t tid; hthread_attr_t attr; int num_ops = 0; printf( "\n****Main Thread****... \n" ); for( num_ops = 0; num_ops < 5; num_ops++) { // Initialize the attributes for the hardware thread hthread_attr_init( &attr ); hthread_attr_sethardware( &attr, HWTI_BASEADDR ); // Create the hardware thread printf( "Starting Hardware Thread... \r" ); sta = hthread_create( &tid, &attr, NULL, (void*)(num_ops) ); printf( "Started Hardware Thread (TID = %d) (ARG = %d)... 0x%8.8x\n", tid, num_ops, sta ); // Clean up the attribute structure hthread_attr_destroy( &attr ); // Wait for the hardware thread to exit printf( "Waiting for Hardware Thread... \r" ); hthread_join( tid, &retval ); printf( "Joined on Hardware Thread... 0x%8.8x\n", (Huint)retval ); } // Return from main return 0; }
int main() { hthread_t test_thread; hthread_attr_t test_attr; hthread_mutex_t mutex; int arg, retVal; //Print the name of the test to the screen printf( "Starting test mutex_init_3\n" ); //Set up the arguments for the test arg = (int) &mutex; //Initialize RPC rpc_setup(); //Run the tests hthread_attr_init( &test_attr ); if ( HARDWARE ) hthread_attr_sethardware( &test_attr, HWTI_ONE_BASEADDR ); hthread_create( &test_thread, &test_attr, testThread, (void *) arg ); hthread_join( test_thread, (void *) &retVal ); if ( HARDWARE ) readHWTStatus( HWTI_ONE_BASEADDR ); //Evaluate the results if ( retVal == EXPECTED_RESULT ) { printf("Test PASSED\n"); return PTS_PASS; } else { printf("Test FAILED [expecting %d, received %d]\n", EXPECTED_RESULT, retVal ); return PTS_FAIL; } }
int main( int argc, char *argv[] ) { Huint sta; void* retval; hthread_t tid; hthread_attr_t attr; int num_ops = 0; printf( "\n****Main Thread****... \n" ); XCache_DisableDCache(); // ************************************************************************************* unsigned int *fcn_pointer = (unsigned int*)(HWTI_BASEADDR + 6*sizeof(int)); int code_offset = 0; FuncPointer fp = 0; unsigned char * prog_ptr = 0; unsigned int * first_instr = 0; // Initialize code offset and program pointer code_offset = 0x1f0; //0x1d4;//0x1a8; prog_ptr = (unsigned char *)&junk_o; // Initialize function pointer (actual place to jump to) fp = (FuncPointer)(prog_ptr + code_offset); // Initialize a pointer that allows one to "look" at the 1st instruction first_instr = (unsigned int*)(prog_ptr + code_offset); *fcn_pointer = (int)fp; // ************************************************************************************* for( num_ops = 0; num_ops < 5; num_ops++) { // Initialize the attributes for the hardware thread hthread_attr_init( &attr ); hthread_attr_sethardware( &attr, HWTI_BASEADDR ); // Create the hardware thread printf( "Starting Hardware Thread... \r" ); sta = hthread_create( &tid, &attr, (void*)fp, (void*)(num_ops) ); printf( "Started Hardware Thread (TID = %d) (ARG = %d)... 0x%8.8x\n", tid, num_ops, sta ); // Clean up the attribute structure hthread_attr_destroy( &attr ); // Wait for the hardware thread to exit printf( "Waiting for Hardware Thread... \r" ); hthread_join( tid, &retval ); printf( "Joined on Hardware Thread... 0x%8.8x\n", (Huint)retval ); } // Return from main return 0; }
void* findFibonacci(void * arg) { hthread_attr_t attrBase; hthread_t threadBase; hthread_t threadOne; hthread_t threadTwo; struct fibonacci * fib; struct fibonacci fibOne; struct fibonacci fibTwo; fib = (struct fibonacci *) arg; if (fib->fibNum == 0 || fib->fibNum == 1) { //Set up the attr for a HW thread hthread_attr_init( &attrBase ); hthread_attr_sethardware( &attrBase, HWTI_BASEADDR ); //since there is only one HWTI, perform a mutex lock on it. //then create the HW thread hthread_mutex_lock( &hwtiMutex ); //hthread_create(&threadBase, NULL, findFibHWTI, (void*)fib); //readHWTStatus(); //resetHWT(); //printf( "fibVal is %d\n", fib->fibVal ); printf( "fib address is %x, %x, %x\n", (Huint)fib, (Huint)(&fib->fibNum), (Huint)(&fib->fibVal) ); hthread_create(&threadBase, &attrBase, NULL, arg); //Clean up the attr hthread_attr_destroy( &attrBase ); //Wait for HW thread to finish ... and unlock mutex hthread_join(threadBase, NULL); //readHWTStatus(); printf( "fibVal is %d\n", fib->fibVal ); hthread_mutex_unlock( &hwtiMutex ); } else { fibOne.fibNum = fib->fibNum - 1; fibTwo.fibNum = fib->fibNum - 2; hthread_create(&threadOne, NULL, findFibonacci, (void*)&fibOne); hthread_create(&threadTwo, NULL, findFibonacci, (void*)&fibTwo); hthread_join(threadOne, NULL); hthread_join(threadTwo, NULL); fib->fibVal = fibOne.fibVal + fibTwo.fibVal; } return NULL; }
int main( int argc, char *argv[] ) { hthread_t tid, sw1, sw2; hthread_attr_t hw1Attr, sw1Attr, sw2Attr; hthread_mutex_t mutex; Huint retval; struct arguments myArgs; hthread_attr_init( &hw1Attr ); hthread_attr_init( &sw1Attr ); hthread_attr_init( &sw2Attr ); hthread_attr_sethardware( &hw1Attr, HWTI_BASEADDR ); hthread_mutex_init( &mutex, NULL ); myArgs.mutex = &mutex; retval = hthread_mutex_lock( myArgs.mutex ); // Set the thread's argument data to some value myArgs.value = 1000; // Create two software threads hthread_create( &tid, &hw1Attr, NULL, (void*)(&myArgs) ); hthread_create( &sw1, &sw1Attr, thread, (void*)(&myArgs) ); hthread_create( &sw2, &sw2Attr, thread, (void*)(&myArgs) ); hthread_yield(); // HWT should be blocked readHWTStatus(); retval = hthread_mutex_unlock( myArgs.mutex ); hthread_join( tid, (void*)(&retval) ); hthread_join( sw1, (void*)(&retval) ); hthread_join( sw2, (void*)(&retval) ); readHWTStatus(); // Clean up the attribute structure hthread_attr_destroy( &hw1Attr ); hthread_attr_destroy( &sw1Attr ); hthread_attr_destroy( &sw2Attr ); // Print out value of arg, and a successful exit message printf( "After joins arg = %d\n", myArgs.value); printf( "-- QED --\n" ); // Return from main return 1; }
int main( int argc, char *argv[] ) { hthread_t tid1; hthread_attr_t attr1; struct command commands; Huint i; log_t log; // Create the log file for timing reports log_create( &log, 1024 ); // Initialize the attributes for the threads hthread_attr_init( &attr1 ); // Setup the attributes for the hardware threads hthread_attr_sethardware( &attr1, HWT_ZERO_BASEADDR ); // Initialize matrixData commands.count = 060; commands.value = 1012; commands.operation = 6; //commands.ptrData = (int *) malloc( sizeof( int ) * commands.count ); commands.ptrData = (int *) 0x63000050; // Create the hardware thread log_time( &log ); hthread_create( &tid1, &attr1, NULL, (void*)(&commands) ); // Wait for the threads to exit hthread_join( tid1, NULL ); log_time( &log ); readHWTStatus( HWT_ZERO_BASEADDR ); for( i = 0; i < commands.count; i+=16 ) { printf( "%i=%i\n", i, commands.ptrData[i] ); } // Clean up the attribute structure hthread_attr_destroy( &attr1 ); printf( "log dump\n" ); log_close_ascii( &log ); printf( "-- QED --\n" ); // Return from main return 1; }
int main() { hthread_t test_thread; hthread_attr_t test_attr; int arg, retVal, start_num, waken_num; struct testdata data; hthread_mutex_t mutex; hthread_cond_t cond; //Print the name of the test to the screen printf( "Starting test cond_broadcast_1\n" ); //Set up the arguments for the test hthread_cond_init( &cond, NULL ); hthread_mutex_init( &mutex, NULL ); start_num = 0; waken_num = 0; data.mutex = &mutex; data.cond = &cond; data.start_num = &start_num; data.waken_num = &waken_num; data.function = a_thread_function; arg = (int) &data; //Initialize RPC rpc_setup(); //Run the tests hthread_attr_init( &test_attr ); if ( HARDWARE ) hthread_attr_sethardware( &test_attr, HWTI_ONE_BASEADDR ); hthread_create( &test_thread, &test_attr, testThread, (void *) arg ); hthread_join( test_thread, (void *) &retVal ); if ( HARDWARE ) readHWTStatus( HWTI_ONE_BASEADDR ); //Evaluate the results if ( retVal == EXPECTED_RESULT ) { printf("Test PASSED\n"); return PTS_PASS; } else { printf("Test FAILED [expecting %d, received %d]\n", EXPECTED_RESULT, retVal ); return PTS_FAIL; } }
int main() { xps_timer_t timer; int time_create, time_start, time_stop; // ************************************************************************************* extern unsigned char intermediate[]; extern unsigned int dct_handle_offset; unsigned int dct_handle = (dct_handle_offset) + (unsigned int)(&intermediate); extern unsigned int idct_handle_offset; unsigned int idct_handle = (idct_handle_offset) + (unsigned int)(&intermediate); // ************************************************************************************* // Thread attribute structures Huint sta[NUM_THREADS]; void* retval[NUM_THREADS]; hthread_t tid[NUM_THREADS]; hthread_attr_t attr[NUM_THREADS]; targ_t targ[NUM_THREADS]; int my_dct_matrix[BLOCK_SIZE][BLOCK_SIZE] = { {23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170 }, {32138, 27246, 18205, 6393, -6393, -18205, -27246, -32138 }, {30274, 12540, -12540, -30274, -30274, -12540, 12540, 30274 }, {27246, -6393, -32138, -18205, 18205, 32138, 6393, -27246 }, {23170, -23170, -23170, 23170, 23170, -23170, -23170, 23170 }, {18205, -32138, 6393, 27246, -27246, -6393, 32138, -18205 }, {12540, -30274, 30274, -12540, -12540, 30274, -30274, 12540 }, {6393 , -18205, 27246, -32138, 32138, -27246, 18205, -6393 } }; int my_dct_matrix_trans[BLOCK_SIZE][BLOCK_SIZE] = { {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0} }; int my_temp[BLOCK_SIZE][BLOCK_SIZE]; int my_input[BLOCK_SIZE][BLOCK_SIZE]; int my_intermediate_dct[BLOCK_SIZE][BLOCK_SIZE]; int my_intermediate_idct[BLOCK_SIZE][BLOCK_SIZE]; int my_output[BLOCK_SIZE][BLOCK_SIZE]; int my_idct_output[BLOCK_SIZE][BLOCK_SIZE]; int my_scale_factor = 16; // Create timer xps_timer_create(&timer, (int*)0x20400000); // Start timer xps_timer_start(&timer); int i,j; #ifdef USE_MB_THREAD printf("Using heterogeneous MB threads\r\n"); printf("\tCode start address = 0x%08x\n", (unsigned int)&intermediate); #else printf("Using native PPC threads\r\n"); #endif for (j = 0; j < NUM_THREADS; j++) { // Initialize the attributes for the threads hthread_attr_init( &attr[j] ); hthread_attr_sethardware( &attr[j], (void*)base_array[j] ); } // Calculate transpose of dct_matrix initialize_dct_matrix(my_dct_matrix, my_dct_matrix_trans); // Initialize input for (i = 0; i < BLOCK_SIZE; i++) { for (j = 0; j < BLOCK_SIZE; j++) { my_input[i][j] = i+j; } } // Fill in thread arguments for an initial DCT run targ[0].scale_factor = my_scale_factor; targ[0].input = my_input; targ[0].intermediate = my_intermediate_dct; targ[0].output = my_temp; targ[0].coeff_matrix = my_dct_matrix; targ[0].coeff_matrix_trans = my_dct_matrix_trans; dct_thread(&targ[0]); printf("\r\nOriginal Input:\r\n"); print_matrix(my_input); printf("\r\nOriginal DCT:\r\n"); print_matrix(my_temp); printf("**************************************************\r\n"); // Fill in thread arguments targ[0].scale_factor = my_scale_factor; targ[0].input = my_input; targ[0].intermediate = my_intermediate_dct; targ[0].output = my_output; targ[0].coeff_matrix = my_dct_matrix; targ[0].coeff_matrix_trans = my_dct_matrix_trans; targ[1].scale_factor = my_scale_factor; targ[1].input = my_temp; targ[1].intermediate = my_intermediate_idct; targ[1].output = my_idct_output; targ[1].coeff_matrix = my_dct_matrix; targ[1].coeff_matrix_trans = my_dct_matrix_trans; // Start timing thread create time_create = xps_timer_read_counter(&timer); // Peform DCT //dct_thread(&targ); // Use a thread #ifdef USE_MB_THREAD sta[0] = hthread_create( &tid[0], &attr[0], (void*)dct_handle, (void*)&targ[0] ); #else sta[0] = hthread_create( &tid[0], NULL, dct_thread, (void*)&targ[0]); #endif // Peform IDCT //idct_thread(&targ); // Use a thread #ifdef USE_MB_THREAD sta[1] = hthread_create( &tid[1], &attr[1], (void*)idct_handle, (void*)&targ[1] ); #else sta[1] = hthread_create( &tid[1], NULL, idct_thread, (void*)&targ[1]); #endif // Allow created threads to begin running and start timer time_start = xps_timer_read_counter(&timer); // Wait for threads to complete hthread_join(tid[0],&retval[0]); hthread_join(tid[1],&retval[1]); // Stop timer time_stop = xps_timer_read_counter(&timer); printf("\r\nDCT (retval = 0x%08x):\r\n",(unsigned int)retval[0]); print_matrix(my_output); printf("\r\nIDCT (retval = 0x%08x):\r\n",(unsigned int)retval[1]); print_matrix(my_idct_output); printf("*********************************\n"); printf("Create time = %u\n",time_create); printf("Start time = %u\n",time_start); printf("Stop time = %u\n",time_stop); printf("*********************************\n"); printf("Creation time (|Start - Create|) = %u\n",time_start - time_create); printf("Elapsed time (|Stop - Start|) = %u\n",time_stop - time_start); printf("Total time (|Create - Stop|) = %u\n",time_stop - time_create); return 0; }
int main( int argc, char *argv[] ) { if (NUM_THREADS > 2){ printf("CANNOT USE MORE THAN (2) HETEROGENEOUS THREADS!!!!\r\n"); return (-1); } // Timer variables xps_timer_t timer; int time_create, time_start, time_stop; // Mutex hthread_mutex_t * mutex = (hthread_mutex_t*)malloc( sizeof(hthread_mutex_t) ); hthread_mutex_init( mutex, NULL ); // Thread attribute structures Huint sta[NUM_THREADS]; void* retval[NUM_THREADS]; hthread_t tid[NUM_THREADS]; hthread_attr_t attr[NUM_THREADS]; targ_t thread_arg[NUM_THREADS]; // Setup Cache XCache_EnableICache(0xc0000801); // Create timer xps_timer_create(&timer, (int*)0x20400000); // Start timer xps_timer_start(&timer); // ************************************************************************************* extern unsigned char intermediate[]; extern unsigned int blink_handle_offset; unsigned int blink_handle = (blink_handle_offset) + (unsigned int)(&intermediate); // ************************************************************************************* int j = 0; printf("Code start address = 0x%08x\n", (unsigned int)&intermediate); for (j = 0; j < NUM_THREADS; j++) { // Initialize the attributes for the threads hthread_attr_init( &attr[j] ); hthread_attr_sethardware( &attr[j], (void*)base_array[j] ); } int num_ops = 0; for( num_ops = 0; num_ops < 1; num_ops = num_ops + 1) { printf("******* Round %d ********\n",num_ops); #ifdef USE_MB_THREAD printf("**** MB-based Threads ****\n"); #else printf("**** PPC-based Threads ****\n"); #endif // Initialize thread arguments for ( j= 0; j < NUM_THREADS; j++) { thread_arg[j].arg = 1 << ((j + 1)); thread_arg[j].mutex = mutex; } time_create = xps_timer_read_counter(&timer); // Create threads for (j = 0; j < NUM_THREADS; j++) { // Create the blink thread #ifdef USE_MB_THREAD // Create MB Thread sta[j] = hthread_create( &tid[j], &attr[j], (void*)blink_handle, (void*)(&thread_arg[j]) ); //printf( "Started MB Thread (TID = %d) \n", tid[j]); #else // Create SW Thread sta[j] = hthread_create( &tid[j], NULL, blink_thread, (void*)(&thread_arg[j]) ); //printf( "Started SW Thread (TID = %d) \n", tid[j]); #endif } // Allow created threads to begin running and start timer time_start = xps_timer_read_counter(&timer); printf("Waiting for threads...\n"); // Join on all threads for (j = 0; j < NUM_THREADS; j++) { hthread_join( tid[j], &retval[j] ); } // Grab stop time time_stop = xps_timer_read_counter(&timer); // Print out status for (j = 0; j < NUM_THREADS; j++) { printf("TID[%d] = 0x%08x, status = 0x%08x, retval = 0x%08x\n",j,tid[j],sta[j],(unsigned int)retval[j]); } printf("*********************************\n"); printf("Create time = %u\n",time_create); printf("Start time = %u\n",time_start); printf("Stop time = %u\n",time_stop); printf("*********************************\n"); printf("Creation time (|Start - Create|) = %u\n",time_start - time_create); printf("Elapsed time (|Stop - Start|) = %u\n",time_stop - time_start); } hthread_mutex_destroy( mutex ); free( mutex ); // Clean up the attribute structures for (j = 0; j < NUM_THREADS; j++) { hthread_attr_destroy( &attr[j] ); } printf ("-- Complete --\n"); // Return from main return 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; }
int run_tests() { if (NUM_THREADS > NUM_CPUS){ printf("CANNOT USE MORE THAN (%d) HETEROGENEOUS THREADS!!!!\r\n", NUM_CPUS); return (-1); } // Timer variables xps_timer_t timer; int time_create, time_start, time_stop; // Thread attribute structures Huint sta[NUM_THREADS]; void* retval[NUM_THREADS]; hthread_t tid[NUM_THREADS]; hthread_attr_t attr[NUM_THREADS]; targ_t thread_arg[NUM_THREADS]; // Setup Cache XCache_DisableDCache(); XCache_EnableICache(0xc0000801); // Create timer xps_timer_create(&timer, (int*)0x20400000); // Start timer xps_timer_start(&timer); // ************************************************************************************* extern unsigned char intermediate[]; extern unsigned int distance_handle_offset; unsigned int distance_handle = (distance_handle_offset) + (unsigned int)(&intermediate); printf("Code start address = 0x%08x\n", (unsigned int)&intermediate); // ************************************************************************************* int vals_x0[ARR_LENGTH]; int vals_x1[ARR_LENGTH]; int vals_y0[ARR_LENGTH]; int vals_y1[ARR_LENGTH]; int vals_ds[ARR_LENGTH]; int j = 0; for (j = 0; j < NUM_THREADS; j++) { // Initialize the attributes for the threads hthread_attr_init( &attr[j] ); hthread_attr_sethardware( &attr[j], (void*)base_array[j] ); } for (j = 0; j < ARR_LENGTH; j++) { vals_x0[j] = ARR_LENGTH - j; vals_y0[j] = ARR_LENGTH - j; vals_x1[j] = ARR_LENGTH - j + 1; vals_y1[j] = ARR_LENGTH - j; } #ifdef MY_DEBUG #endif int num_ops = 0; for( num_ops = 0; num_ops < 2; num_ops = num_ops + 1) { printf("******* Round %d ********\n",num_ops); #ifdef USE_MB_THREAD printf("**** MB-based Threads ****\n"); #else printf("**** PPC-based Threads ****\n"); #endif for (j = 0; j < ARR_LENGTH; j++) { vals_x0[j] = ARR_LENGTH - j; } // Initialize thread arguments int num_items = ARR_LENGTH/NUM_THREADS; int extra_items = ARR_LENGTH - (num_items*NUM_THREADS); for ( j= 0; j < NUM_THREADS; j++) { thread_arg[j].x0s = &vals_x0[j*(num_items)]; thread_arg[j].y0s = &vals_y0[j*(num_items)]; thread_arg[j].x1s = &vals_x1[j*(num_items)]; thread_arg[j].y1s = &vals_y1[j*(num_items)]; thread_arg[j].distances = &vals_ds[j*(num_items)]; thread_arg[j].length = num_items; } // Add in extra items for the last thread if needed thread_arg[j-1].length += extra_items; time_create = xps_timer_read_counter(&timer); // Create threads for (j = 0; j < NUM_THREADS; j++) { // Create the distance thread #ifdef USE_MB_THREAD // Create MB Thread sta[j] = hthread_create( &tid[j], &attr[j], (void*)distance_handle, (void*)(&thread_arg[j]) ); //printf( "Started MB Thread (TID = %d) \n", tid[j]); #else // Create SW Thread sta[j] = hthread_create( &tid[j], NULL, distance_thread, (void*)(&thread_arg[j]) ); //printf( "Started SW Thread (TID = %d) \n", tid[j]); #endif } // Allow created threads to begin running and start timer time_start = xps_timer_read_counter(&timer); // Join on all threads for (j = 0; j < NUM_THREADS; j++) { hthread_join( tid[j], &retval[j] ); } // Grab stop time time_stop = xps_timer_read_counter(&timer); // Print out status for (j = 0; j < NUM_THREADS; j++) { printf("TID[%d] = 0x%08x, status = 0x%08x, retval = 0x%08x\n",j,tid[j],sta[j],(unsigned int)retval[j]); } printf("*********************************\n"); printf("Create time = %u\n",time_create); printf("Start time = %u\n",time_start); printf("Stop time = %u\n",time_stop); printf("*********************************\n"); printf("Creation time (|Start - Create|) = %u\n",time_start - time_create); printf("Elapsed time (|Stop - Start|) = %u\n",time_stop - time_start); printf("Total time (|Create - Stop|) = %u\n",time_stop - time_create); } #ifdef MY_DEBUG for (j = 0; j < ARR_LENGTH; j++) { printf("D(%d) = %d\n",j,vals_ds[j]); } #endif // Clean up the attribute structures for (j = 0; j < NUM_THREADS; j++) { hthread_attr_destroy( &attr[j] ); } printf ("-- Complete --\n"); // Return from main return 0; }
//int main( int argc, char *argv[] ) int run_tests() { if (NUM_THREADS > NUM_CPUS){ printf("CANNOT USE MORE THAN (%d) HETEROGENEOUS THREADS!!!!\r\n",NUM_CPUS); return (-1); } // Timer variables xps_timer_t timer; int time_create, time_start, time_stop; // Thread attribute structures Huint sta[NUM_THREADS]; void* retval[NUM_THREADS]; hthread_t tid[NUM_THREADS]; hthread_attr_t attr[NUM_THREADS]; targ_t thread_arg[NUM_THREADS]; // Setup Cache XCache_DisableDCache(); XCache_EnableICache(0xc0000801); // Create timer xps_timer_create(&timer, (int*)0x20400000); // Start timer xps_timer_start(&timer); // ************************************************************************************* extern unsigned char intermediate[]; extern unsigned int sort_handle_offset; unsigned int sort_handle = (sort_handle_offset) + (unsigned int)(&intermediate); // ************************************************************************************* float local_data[ARR_LENGTH]; int j = 0; printf("Code start address = 0x%08x\n", (unsigned int)&intermediate); for (j = 0; j < NUM_THREADS; j++) { // Initialize the attributes for the threads hthread_attr_init( &attr[j] ); hthread_attr_sethardware( &attr[j], (void*)base_array[j] ); } for (j = 0; j < ARR_LENGTH; j++) { local_data[j] = (ARR_LENGTH - j)*1.00; } #ifdef MY_DEBUG show_array(&local_data[0], ARR_LENGTH); #endif int num_ops = 0; for( num_ops = 0; num_ops < 2; num_ops = num_ops + 1) { printf("******* Round %d ********\n",num_ops); #ifdef USE_MB_THREAD printf("**** MB-based Threads ****\n"); #else printf("**** PPC-based Threads ****\n"); #endif for (j = 0; j < ARR_LENGTH; j++) { local_data[j] = ARR_LENGTH - j; } // Initialize thread arguments for ( j= 0; j < NUM_THREADS; j++) { thread_arg[j].data = &local_data[j*(ARR_LENGTH/NUM_THREADS)]; thread_arg[j].length = ARR_LENGTH/NUM_THREADS; } time_create = xps_timer_read_counter(&timer); // Create threads for (j = 0; j < NUM_THREADS; j++) { // Create the sort thread #ifdef USE_MB_THREAD // Create MB Thread sta[j] = hthread_create( &tid[j], &attr[j], (void*)sort_handle, (void*)(&thread_arg[j]) ); //printf( "Started MB Thread (TID = %d) \n", tid[j]); #else // Create SW Thread sta[j] = hthread_create( &tid[j], NULL, bubblesort_thread, (void*)(&thread_arg[j]) ); //printf( "Started SW Thread (TID = %d) \n", tid[j]); #endif } // Allow created threads to begin running and start timer time_start = xps_timer_read_counter(&timer); // Join on all threads for (j = 0; j < NUM_THREADS; j++) { hthread_join( tid[j], &retval[j] ); } // Grab stop time time_stop = xps_timer_read_counter(&timer); // Print out status for (j = 0; j < NUM_THREADS; j++) { printf("TID[%d] = 0x%08x, status = 0x%08x, retval = 0x%08x\n",j,tid[j],sta[j],(unsigned int)retval[j]); } printf("*********************************\n"); printf("Create time = %u\n",time_create); printf("Start time = %u\n",time_start); printf("Stop time = %u\n",time_stop); printf("*********************************\n"); printf("Creation time (|Start - Create|) = %u\n",time_start - time_create); printf("Elapsed time (|Stop - Start|) = %u\n",time_stop - time_start); printf("Total time (|Create - Stop|) = %u\n",time_stop - time_create); } #ifdef MY_DEBUG show_array(&local_data[0], ARR_LENGTH); check_array(&local_data[0], ARR_LENGTH); // Note there will be errors as the data set is not merged #endif // Clean up the attribute structures for (j = 0; j < NUM_THREADS; j++) { hthread_attr_destroy( &attr[j] ); } printf ("-- Complete --\n"); // Return from main return 0; }
int run_tests() { // Timer variables xps_timer_t timer; int time_create, time_start, time_unlock, time_stop; // Mutex hthread_mutex_t * mutex = (hthread_mutex_t*)malloc( sizeof(hthread_mutex_t) ); hthread_mutex_init( mutex, NULL ); float min; // Thread attribute structures Huint sta[NUM_THREADS]; void* retval[NUM_THREADS]; hthread_t tid[NUM_THREADS]; hthread_attr_t attr[NUM_THREADS]; targ_t thread_arg[NUM_THREADS]; // Setup Cache XCache_DisableDCache(); XCache_EnableICache(0xc0000801); // Create timer xps_timer_create(&timer, (int*)0x20400000); // Start timer xps_timer_start(&timer); // ************************************************************************************* extern unsigned char intermediate[]; extern unsigned int min_handle_offset; unsigned int min_handle = (min_handle_offset) + (unsigned int)(&intermediate); // ************************************************************************************* printf("Code start address = 0x%08x\n", (unsigned int)&intermediate); int i = 0; float main_array[ARRAY_LENGTH]; printf("Addr of array = 0x%08x\n",(unsigned int)&main_array[0]); for (i = 0; i < ARRAY_LENGTH; i++) { main_array[i] = (i+2)*3.14f; } int num_items = ARRAY_LENGTH/NUM_THREADS; int extra_items = ARRAY_LENGTH - (num_items*NUM_THREADS); float * start_addr = &main_array[0]; for (i = 0; i < NUM_THREADS; i++) { // Initialize the attributes for the hardware threads hthread_attr_init( &attr[i] ); hthread_attr_sethardware( &attr[i], (void*)base_array[i] ); // Initialize thread arguments thread_arg[i].num_items = num_items; thread_arg[i].data_ptr = start_addr; thread_arg[i].min_mutex = mutex; thread_arg[i].min = &min; start_addr+=num_items; } // Add in extra items for the last thread if needed thread_arg[i-1].num_items += extra_items; int num_ops = 0; for( num_ops = 0; num_ops < 2; num_ops = num_ops + 1) { printf("******* Round %d ********\n",num_ops); #ifdef USE_MB_THREAD printf("**** MB-based Threads ****\n"); #else printf("**** PPC-based Threads ****\n"); #endif min = 9999999; // Lock mutex before hand so that timing will not include thread creation time hthread_mutex_lock(mutex); // Start timing thread create time_create = xps_timer_read_counter(&timer); for (i = 0; i < NUM_THREADS; i++) { // Create the worker threads #ifdef USE_MB_THREAD // Create MB Thread sta[i] = hthread_create( &tid[i], &attr[i], (void*)(min_handle), (void*)(&thread_arg[i]) ); #else // Create SW Thread sta[i] = hthread_create( &tid[i], NULL, min_thread, (void*)(&thread_arg[i]) ); #endif } // Allow created threads to begin running and start timer time_start = xps_timer_read_counter(&timer); hthread_mutex_unlock(mutex); time_unlock = xps_timer_read_counter(&timer); // Wait for the threads to exit //printf( "Waiting for thread(s) to complete... \n" ); for (i = 0; i < NUM_THREADS; i++) { hthread_join( tid[i], &retval[i] ); } time_stop = xps_timer_read_counter(&timer); // Display results printf("Min = %f\n",min); for (i = 0; i < NUM_THREADS; i++) { printf("TID = 0x%08x, status = 0x%08x, retval = 0x%08x\n",tid[i],sta[i],(Huint)retval[i]); } printf("*********************************\n"); printf("Create time = %u\n",time_create); printf("Start time = %u\n",time_start); printf("Unlock time = %u\n",time_unlock); printf("Stop time = %u\n",time_stop); printf("*********************************\n"); printf("Creation time (|Start - Create|) = %u\n",time_start - time_create); printf("Unlock time (|Unlock - Start|) = %u\n",time_unlock - time_start); printf("Elapsed time (|Stop - Start|) = %u\n",time_stop - time_start); } hthread_mutex_destroy( mutex ); free( mutex ); // Clean up the attribute structures for (i = 0; i < NUM_THREADS; i++) { hthread_attr_destroy( &attr[i] ); } printf ("-- Complete --\n"); // Return from main return 0; }