SHM

来源:互联网 发布:人工智能大学专业 编辑:程序博客网 时间:2024/06/05 03:30
/* File: shm.c shm.h
*                    Author:DingChongChong
*                    Description:Provide the shared memory operations
*                    Release: V1.0 2016/04/12
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/sem.h>
#include<sys/shm.h>

#include "shm.h"


/**********GB************/
static char * shmBaseAddr=NULL;
#define SHM_SIZE (4*1024*1024)+sizeof(partition_t)

/*********sem**********/
key_t sem_key=20160401;
int sem_id;
 union semun {
               int              val;   
               struct semid_ds *buf;    
               unsigned short  *array; 
               struct seminfo  *__buf; 
};


int semaphore_init()
{
sem_id=semget(sem_key,1,0666|IPC_CREAT);
if(-1 == sem_id)
return -1;
union semun sem_un;
sem_un.val=1;
return semctl(sem_id,0,SETVAL,sem_un);
}
int semaphore_del()
{
union semun sem_un;
return semctl(sem_id,0,IPC_RMID,sem_un);
}
int semaphore_p()
{
struct sembuf sem_buf;
sem_buf.sem_num=0;
sem_buf.sem_op=-1;
sem_buf.sem_flg=SEM_UNDO;
return semop(sem_id,&sem_buf,1);
}
int semaphore_v()
{
struct sembuf sem_buf;
sem_buf.sem_num=0;
sem_buf.sem_op=1;
sem_buf.sem_flg=SEM_UNDO;
return semop(sem_id,&sem_buf,1);
}




/*********shm*************/

key_t shm_key=20160402;
int shm_id;

/*
* Func: shm_init()
* Param:
* memsetFlag : 1 reset the partition table,else not reset.
*/
int shm_init(unsigned int memsetFlag)
{
if(-1==semaphore_init())
return -1;
 
if(-1 == (shm_id=shmget(shm_key,SHM_SIZE,0666|IPC_CREAT)))
return -1;

if(NULL ==(shmBaseAddr=shmat(shm_id,NULL,0)))
return -1;

if(1==memsetFlag)
{
memset(shmBaseAddr,0,SHM_SIZE);
partition_t partition;
partition.sectNum=0;
partition.remainSpace=SHM_SIZE-sizeof(partition_t);
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition_t));
semaphore_v();
}
return 1;
}




/*
*
* Func: register_section()
* Params:
* sectKey : The unique key id witch stand for the section you need to register.for sections key list ,you may use AN enum struct ,the first item must start with '1';.
* dataSize: In this section ,dataSize is a record size,you can use 'size(struct)'
* dataNum:In this section ,dataNum you need to store.
* return : 1 success;-1 failed.
*
* example:
* typedef enum _SECTION_LIST
* {
* SECTION_SECT1=1,
* SECTION_SECT2,
* SECTION...
* }SectionList;
*
* typedef struct _DATA_YOU_NEED
* {
* int ...
* }MyData;
* int main()
* {
* if(1!=shm_init(1))
* printf("shm init failed!\n");
* else
* {
* register_section(SECTION_SECT1,sizeof(MyData),100);
* }
* }
*
*/
int register_section(int sectKey,int dataSize,int dataNum)
{
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
if( (partition.sectNum == SECTION_NUM)  || (partition.remainSpace  <  (dataSize * dataNum)) )
return -1;
else
{ int i;
for(i=0;i<partition.sectNum;i++)
if(partition.sectTable[i].sectKey == sectKey)
return -1;
partition.sectTable[partition.sectNum].sectKey=sectKey;
partition.sectTable[partition.sectNum].maxNum=dataNum;
partition.sectTable[partition.sectNum].usedNum=0;
partition.sectTable[partition.sectNum].dataSize=dataSize;
partition.sectTable[partition.sectNum].sectOffset=SHM_SIZE-partition.remainSpace;
partition.sectNum++;
partition.remainSpace-=(dataSize * dataNum );
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition_t));
semaphore_v();

}
return 1;
}


/*   Func :  shm_read()
* Params:
* sectKey:the key of sections
* dest:the address of where you need to keep
*     Description:this function read data by "index" ;index>=1
*/
int shm_read(int sectKey,void *dest,int index)
{
if(index<=0)
return -1;
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition_t));
semaphore_v();


int i;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum && (index<=partition.sectTable[i].usedNum))
{
semaphore_p();
memcpy((unsigned char *)dest, (unsigned char *)(shmBaseAddr+partition.sectTable[i].sectOffset+partition.sectTable[i].dataSize * (index-1)), partition.sectTable[i].dataSize); 
semaphore_v();
}
else
return -1;
return 1;

}


/*   Func : shm_write()
*     Description:this function write data at last position.
*/
int shm_write(int sectKey,void *src)
{
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
int i;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum)
{
if(partition.sectTable[i].usedNum==partition.sectTable[i].maxNum)
return -1;
else
{
semaphore_p();
memcpy((unsigned char *)(shmBaseAddr+partition.sectTable[i].sectOffset+partition.sectTable[i].dataSize * partition.sectTable[i].usedNum),(unsigned char *)src,partition.sectTable[i].dataSize);
semaphore_v();
partition.sectTable[i].usedNum++;
}
}
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition));
semaphore_v();
return 1;
}


/*   Func : shm_writeEx()
*     Description:this function write data at last position.
*/
int shm_writeEx(int sectKey,void *src,int index)
{
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
int i;
if(index<=0 || index>partition.sectTable[i].usedNum)
return -1;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum)
{
if(partition.sectTable[i].usedNum==partition.sectTable[i].maxNum)
return -1;
else
{
semaphore_p();
memcpy((unsigned char *)(shmBaseAddr+partition.sectTable[i].sectOffset+partition.sectTable[i].dataSize * (index-1)), (unsigned char *)src, partition.sectTable[i].dataSize);
semaphore_v();
partition.sectTable[i].usedNum++;
}
}
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition));
semaphore_v();
return 1;
}


int shm_reset(int sectKey)
{
semaphore_p();
partition_t partition;
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
int i;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum)
{
partition.sectTable[i].usedNum=0;
semaphore_p();
memcpy((unsigned char *)shmBaseAddr,(unsigned char *)&partition,sizeof(partition));
semaphore_v();
return 1;
}
return -1;
}


int shm_get_section_datanum(int sectKey)
{
partition_t partition;
semaphore_p();
memcpy((unsigned char *)&partition,(unsigned char *)shmBaseAddr,sizeof(partition));
semaphore_v();
int i;
for(i=0; i < partition.sectNum; i++)
if( partition.sectTable[i].sectKey == sectKey )
break;
if(i != partition.sectNum)
{
return partition.sectTable[i].usedNum;
}
return -1;
}
0 0