#include #include #include #if (defined SOLARIS || defined POSIX) #include #include #include #ifdef __cplusplus extern "C" { #endif int shm_open(const char *, int, mode_t); #ifdef __cplusplus } #endif #else #include #include #endif /* format of the data buffer area header */ #define NBLOCKS 64 /* current number of buffers used - must be 2**n */ #define MAX_BUFFERS 128 /* unchangeable maximum because of header structure */ typedef struct s_buffer_header { int buffer_offset; /* offset to first buffer */ int buffer_number; /* number of buffers */ int buffer_length; /* length of buffers */ int buffer_next; /* next buffer to be written */ int buffer_max; /* MAX_BUFFERS */ int buffer_spare1; int buffer_spare2; int buffer_spare3; long long buffer_currentage; long long buffer_age[MAX_BUFFERS]; } BUFFER_HEADER; #define SHM_KEY 110205 short * shm_bufferarea=NULL; static short DataBuffer[(32*1024)+16]; // maximum length is 64Kbyte + allow for 32 byte header later int debug=0; void initialise () { #if (defined SOLARIS || defined POSIX) int shmid; int shmkey = SHM_KEY; char object_name[16]; #else int shmid; key_t shmkey = SHM_KEY; #endif /* Open the shared memory object */ #if (defined SOLARIS || defined POSIX) sprintf( object_name, "/SHM_%d", shmkey ); shmid = shm_open( object_name, O_RDONLY, ( mode_t ) 0 ); /*--> Just check that we have opened the segment ok <--*/ if ( shmid == -1 ) {perror( "shm_open " ); exit( 1 );} #else shmid = shmget(shmkey, 0, SHM_R); if (shmid == -1) {perror("shmget"); exit(1);} #endif #if (defined SOLARIS || defined POSIX) /*--> Now attach the memory segment <--*/ shm_bufferarea = (short *)mmap( ( caddr_t ) NULL, ( size_t ) 0x401000, PROT_READ, MAP_SHARED, shmid, 0 ); /*--> Now check that we have attached it correctly <--*/ if ( shm_bufferarea == ( void *) MAP_FAILED ) { perror( "mmap" ); exit ( 1 ); } /*--> Close the shared memory segment <--*/ close( shmid ); #else shm_bufferarea = shmat(shmid, (void *) 0, SHM_RDONLY); if (shm_bufferarea == (void *) -1) {perror("shmat"); exit(1);} #endif } short *get_block (int *New, int *runinfo) { int offset, number, length, next, max; int i; unsigned long long cage; static unsigned long long age =0; BUFFER_HEADER * baseaddress; short * bufferaddress =0; if (shm_bufferarea == NULL) { initialise (); if(debug) { printf("midasTS : Shared buffer area located at 0x%p\n", shm_bufferarea); } baseaddress = (BUFFER_HEADER *) shm_bufferarea; age = baseaddress->buffer_currentage; /* start at the next new buffer */ } baseaddress = (BUFFER_HEADER *) shm_bufferarea; cage = baseaddress->buffer_currentage; number = baseaddress->buffer_number; next = baseaddress->buffer_next; max = baseaddress->buffer_max; offset = baseaddress->buffer_offset; length = baseaddress->buffer_length; *runinfo = length; if (debug) { printf ("current control information: "); printf ("offset=%d number=%d length=%d next=%d max=%d age=%lld\n", offset, number, length, next, max, cage); } i = ( next - 1 ) & ( number - 1 ); if ( baseaddress->buffer_age[i] != 0 ) { bufferaddress = (short *) ((char *)shm_bufferarea + offset + (length * i)); if (debug) { printf( "midasTS :index=%d age = %lld : cage = %lld\n", i, age, cage ); } /*--> Check to see the age of the data block .... <--*/ if ( cage > age ) { /*--> found a new buffer <--*/ age = cage; /* copy the buffer */ memcpy (&DataBuffer[12], bufferaddress, baseaddress->buffer_length); bufferaddress = &DataBuffer[12]; *New = 1; /* a new buffer */ if (debug) { printf( "midasTS :New buffer: index=%d age = %lld\n", i, age); } } else { /*--> So this buffer is the same as the last one .... <--*/ *New = 0; /* no buffer available */ } } else { *New = 0; /* no buffer available */ } return bufferaddress; }