/***************************************************************************/ /* Circthread.c, circular buffer example and test progam between threads. * * Usage: Circthread <buffer-size> <event-size> <repeat-count> [<cpu1> <cpu2>] */ /***************************************************************************/ static char Usage[] = "\ Usage: Circthread <buffer-size> <event-size> <repeat-count> [<cpu1> <cpu2>]\ "; #define USAGE printf("%s\n",Usage), exit(1) #include <stdio.h> #include<sys/types.h> #include<sys/time.h> #include <pthread.h> #define DO_CHECKno /* do data consistency checks */ #include "Circ.h" #define MAX_EVTSIZE 65536*2 #define MAGIC 0x31071965 #define GO_ON 0 #define STOP_IT 1 pthread_attr_t thread_attribute; pthread_t thread_write, thread_read; #ifdef LynxOS #define pthread_addr_t void** #define pthread_startroutine_t void** #endif static unsigned long full, empty; static int repeat, bufsize, evtsize; static int cpu1 = -1, cpu2 = -1; void t_circ_read (int); void t_circ_write (int); /***************************************************************************/ int main (int argc, char *argv[]) /*------------------------------- */ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { int cid; long cpu_mask; pthread_addr_t status; /*......................................................................... */ if (argc != 4 && argc != 6) USAGE; bufsize = atoi (argv[1]); evtsize = atoi (argv[2]); repeat = atoi (argv[3]); if (argc == 6) { cpu1 = atoi (argv[4]); cpu2 = atoi (argv[5]); } if ((cid = CircOpen (NULL, "NONE", bufsize)) < 0) { fprintf (stderr, "%s> Circular buffer open failed !\n", argv[0]); exit (1); } printf ("%s> Circular buffer opened for read/write : id=%d\n", argv[0], cid); /* setup and start threads to do tcp-send */ if (pthread_attr_create (&thread_attribute) < 0) { perror ("pthread_attr_create"); exit (1); } if (pthread_create (&thread_read, thread_attribute, (pthread_startroutine_t) t_circ_read, (void *) cid) < 0) { perror ("pthread_create t_circ_read()"); exit (1); } #ifdef __osf__ if (cpu1 >= 0) /* does not work ! */ { cpu_mask = 1<<cpu1; printf("mask1=0x%x\n",cpu_mask); if (pthread_bind_to_cpu_np(thread_read, cpu_mask) < 0) perror ("cpu1: pthread_bind_to_cpu_np"); } #endif if (pthread_create (&thread_write, thread_attribute, (pthread_startroutine_t) t_circ_write, (void *) cid) < 0) { perror ("pthread_create t_circ_write()"); exit (1); } #ifdef __osf__ if (cpu2 >= 0) { cpu_mask = 1<<cpu2; printf("mask2=0x%x\n",cpu_mask); if (pthread_bind_to_cpu_np(thread_write, cpu_mask) < 0) perror ("cpu2: pthread_bind_to_cpu_np"); } #endif if (pthread_join (thread_write, &status) < 0) perror ("pthread_join"); if (pthread_join (thread_read, &status) < 0) perror ("pthread_join"); (void) CircClose (cid); } /***************************************************************************/ void t_circ_read (int cid) /*------------------------ */ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { int repeat, evtsize, number, last; int *data; int *ptr; /*......................................................................... */ data = (int *) malloc (MAX_EVTSIZE); /* Test 1: CircLocate, CircRelease without memcpy */ printf ("%s> Test #1 using CircLocate/CircRelease without moving data\n", "t_circ_read"); empty = 0; repeat = 0; data[0] = GO_ON; while (data[0] == GO_ON) { while ( (ptr = (int*)CircLocate (cid, &number, &evtsize)) == (int*)-1) { empty++; pthread_yield (); } last = (evtsize/sizeof (int) - 1); if (repeat++ == 0) timing_start (); #ifdef DO_CHECK if (ptr[last] != MAGIC) { printf ("%s> Invalid MAGIC number %x found for event #%d !\n", ptr[last], repeat); exit (1); } if (repeat != number) { printf ("%s> Invalid event number %d found instead of %d !\n", number, repeat); exit (1); } #endif data[0] = ptr[0]; (void) CircRelease (cid); } /* Test 2: CircGet with memcpy */ printf ("%s> Test #2 using CircGet and moving data (memcpy)\n", "t_circ_read"); empty = 0; repeat = 0; data[0] = GO_ON; while (data[0] == GO_ON) { while ((evtsize = CircGet (cid, &number, (char *) data, MAX_EVTSIZE)) < 0) { empty++; pthread_yield (); } #ifdef DO_CHECK last = (evtsize/sizeof (int) - 1); if (data[last] != MAGIC) { printf ("%s> Invalid MAGIC number %x found for event number %d !\n", "thread_read", data[last], repeat); exit (1); } if (++repeat != number) { printf ("%s> Invalid event number %d found instead of %d !\n", "thread_read", number, repeat); exit (1); } #endif } } /***************************************************************************/ void t_circ_write (int cid) /*------------------------- */ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ { int *data, i, last; int *ptr; double real_time, cpu_time, cpu_usage; /*......................................................................... */ data = (int *) malloc (evtsize); last = (evtsize/sizeof(int) - 1); data[0] = 0; data[last] = MAGIC; /* Test #1: CircReserve, CircValidate without memcpy ****************************************** */ printf ("%s> Test #1 using CircReserve/CircValidate without moving data\n", "t_circ_write"); full = 0; timing_start (); for (i = 1; i <= repeat; i++) { while ( (ptr = (int *)CircReserve (cid, i, evtsize)) == (int*)-1) { full++; pthread_yield (); } if (i < repeat) ptr[0] = 0; else ptr[0] = 1; /* mark end of test */ #ifdef DO_CHECK ptr[last] = MAGIC; #endif (void) CircValidate (cid, i, (char *) ptr, evtsize); } timing_stop (&real_time, &cpu_time, &cpu_usage); if (real_time > 0.0) { printf ("%s> Real-time: %.2fs, CPU-time: %.2fs, CPU-usage: %.1f%%\n", "t_circ_write", real_time, cpu_time, cpu_usage); printf ("%s> Events: %d, %.0f per sec\n", "t_circ_write", repeat, (double) repeat / real_time); printf ("%s> Bytes : %.0f, %.1f MB /sec\n", "t_circ_write", (double) repeat * evtsize, (double) repeat * evtsize / 1024. / 1024. / real_time); printf ("%s> Buffer full: %d empty: %d\n", "t_circ_write", full, empty); } else printf ("%s> not timing possible\n", "t_circ_write"); /* Test 1: CircPut with memcpy ***************************** */ printf ("%s> Test #1 using CircPut and moving data (memcpy)\n", "t_circ_write"); full = 0; timing_start (); for (i = 1; i <= repeat; i++) { if (i == repeat) data[0] = 1; /* mark end of test */ while (CircPut (cid, i, (char *) data, evtsize) < 0) { full++; pthread_yield (); } } timing_stop (&real_time, &cpu_time, &cpu_usage); if (real_time > 0.0) { printf ("%s> Real-time: %.2fs, CPU-time: %.2fs, CPU-usage: %.1f%%\n", "t_circ_write", real_time, cpu_time, cpu_usage); printf ("%s> Events: %d, %.0f per sec\n", "t_circ_write", repeat, (double) repeat / real_time); printf ("%s> Bytes : %.0f, %.1f MB /sec\n", "t_circ_write", (double) repeat * evtsize, (double) repeat * evtsize / 1024. / 1024. / real_time); printf ("%s> Buffer full: %d empty: %d\n", "t_circ_write", full, empty); } else printf ("%s> not timing possible\n", "t_circ_write"); }