Exemplo n.º 1
0
static void build_histogram_thread_create(void)
{
	int error;
	pthread_attr_init(&build_histogram_attr);
	pthread_attr_setstacksize(&build_histogram_attr, STACK_SIZE);
	
#ifdef HW_HISTOGRAM
	printf("building histogram in hardware...\n");
	rthread_attr_init(&build_histogram_rattr);
	rthread_attr_setslotnum(&build_histogram_rattr, 0);
	rthread_attr_setresources(&build_histogram_rattr, build_histogram_resources, 2);
	error = rthread_create(
			&build_histogram_thread,
			&build_histogram_attr,
			&build_histogram_rattr,
			NULL);
#else
	printf("building histogram in software...\n");
	error = pthread_create(
			&build_histogram_thread,
			&build_histogram_attr,
			build_histogram_entry,
			NULL);
#endif
	
	if(error){
		perror("pthread_create: build_histogram");
		exit(1);
	}

}
Exemplo n.º 2
0
static inline int posix_hwt_create(int nslot, void * init_data, reconos_res_t * res, int nres)
{

        rthread_attr_init(&rattr[nslot]);
        rthread_attr_setslotnum(&rattr[nslot], nslot);
        rthread_attr_setresources(&rattr[nslot], res, nres);

        //pthread_attr_init(&posix_attr);

        return rthread_create(&posix_thread[nslot], &rattr[nslot], init_data);
}
Exemplo n.º 3
0
/**
   creates sample HW threads (dynamic)

   @param number_of_threads: number of threads for sampling step
   @param hw_circuit: hardware circuit of the thread
   @param parameter: pointer to a array filled with parameter (size <= 128 byte)
   @param number_of_parameter: number of parameter in parameter array
*/
void set_sample_hw_dynamic (unsigned int number_of_threads, reconos_circuit_t *  hw_circuit, int * parameter, unsigned int number_of_parameter){


     
     int i;

     // terminate old sw threads if needed
     if (number_of_threads < 0 || number_of_threads == hw_number_of_threads_s_dynamic) 
     {
          return;
     } 
     else 
     {
          if (number_of_threads < hw_number_of_threads_s_dynamic)
          {
               // remove slots, which are not needed
               sample_hw_delete_dynamic(hw_number_of_threads_s_dynamic - number_of_threads);
               hw_number_of_threads_s_dynamic = number_of_threads;
               return;
          }
     }


     if (information_s_dynamic == NULL)
     {
        // set information
        information_s_dynamic = (information_struct_s *) malloc (sizeof(information_struct_s));
        information_s_dynamic[0].particles = particles;
        information_s_dynamic[0].number_of_particles = N;
        information_s_dynamic[0].particle_size = sizeof(particle);
        information_s_dynamic[0].max_number_of_particles = 8096 / sizeof(particle);
        information_s_dynamic[0].block_size = block_size;
        information_s_dynamic[0].parameter = parameter;
        information_s_dynamic[0].number_of_parameter = number_of_parameter;
     }

     if (res_s_dynamic == NULL)
     {
        // set ressources
        res_s_dynamic = (reconos_res_t *) malloc (4 * sizeof(reconos_res_t));
        res_s_dynamic[0].ptr  =  mb_sampling_handle;
        res_s_dynamic[0].type =  CYG_MBOX_HANDLE_T ;
        res_s_dynamic[1].ptr  =  mb_sampling_done_handle;
        res_s_dynamic[1].type =  CYG_MBOX_HANDLE_T ;
        res_s_dynamic[2].ptr  =  hw_mb_sampling_measurement_handle;
        res_s_dynamic[2].type =  CYG_MBOX_HANDLE_T ;
        res_s_dynamic[3].ptr  =  hw_mb_sampling_exit_handle;
        res_s_dynamic[3].type =  CYG_MBOX_HANDLE_T ;
     }
     
     // create and resume hw sampling threads in eCos
     for (i = 0; i < (number_of_threads - hw_number_of_threads_s_dynamic); i++)
     {

          hw_thread_node * new_node = malloc (sizeof(hw_thread_node));
          new_node->sw_attr = (pthread_attr_t *) malloc (sizeof(pthread_attr_t));
          new_node->hw_attr = (rthread_attr_t *) malloc (sizeof(rthread_attr_t));
     
          int ret = pthread_attr_init(new_node->sw_attr);
          //diag_printf("\nS: p_thread_attr_init = %d", ret);
          ret = pthread_attr_setstacksize(new_node->sw_attr, STACK_SIZE);
          //diag_printf("\nS: p_thread_attr_set_stacksize = %d", ret);
          ret = rthread_attr_init(new_node->hw_attr);
          //diag_printf("\nS: r_thread_attr_init = %d", ret);
          ret = rthread_attr_setcircuit(new_node->hw_attr, hw_circuit);
          //diag_printf("\nS: r_thread_set_circuit = %d", ret);
	  //rthread_attr_setstatesize(new_node->hw_attr, 16384);

          ret = rthread_attr_setresources(new_node->hw_attr, res_s_dynamic, 4);
          //diag_printf("\nS: r_thread_attr_setresources = %d", ret);

          ret = rthread_create(&(new_node->hw_thread), new_node->sw_attr, new_node->hw_attr, 
                 (void*)information_s_dynamic); 
          //diag_printf("\nS: r_thread_create = %d", ret);

          // insert node to list
          new_node->next = hw_threads_s_dynamic;
          hw_threads_s_dynamic = new_node;
     }

     // set number of hw threads
     hw_number_of_threads_s_dynamic = number_of_threads;
     
}
Exemplo n.º 4
0
/**
   creates sample HW threads (and deletes 'old' hw threads) (static)

   @param number_of_threads: number of threads for sampling step
   @param reconos_slots: pointer to array including the slot numbers, where the sampling hw threads are connected with 
   @param parameter: pointer to a array filled with parameter (size <= 128 byte)
   @param number_of_parameter: number of parameter in parameter array
*/
void set_sample_hw_static (unsigned int number_of_threads, unsigned int * reconos_slots, int * parameter, unsigned int number_of_parameter){

     
     int i;

     // terminate old sw threads if needed
     if (hw_number_of_threads_s > 0) {

          sample_hw_delete_static();
                
          for (i=0; i<hw_number_of_threads_s;i++){
  
               free(hw_thread_s_stack[i]);
          }

          free(hw_thread_s);
          free(hw_thread_s_stack);
          free(hw_thread_s_handle);
          free(res_s);
          free(hw_thread_s_attr);
          free(information_s);
     }

     // set number of hw threads
     hw_number_of_threads_s = number_of_threads;

     if (number_of_threads < 1) return;

     // set information
     information_s = (information_struct_s *) malloc (sizeof(information_struct_s));
         

     // set information
     information_s[0].particles = particles;
     information_s[0].number_of_particles = N;
     information_s[0].particle_size = sizeof(particle);
     information_s[0].max_number_of_particles = 8096 / sizeof(particle);
     information_s[0].block_size = block_size;

     // parameter
     information_s[0].parameter = parameter;
     information_s[0].number_of_parameter = number_of_parameter;

     //diag_printf("\ninformation address (sampling): %d", (int)information_s);
     //diag_printf("\nparticle address: %d", (int)particles);
     
     // create hw threads variables
     hw_thread_s = (cyg_thread *) malloc (number_of_threads * sizeof(cyg_thread));

     // create hw thread stacks 
     hw_thread_s_stack = (char **) malloc (number_of_threads * sizeof (char *));
     for (i=0; i<number_of_threads; i++){
          
          hw_thread_s_stack[i] = (char *) malloc (STACK_SIZE * sizeof(char));     
     }
 
     // create hw handles
     hw_thread_s_handle = (cyg_handle_t *) malloc (number_of_threads * sizeof(cyg_handle_t));

     // attributes for hw threads
     hw_thread_s_attr = malloc (number_of_threads * sizeof(rthread_attr_t));
     

     // set ressources
     res_s = (reconos_res_t *) malloc (4 * sizeof(reconos_res_t));
           
     res_s[0].ptr  =  mb_sampling_handle;
     res_s[0].type =  CYG_MBOX_HANDLE_T ;
     res_s[1].ptr  =  mb_sampling_done_handle;
     res_s[1].type =  CYG_MBOX_HANDLE_T ;
     res_s[2].ptr  =  hw_mb_sampling_measurement_handle;
     res_s[2].type =  CYG_MBOX_HANDLE_T ;
     res_s[3].ptr  =  hw_mb_sampling_exit_handle;
     res_s[3].type =  CYG_MBOX_HANDLE_T ;    
     
     // create and resume hw sampling threads in eCos
     for (i = 0; i < number_of_threads; i++){
     
          // set attributes
          rthread_attr_init(&hw_thread_s_attr[i]);
          // set slot number
          rthread_attr_setslotnum(&hw_thread_s_attr[i], reconos_slots[i]);
          // add ressources
          rthread_attr_setresources(&hw_thread_s_attr[i], res_s, 3); 

          //diag_printf("\n--> hw sampling (%d, slot %d) dcr address: %d", 
          //   i, reconos_slots[i], hw_thread_s_attr[i].dcr_base_addr);

          // create hw sampling thread
          reconos_hwthread_create(
	      (cyg_addrword_t) PRIO_HW,  // priority
              &hw_thread_s_attr[i], // attributes
              (cyg_addrword_t) &information_s[0], // entry data
              "HW_SAMPLING",           // thread name 
               hw_thread_s_stack[i],   // stack
               STACK_SIZE,             // stack size 
               &hw_thread_s_handle[i], // thread handle
               &hw_thread_s[i]         // thread object
          );
          
	  // resume threads
          cyg_thread_resume(hw_thread_s_handle[i]);  
     }
	
     
}
Exemplo n.º 5
0
/**
   creates observation HW threads

   @param number_of_threads: number of threads for observation step
   @param reconos_slots: pointer to array including the slot numbers, where the observation hw threads are connected to
   @param parameter: pointer to a array filled with parameter (size <= 128 byte)
   @param number_of_parameter: number of parameter in parameter array
*/
void set_observe_hw (unsigned int number_of_threads, unsigned int * reconos_slots, int * parameter, unsigned int number_of_parameter){

     
     int i;

     // terminate old sw threads if needed
     if (hw_number_of_threads_o > 0){

       observation_hw_delete();

        // free all variables
        for (i=0; i<hw_number_of_threads_o;i++){
   
            free(hw_thread_o_stack[i]);
         }

        free(hw_thread_o);
        free(hw_thread_o_stack);
        free(hw_thread_o_handle);
        free(res_o);
        free(hw_thread_o_attr);
        free(information_o);
     }

     // set number of hw threads
     hw_number_of_threads_o = number_of_threads;

     if (number_of_threads < 1) return;

     // set information
     information_o = (information_struct_o *) malloc (sizeof(information_struct_o));
           

     // set information particles
     information_o[0].particles = particles;
     information_o[0].number_of_particles = N;
     information_o[0].particle_size = sizeof(particle);
     information_o[0].block_size = block_size;
     information_o[0].observation_size = sizeof(observation);
     information_o[0].observations = observations;
     information_o[0].input = &observations_input;
     information_o[0].parameter_size = (int) number_of_parameter;
     information_o[0].parameter = parameter;

     
     // create hw threads variables
     hw_thread_o = (cyg_thread *) malloc (number_of_threads * sizeof(cyg_thread));

     // create hw thread stacks 
     hw_thread_o_stack = (char **) malloc (number_of_threads * sizeof (char *));
     for (i=0; i<number_of_threads; i++){
          
          hw_thread_o_stack[i] = (char *) malloc (STACK_SIZE * sizeof(char));     
     }
 
     // create hw handles
     hw_thread_o_handle = (cyg_handle_t *) malloc (number_of_threads * sizeof(cyg_handle_t));

     // set ressources
     res_o = (reconos_res_t *) malloc (3 * sizeof(reconos_res_t));
          
     res_o[0].ptr  =  mb_sampling_done_handle;
     res_o[0].type =  CYG_MBOX_HANDLE_T ;
     res_o[1].ptr  =  mb_importance_handle;
     res_o[1].type =  CYG_MBOX_HANDLE_T ;
     res_o[2].ptr  =  hw_mb_observation_measurement_handle;
     res_o[2].type =  CYG_MBOX_HANDLE_T ;

     // attributes for hw threads
     hw_thread_o_attr = malloc (number_of_threads * sizeof(rthread_attr_t));

     // create and resume hw observation threads in eCos
     for (i = 0; i < number_of_threads; i++){
     
         
          // set attributes
          rthread_attr_init(&hw_thread_o_attr[i]);
          // set slot number
          rthread_attr_setslotnum(&hw_thread_o_attr[i], reconos_slots[i]);
          // add ressources
          rthread_attr_setresources(&hw_thread_o_attr[i], res_o, 3); 

          //diag_printf("\n--> hw observation (%d, slot %d) dcr address: %d", i, reconos_slots[i], hw_thread_o_attr[i].dcr_base_addr);

          // create hw observation thread
          reconos_hwthread_create(
	      (cyg_addrword_t) PRIO_HW,  // priority
              &hw_thread_o_attr[i], // attributes
              (cyg_addrword_t) &information_o[0] , // entry data
              "HW_OBSERVATION",        // thread name 
               hw_thread_o_stack[i],   // stack
               STACK_SIZE,             // stack size 
               &hw_thread_o_handle[i], // thread handle
               &hw_thread_o[i]         // thread object
          );
          
	  // resume threads
          cyg_thread_resume(hw_thread_o_handle[i]);   
      }
    

}
Exemplo n.º 6
0
int main( int argc, char *argv[] )
{

    unsigned int i, start_count = 0, done_count = 0;
    timing_t t_start = 0, t_stop = 0, t_gen = 0, t_sort = 0, t_merge =
        0, t_check = 0;
    unsigned int *addr;
    unsigned int dummy;
    int retval;

    printf( "-------------------------------------------------------\n"
            "ReconOS hardware multithreading case study (sort)\n"
            "(c) Computer Engineering Group, University of Paderborn\n\n"
            "eCos/POSIX, multi-threaded hardware version (" __FILE__ ")\n"
            "Compiled on " __DATE__ ", " __TIME__ ".\n"
            "-------------------------------------------------------\n\n" );

#ifdef USE_CACHE
    printf( "enabling data cache for external ram\n" );
    XCache_EnableDCache( 0x80000000 );
#else
    printf( "data cache disabled\n" );
    XCache_DisableDCache(  );
#endif

    data = buf_a;

    //----------------------------------
    //-- GENERATE DATA
    //----------------------------------
    printf( "Generating data..." );
    t_start = gettime(  );
    generate_data( data, SIZE );
    t_stop = gettime(  );
    t_gen = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

#ifdef USE_CACHE
    // flush cache contents - the hardware can only read from main memory
    // TODO: storing could be more efficient
    printf( "Flushing cache..." );
    XCache_EnableDCache( 0x80000000 );
    printf( "done\n" );
#endif

    //----------------------------------
    //-- SORT DATA
    //----------------------------------
    // create mail boxes for 'start' and 'complete' messages
    mb_start_attr.mq_flags   = mb_done_attr.mq_flags   = 0;
    mb_start_attr.mq_maxmsg  = mb_done_attr.mq_maxmsg  = 10;
    mb_start_attr.mq_msgsize = mb_done_attr.mq_msgsize = 4;
    mb_start_attr.mq_curmsgs = mb_done_attr.mq_curmsgs = 0;

    // unlink mailboxes, if they exist
    retval = mq_unlink("/mb_start");
    if (retval != 0 && errno != ENOENT) {    // we don't care if it doesn't exist
        diag_printf("unable to unlink mb_start");
    }
    retval = mq_unlink("/mb_done");
    if (retval != 0 && errno != ENOENT) {    // we don't care if it doesn't exist
        diag_printf("unable to unlink mb_done");
    }

    // open/create mailboxes
    mb_start = mq_open("/mb_start",
            O_RDWR | O_CREAT, S_IRWXU | S_IRWXG,
            &mb_start_attr);
    if (mb_start == (mqd_t)-1) {
        diag_printf("unable to create mb_start");
    }
    mb_done = mq_open("/mb_done",
            O_RDWR | O_CREAT, S_IRWXU | S_IRWXG,
            &mb_done_attr);
    if (mb_done == (mqd_t)-1) {
        diag_printf("unable to create mb_done");
    }

    // create sorting sowftware threads
    for ( i = 0; i < MT_HW_NUM_SW_THREADS; i++ ) {
        pthread_attr_init(&thread_sorter_attr[i]);
        pthread_create(&thread_sorter[i],
                &thread_sorter_attr[i],
                sort8k_entry_posix, (void*)i);
    }

    // create sorting hardware thread
    pthread_attr_init(&hwthread_sorter_attr);
    pthread_attr_setstacksize(&hwthread_sorter_attr, STACK_SIZE);
    rthread_attr_init(&hwthread_sorter_hwattr);
    rthread_attr_setslotnum(&hwthread_sorter_hwattr, 0);
    rthread_attr_setresources(&hwthread_sorter_hwattr, hwthread_sorter_resources, 2);
    rthread_create(&hwthread_sorter, &hwthread_sorter_attr, &hwthread_sorter_hwattr, (void*)0);

    printf( "Sorting data..." );
    i = 0;

    t_start = gettime(  );

    // put 9 messages into mb_start
    while ( start_count < 9 ) {
        addr = &data[i];
        if ( mq_send( mb_start, ( void * ) &addr, sizeof(addr), 0 ) == 0 ) {
            start_count++;
            i += N;
        } else {                                                          
            perror("while sending to mq_send");
            break;
        }
    }

    t_stop = gettime(  );
    t_sort += calc_timediff_ms( t_start, t_stop );

    while ( done_count < SIZE / N ) {
        t_start = gettime(  );
        // if we have something to distribute,
        // put one into the start mailbox
        if ( start_count < SIZE / N ) {
            addr = &data[i];
            if ( mq_send( mb_start, ( void * ) &addr, sizeof(addr), 0 ) == 0 ) {
                start_count++;
                i += N;
            } else {                                                          
                perror("while sending to mq_send");
                break;
            }
        }
        // see whether anybody's done
        if ( mq_receive( mb_done, (void*)&dummy, sizeof(dummy), 0 ) == sizeof(dummy) ) {
            done_count++;
        } else {
            perror( "while receiving from mq_done" );
            break;
        }
        t_stop = gettime(  );
        t_sort += calc_timediff_ms( t_start, t_stop );
    }
    printf( "done\n" );

#ifdef USE_CACHE
    // flush cache contents
    // TODO: invalidating would suffice
    printf( "Flushing cache..." );
    XCache_EnableDCache( 0x80000000 );
    printf( "done\n" );
#endif


    //----------------------------------
    //-- MERGE DATA
    //----------------------------------
    printf( "Merging data..." );
    t_start = gettime(  );
    data = recursive_merge( data, buf_b, SIZE, N, simple_merge );
    t_stop = gettime(  );
    t_merge = calc_timediff_ms( t_start, t_stop );
    printf( "done\n" );

    //----------------------------------
    //-- CHECK DATA
    //----------------------------------
    printf( "Checking sorted data..." );
    t_start = gettime(  );
    if ( check_data( data, SIZE ) != 0 )
        printf( "CHECK FAILED!\n" );
    else
        printf( "check successful.\n" );
    t_stop = gettime(  );
    t_check = calc_timediff_ms( t_start, t_stop );

    printf( "\nRunning times (size: %d words):\n"
            "\tGenerate data: %d ms\n"
            "\tSort data    : %d ms\n"
            "\tMerge data   : %d ms\n"
            "\tCheck data   : %d ms\n"
            "\nTotal computation time (sort & merge): %d ms\n",
            SIZE, t_gen, t_sort, t_merge, t_check, t_sort + t_merge );


    return 0;

}
Exemplo n.º 7
0
int main() {	
 // send message queue
	char *send_buf;
	char *recv_buf;

	size_t len = 4;
	unsigned int prio = 1;
	int n = 0;
	struct mq_attr	hw_sw_attr;
	struct mq_attr	sw_hw_attr;

	mqd_t mqd_hw_sw;
	mqd_t mqd_sw_hw;

 	hw_sw_attr.mq_flags   = 0;
	hw_sw_attr.mq_maxmsg  = 10;
	hw_sw_attr.mq_msgsize = len;
	hw_sw_attr.mq_curmsgs = 0;
 
	sw_hw_attr.mq_flags   = 0;
	sw_hw_attr.mq_maxmsg  = 10;
	sw_hw_attr.mq_msgsize = len;
	sw_hw_attr.mq_curmsgs = 0;
 
	if ((mqd_hw_sw = mq_open("/hw_sw", O_RDWR|O_CREAT, 777,  &hw_sw_attr)) < 0)
		perror("open hw_sw");
	if ((mqd_sw_hw = mq_open("/sw_hw", O_RDWR|O_CREAT, 777, &sw_hw_attr)) < 0)
		perror("open sw_hw");

	send_buf = malloc(1024);
	recv_buf = malloc(1024);
	memset(send_buf, 0, 1024);
	memset(recv_buf, 0, 1024);

	rthread_attr_t rcv_attr;
	rthread_attr_init(&rcv_attr);
        reconos_res_t res[2] = {{&mqd_sw_hw,PTHREAD_MQD_T }, 
                        {&mqd_hw_sw,PTHREAD_MQD_T }};

	rthread_attr_init(&rcv_attr);
        rthread_attr_setslotnum(&rcv_attr, 0); 
        rthread_attr_setresources(&rcv_attr, res, 2);
	rthread_t mythread;
        rthread_create( &mythread, &rcv_attr, NULL);


	if (mq_send(mqd_sw_hw, &send_buf, len, prio) < 0)
		perror("mq_send");
	fprintf(stderr, "--------------->message sent, ptr = %i\n", send_buf);
	if (mq_send(mqd_sw_hw, &recv_buf, len, prio) < 0)
                  perror("mq_send");
        fprintf(stderr, "--------------->message sent, ptr = %i\n", recv_buf);
	int msglen = 12;
	memcpy(send_buf, "hello world", msglen);
	if (mq_send(mqd_sw_hw, &msglen, len, prio) < 0)
                   perror("mq_send");
        fprintf(stderr, "--------------->message sent, ptr = %i\n", recv_buf);


	if ((n = mq_receive(mqd_hw_sw, &msglen, len, &prio)) < 0)
		perror("my_receive");
	fprintf(stderr, "--------------->message received \n");

	
	fprintf(stderr, "------------------> new message is %d bytes long \n", msglen);
	fprintf(stderr, "memory at location \"recv_buf\" %s\n", recv_buf);
	fprintf(stderr, "memory at location \"recv_buf + 16\" %s\n", recv_buf + 16);

	sleep(10);

	return 1;


}
Exemplo n.º 8
0
///
/// Application entry function. Sets up data strctures and threads.
///
void cyg_user_start()
{
    struct udp_connection *con;
//    cyg_sem_t *sem_array[8];
    reconos_res_t sem_array_laplace[8];
    reconos_res_t sem_array_display[8];
    int i;

#if defined(USE_DCACHE)
    // enable caches for DRAM
    XCache_EnableDCache(0x80000000);
#endif

    diag_printf("Hello embedded world!\n"
                "This is " __FILE__ " (ReconOS), built " __DATE__ ", "
                __TIME__ "\n");

    // initialize hardware
    diag_printf("Initializing hardware...\n");
    init();

    // initialize image buffers
    diag_printf("Initializing image buffers...\n");
    for (i = 0; i < 2; i++) {
		byte_buffer_init(&input_buffer[i], WIDTH, HEIGHT);                            // one image + four lines (???)
		byte_buffer_fill(&input_buffer[i], 0);
		byte_buffer_init(&laplace_buffer[i], WIDTH, HEIGHT);                          // one image
		byte_buffer_fill(&laplace_buffer[i], 0);
    }

    // initialize fake output image buffer
    output_buffer[0].width = WIDTH;                                               // irrelevant
    output_buffer[0].height = HEIGHT;                                             // irrelevant
    output_buffer[0].data = fb_info.fb;                                           // this points to the VGA frame buffer
    // NOTE: the semaphores of this buffer are not used and therefore not initialized

    diag_printf
        ("Buffer addresses: input: 0x%08X, laplace: 0x%08X, output: 0x%08X\n",
         input_buffer[0].data, laplace_buffer[0].data, output_buffer[0].data);

    // set up UDP connection        
    diag_printf("Setting up UDP networking...\n");
    con = udp_connection_create(inet_addr("192.168.1.2"));

    // initialize thread info structures
    diag_printf("Initializing thread info structures...\n");
    buffer_thread_info_init(&input_thread_info, 2,  NULL, input_buffer);/*, NULL,
                            &laplace_rdy, NULL, &input_new);*/
    buffer_thread_info_init(&laplace_thread_info, 2, input_buffer,
                            laplace_buffer);/*, &laplace_rdy, &display_rdy,
                            &input_new, &laplace_new);*/
    buffer_thread_info_init(&display_thread_info, 2, laplace_buffer,
                            output_buffer);/*, &display_rdy, NULL,
                            &laplace_new, NULL);*/

    // initialize semaphores        
/*    diag_printf("Initializing semaphores...\n");
    cyg_semaphore_init(&input_new, 0);
    cyg_semaphore_init(&laplace_rdy, 1);
    cyg_semaphore_init(&laplace_new, 0);
    cyg_semaphore_init(&display_rdy, 1);*/

    // pass connection info to input thread 
    input_thread_info.data = (cyg_addrword_t) con;

    diag_printf("Creating threads...");

    // create input thread
    diag_printf("input...");
    cyg_thread_create(16,                                                      // scheduling info (eg pri)  
                      entry_buffer_recv,                                       // entry point function     
                      (cyg_addrword_t) & input_thread_info,                    // entry data                
                      "INPUT THREAD",                                          // optional thread name      
                      input_stack,                                             // stack base                
                      MYTHREAD_STACK_SIZE,                                     // stack size,       
                      &input_handle,                                           // returned thread handle    
                      &input_thread                                            // put thread here           
        );

#if !defined(USE_HW_LAPLACE)
    // create laplace software thread
    diag_printf("laplace_sw...");
    cyg_thread_create(16,                                                      // scheduling info (eg pri)  
                      entry_buffer_laplace,                                    // entry point function      
                      (cyg_addrword_t) & laplace_thread_info,                  // entry data
                      "LAPLACE THREAD (SW)",                                   // optional thread name     
                      laplace_stack,                                           // stack base               
                      MYTHREAD_STACK_SIZE,                                     // stack size,      
                      &laplace_handle,                                         // returned thread handle 
                      &laplace_thread                                          // put thread here       
        );
#else
    // create laplace hardware thread
    diag_printf("laplace_hw...");
    fill_sem_array(sem_array_laplace, &laplace_thread_info);
    rthread_attr_init(&laplace_hwthread_attr);
    rthread_attr_setslotnum(&laplace_hwthread_attr, 0);
    rthread_attr_setresources(&laplace_hwthread_attr, sem_array_laplace, 8);
    reconos_hwthread_create(16,                                                // scheduling info (eg pri)  
                            &laplace_hwthread_attr,                            // hw thread attributes
                            shm_init(&laplace_thread_info),                    // init data
                            "LAPLACE_THREAD (HW)",                             // optional thread name      
                            laplace_stack,                                     // stack base                
                            MYTHREAD_STACK_SIZE,                               // stack size,           
                            &laplace_handle,                                   // returned thread handle    
                            &laplace_hwthread);                                // put thread here       
#endif

#if !defined(USE_HW_DISPLAY)
    // create display software thread
    diag_printf("display_sw...");
    cyg_thread_create(16,                                                      // scheduling info (eg pri)  
                      entry_buffer_display,                                    // entry point function     
                      (cyg_addrword_t) & display_thread_info,                  // entry data
                      "DISPLAY THREAD",                                        // optional thread name      
                      display_stack,                                           // stack base               
                      MYTHREAD_STACK_SIZE,                                     // stack size,       
                      &display_handle,                                         // returned thread handle
                      &display_thread                                          // put thread here       
        );
#else
    // create display hardware thread
    diag_printf("display_hw...");
    fill_sem_array(sem_array_display, &display_thread_info);
    rthread_attr_init(&display_hwthread_attr);
    rthread_attr_setslotnum(&display_hwthread_attr, 0);
    rthread_attr_setresources(&display_hwthread_attr, sem_array_display, 8);
    reconos_hwthread_create(16,                                                // scheduling info (eg pri)  
                            &display_hwthread_attr,                            // hw thread attributes
                            shm_init(&display_thread_info),                    // init data
                            "DISPLAY_THREAD (HW)",                             // optional thread name      
                            display_stack,                                     // stack base                
                            MYTHREAD_STACK_SIZE,                               // stack size,           
                            &display_handle,                                   // returned thread handle    
                            &display_hwthread,                                 // put thread here       
                            (void *) XPAR_PLB_RECONOS_SLOT_1_BASEADDR, XPAR_OPB_INTC_0_PLB_RECONOS_SLOT_1_INTERRUPT_INTR + 1,   // associated interrupt vector
                            shm_init(&display_thread_info), SHM_SIZE,
                            sem_array, 8);
#endif

    diag_printf("\nStarting threads...\n");

    cyg_thread_resume(input_handle);
    cyg_thread_resume(laplace_handle);
    cyg_thread_resume(display_handle);

    diag_printf("end of main()\n");

}