From 106dbe47ccd610a6cad2980838498ba8497a249f Mon Sep 17 00:00:00 2001 From: Alexander Wenzel Date: Wed, 28 Sep 2011 10:46:29 +0200 Subject: Fixed wrong size of shm on server side. --- include/dlt/dlt_shm.h | 95 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/shared/dlt_shm.c | 21 ++++++++++-- 2 files changed, 108 insertions(+), 8 deletions(-) diff --git a/include/dlt/dlt_shm.h b/include/dlt/dlt_shm.h index c12a43a..fc37117 100644 --- a/include/dlt/dlt_shm.h +++ b/include/dlt/dlt_shm.h @@ -68,34 +68,119 @@ #ifndef DLT_SHM_H #define DLT_SHM_H +/* shared memory key */ +/* must be the same for server and cleint */ #define DLT_SHM_KEY 11771 + +/* default size of shared memory */ +/* size is extended during creation to fit segment size */ +/* client retreives real size from shm buffer */ #define DLT_SHM_SIZE 100000 + +/* Id of the used semaphore */ +/* used for synchronisation of write and read access of multiple clients and server */ +/* must be the same for server and client */ #define DLT_SHM_SEM 22771 typedef struct { - int shmid; // Id of shared memory - int semid; // Id of semaphore - char* shm; // pointer to beginning of shared memory - int size; // size of data areay in shared memory - char* mem; // pointer to data area in shared memory + int shmid; /* Id of shared memory */ + int semid; /* Id of semaphore */ + char* shm; /* pointer to beginning of shared memory */ + int size; /* size of data area in shared memory */ + char* mem; /* pointer to data area in shared memory */ } DltShm; #define DLT_SHM_SEM_GET(id) dlt_shm_pv(id,-1) #define DLT_SHM_SEM_FREE(id) dlt_shm_pv(id,1) +/** + * Initialise the shared memory on the client side. + * This function must be called before using further shm functions. + * @param buf pointer to shm structure + * @param key the identifier of the shm, must be the same for server and client + * @return negative value if there was an error + */ extern int dlt_shm_init_client(DltShm *buf,int key); + +/** + * Initialise the shared memory on the server side. + * This function must be called before using further shm functions. + * @param buf pointer to shm structure + * @param key the identifier of the shm, must be the same for server and client + * @param size the requested size of the shm + * @return negative value if there was an error + */ extern int dlt_shm_init_server(DltShm *buf,int key,int size); +/** + * Push data from client onto the shm. + * @param buf pointer to shm structure + * @param data1 pointer to first data block to be written, null if not used + * @param size1 size in bytes of first data block to be written, 0 if not used + * @param data2 pointer to second data block to be written, null if not used + * @param size2 size in bytes of second data block to be written, 0 if not used + * @param data3 pointer to third data block to be written, null if not used + * @param size3 size in bytes of third data block to be written, 0 if not used + * @return negative value if there was an error + */ extern int dlt_shm_push(DltShm *buf,const unsigned char *data1,unsigned int size1,const unsigned char *data2,unsigned int size2,const unsigned char *data3,unsigned int size3); + +/** + * Pull data from shm. + * This function should be called from client. + * Data is deleted from shm after this call. + * @param buf pointer to shm structure + * @param data pointer to buffer where data is to be written + * @param size maximum size to be written into buffer + * @return negative value if there was an error + */ extern int dlt_shm_pull(DltShm *buf,unsigned char *data, int size); + +/** + * Copy message from shm. + * This function should be called from server. + * Data is not deleted from shm after this call. + * @param buf pointer to shm structure + * @param data pointer to buffer where data is to be written + * @param size maximum size to be written into buffer + * @return negative value if there was an error + */ extern int dlt_shm_copy(DltShm *buf,unsigned char *data, int size); + +/** + * Delete message from shm. + * This function should be called from server. + * This function should be called after each succesful copy. + * @param buf pointer to shm structure + * @return negative value if there was an error + */ extern int dlt_shm_remove(DltShm *buf); +/** + * Print information about shm. + * @param buf pointer to shm structure + */ extern void dlt_shm_info(DltShm *buf); + +/** + * Print status about shm. + * @param buf pointer to shm structure + */ extern void dlt_shm_status(DltShm *buf); +/** + * Deinitialise the shared memory on the client side. + * @param buf pointer to shm structure + * @return negative value if there was an error + */ extern int dlt_shm_free_client(DltShm *buf); + +/** + * Deinitialise the shared memory on the server side. + * @param buf pointer to shm structure + * @return negative value if there was an error + */ extern int dlt_shm_free_server(DltShm *buf); #endif /* DLT_SHM_H */ diff --git a/src/shared/dlt_shm.c b/src/shared/dlt_shm.c index 853dc2d..e3ec7c6 100644 --- a/src/shared/dlt_shm.c +++ b/src/shared/dlt_shm.c @@ -102,6 +102,7 @@ void dlt_shm_pv(int id,int operation) } int dlt_shm_init_server(DltShm *buf,int key,int size) { + struct shmid_ds shm_buf; // Init parameters buf->shm = NULL; @@ -116,6 +117,13 @@ int dlt_shm_init_server(DltShm *buf,int key,int size) { return -1; /* ERROR */ } + // get the size of shm + if (shmctl(buf->shmid, IPC_STAT, &shm_buf)) + { + perror("shmctl"); + return -1; /* ERROR */ + } + // Now we attach the segment to our data space. if ((buf->shm = shmat(buf->shmid, NULL, 0)) == (char *) -1) { perror("shmat"); @@ -139,11 +147,15 @@ int dlt_shm_init_server(DltShm *buf,int key,int size) { ((int*)(buf->shm))[1] = 0; // pointer to read memory ((int*)(buf->shm))[2] = 0; // number of packets buf->mem = (char*)(&(((int*)(buf->shm))[3])); - buf->size = size - (buf->mem - buf->shm); + buf->size = shm_buf.shm_segsz - (buf->mem - buf->shm); // clear memory memset(buf->mem,0,buf->size); + //dlt_shm_status(buf); + //dlt_shm_info(buf); + printf("SHM: Size %d\n",buf->size); + return 0; /* OK */ } @@ -187,6 +199,9 @@ int dlt_shm_init_client(DltShm *buf,int key) { buf->mem = (char*)(&(((int*)(buf->shm))[3])); buf->size = shm_buf.shm_segsz - (buf->mem - buf->shm); + //dlt_shm_status(buf); + //dlt_shm_info(buf); + return 0; /* OK */ } @@ -256,7 +271,7 @@ int dlt_shm_push(DltShm *buf,const unsigned char *data1,unsigned int size1,const } else // read <= write { - if((write + size1+size2+size3 + sizeof(unsigned char)+sizeof(int)) > buf->size) { + if((write+size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > buf->size) { // data does not fit at end of buffer // try write at beginning if((size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > read) { @@ -264,7 +279,7 @@ int dlt_shm_push(DltShm *buf,const unsigned char *data1,unsigned int size1,const //printf("SHM is full at start\n"); return -1; // ERROR } - // write zero and start buffer at beginning + // write zero status and size at end if possible if((write+sizeof(unsigned char)+sizeof(int)) <= buf->size) { *((unsigned char*)(buf->mem+write)) = 0; // init write status to unused *((int*)(buf->mem+write+sizeof(unsigned char))) = 0; // init write size to unused -- cgit v1.2.1