// Helper function to keep code base small
void gport_ima_bench(struct rusage *_start,
                     struct rusage *_finish,
                     unsigned long int *_num_iterations,
                     unsigned int _n)
{
    // initialize port
    gport p = gport_create(2*_n-1,sizeof(int));

    int w[_n];  // external buffer for writing
    int r[_n];  // external buffer for reading

    unsigned long int i;

    // start trials:
    //   write to port, read from port
    getrusage(RUSAGE_SELF, _start);
    for (i=0; i<(*_num_iterations); i++) {
        // producer: write data to port from external buffer
        gport_produce(p,(void*)w,_n);

        // consumer: read data from port to external buffer
        gport_consume(p,(void*)r,_n);
    }
    getrusage(RUSAGE_SELF, _finish);
    *_num_iterations *= _n;

    gport_destroy(p);
}
void producer_handler ( void *_ptr )
{
    gport p = (gport) _ptr;
    unsigned int i, j, n=0;
    int w[PRODUCER_SIZE];
    int eom;

    for (i=0; i<10; i++) {
        for (j=0; j<PRODUCER_SIZE; j++)
            w[j] = n++;

        printf("  producer waiting for %u samples...\n", PRODUCER_SIZE);
        eom = gport_produce(p,(void*)w,PRODUCER_SIZE);

        if (eom) {
            printf("producer received eom\n");
            break;
        }

        printf("  producer waiting %u ms\n", PRODUCER_TIMER);
        usleep(PRODUCER_TIMER*1000);
    }

    // give consumer time to finish reading buffer, then broadcast eom
    usleep(300000);
    gport_signal_eom(p);

    printf("  producer exiting thread\n");
    pthread_exit(0); // exit thread
}