shm implemented as memfd syscall
cheliequan
2022-12-04 14278bd98326f0afdd86fe4ec24e747b0e0b712a
增减共享内存链表管理
8个文件已添加
4个文件已修改
584 ■■■■■ 已修改文件
include/list_in_shm.h 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/memfd.h 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sample/CMakeLists.txt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sample/test_list_in_shm.c 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/CMakeLists.txt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Makefile 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/core 补丁 | 查看 | 原始文档 | blame | 历史
src/list_in_shm.c 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/list_in_shm.h 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/memfd.c 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/memfd.h 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test_list_in_shm.c 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
include/list_in_shm.h
New file
@@ -0,0 +1,65 @@
#ifndef __LIST_IN_SHM_H__
#define __LIST_IN_SHM_M__
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include "stdint.h"
#include "errno.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include "stdio.h"
#include <string.h>
typedef struct sm_list_s
{
  uint32_t n_off;
  uint32_t p_off;
  uint32_t c ;
//  uint32_t mc;
} sm_list_t;
typedef struct node_sm_s
{
    uint32_t p_off ;
    uint32_t n_off ;
    uint32_t data;
}node_sm_t ;
typedef struct list_in_shm_handle_s {
   int fd;
   uint64_t size;
   sem_t * sem;
   uint8_t * ptr ;
   sm_list_t *pFreeListStruct;
   sm_list_t *pList;
   uint8_t *pStart;
}list_in_shm_handle_t;
#define GET_OFFSET(baseptr,ptr) ((uint8_t *)ptr-(uint8_t *)baseptr)
#define GET_PTR(baseptr,offset) ((uint8_t *)baseptr+offset)
#define FROM_FREE_LIST 0x01
#define FROM_LIST      0x02
#define FROM_FRONT     0x10
#define FROM_BACK      0x20
int list_in_shm_init(list_in_shm_handle_t * h, char * name, uint32_t size,uint32_t num,char *nameSem,uint8_t init );
int list_in_shm_insert_node(sm_list_t * plst, uint8_t * basePtr , node_sm_t * node ,uint8_t front);
node_sm_t *list_in_shm_get_node(sm_list_t * plst,uint8_t * basePtr,uint8_t front);
node_sm_t * get_node_from_shm(list_in_shm_handle_t * h,uint8_t flags );
int put_node_in_list(list_in_shm_handle_t * h,node_sm_t *node,uint8_t flags);
void list_in_shm_finish(list_in_shm_handle_t * h);
#ifdef __cplusplus
}
#endif
#endif
include/memfd.h
@@ -14,6 +14,12 @@
int basic_shm_close(int fd);
int basic_shm_shrink(int fd, ssize_t len);
int basic_shm_grow(int fd, ssize_t len);
enum{
   local_open_flag = 0,
   remote_open_flag
};
#ifdef __cplusplus 
#endif
sample/CMakeLists.txt
@@ -6,6 +6,7 @@
# add binary
add_executable(sample_create sample_create.c)
add_executable(sample_open sample_open.c)
add_executable(test_list_in_shm test_list_in_shm.c)
target_link_libraries(sample_create
                  PRIVATE 
@@ -16,3 +17,9 @@
                  memfd
             )
target_link_libraries(test_list_in_shm
                  PRIVATE
                  memfd
              pthread
             )
sample/test_list_in_shm.c
New file
@@ -0,0 +1,88 @@
#include "list_in_shm.h"
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define SHM_NAME  "pollcontrol"
#define SEM_FILE  "/sem_pollcontrol"
#define ID 0xdeadbeef
#define MAX_NODES 1000
typedef struct data
{
    uint32_t p_off ;
    uint32_t n_off ;
    uint32_t data;
}data_t;
int main(int argc, char * argv[])
{
    list_in_shm_handle_t h = {0,};
    data_t * temp= NULL ;
    uint8_t *temp2=NULL ;
    int i =0;
    if( 2 != argc )
      exit(-1);
    if (strcmp(argv[1],"test")== 0)
    {
         list_in_shm_init(&h,SHM_NAME,sizeof(data_t),MAX_NODES,SEM_FILE,1);
#if 1
         for(i=0;i<MAX_NODES;i++)
         {
            temp=get_node_from_shm(&h,FROM_FREE_LIST);
            if(NULL != temp)
            {
               temp->data=i;
               put_node_in_list(&h,(node_sm_t *)temp,FROM_LIST);
            }
         }
        for(i=0;i<MAX_NODES;i++)
        {
           temp=get_node_from_shm(&h,FROM_LIST|FROM_FRONT);
           if(NULL != temp)
           {
              printf("\n %d %d",i,temp->data);
           }
        }
#endif
    }
    else if (strcmp(argv[1],"write")== 0)
    {
         list_in_shm_init(&h,SHM_NAME,sizeof(data_t),MAX_NODES,SEM_FILE,1);
#if 1
         for(i=0;i<MAX_NODES;i++)
         {
            temp=get_node_from_shm(&h,FROM_FREE_LIST);
            if(NULL != temp)
            {
               temp->data=i;
               put_node_in_list(&h,(node_sm_t *)temp,FROM_LIST|FROM_LIST);
            }
         }
#endif
    }
    else if (strcmp(argv[1],"read")==0)
    {
        list_in_shm_init(&h,SHM_NAME,sizeof(data_t),MAX_NODES,SEM_FILE,0);
        for(i=0;i<MAX_NODES;i++)
        {
           temp=get_node_from_shm(&h,FROM_LIST);
           if(NULL != temp)
           {
              printf("\n %d %d",i,temp->data);
           }
        }
    }
    else if (strcmp(argv[1],"dump")== 0)
    {
       list_in_shm_init(&h,SHM_NAME,sizeof(data_t),MAX_NODES,SEM_FILE,0);
       temp2=h.ptr;
       for(i=0;i<h.size;i++)
       {
             if(0 != i && i % 16 == 0 )
                printf("\n");
             printf("%02x",temp2[i]);
       }
    }
}
src/CMakeLists.txt
@@ -5,7 +5,7 @@
include_directories(../include)
# add library
add_library(memfd SHARED memfd.c)
add_library(memfd SHARED memfd.c list_in_shm.c)
target_link_libraries(memfd PRIVATE pthread)
src/Makefile
New file
@@ -0,0 +1,6 @@
all:
    gcc -g -c -Wall -Werror -fpic list_in_shm.c  memfd.c -lpthread
    gcc -shared -o liblistInShm.so list_in_shm.o memfd.o
    gcc test_list_in_shm.c liblistInShm.so -lpthread
clean:
    rm -rf *.so *.o a.out
src/core
Binary files differ
src/list_in_shm.c
New file
@@ -0,0 +1,205 @@
#include "memfd.h"
#include "list_in_shm.h"
int list_in_shm_init(list_in_shm_handle_t * h, char * name, uint32_t size,uint32_t num,char *nameSem,uint8_t init)
{
    uint64_t totalSize=0;
    uint32_t i =0;
    uint8_t *temp = NULL ;
    int len = 0;
    if (NULL == h || NULL == nameSem )
       return  -1;
    /* Change umask temporarily to make sure the correct permission */
    mode_t mask = umask(0);
    h->sem=sem_open(nameSem, O_CREAT | O_RDWR, 0666, 1);
    umask(mask);
    if (NULL  == h->sem )
    {
       printf("\nsem_open failed for file %s  %u\n",nameSem,errno);
       return -1 ;
    }
    totalSize = (size * num) + sizeof(sm_list_t) + sizeof(sm_list_t);
    h->fd = basic_shm_create(name, totalSize);
    if ( 0 >= h->fd )
    {
       printf("\nbasic_shm_create failed errono %u\n",errno);
       sem_close(h->sem);
       return -1;
    }
    h->size=totalSize;
    len = basic_shm_mmap(h->fd, &(h->ptr));
    if(0 >= len || (void *) -1 == h->ptr)
    {
       printf("\nbasic_shm_open failed  %u\n",errno);
       sem_close(h->sem);
       return  -1;
    }
    h->pFreeListStruct=(sm_list_t*)(h->ptr);
    h->pList=(sm_list_t*)((uint8_t*)(h->pFreeListStruct)+sizeof(sm_list_t));
    h->pStart=(uint8_t*)((uint8_t*)(h->pList)+sizeof(sm_list_t));
    if(init)
    {
         sem_wait(h->sem);
         memset(h->ptr,0,totalSize);
         temp=h->pStart;
         for(i=0; i<num; i++)
         {
            list_in_shm_insert_node(h->pFreeListStruct,h->ptr,(node_sm_t *)(temp+i*size),FROM_FRONT);
         }
         sem_post(h->sem);
    }
    return 0 ;
}
int list_in_shm_insert_node(sm_list_t * plst, uint8_t * basePtr , node_sm_t * node ,uint8_t front)
{
    node_sm_t* temp = NULL ;
    if(NULL == plst || NULL == basePtr || NULL == node )
      return -1 ;
    if ( 0 == plst->p_off  && 0 == plst->n_off)
    {
         plst->p_off=GET_OFFSET(basePtr,node);
         plst->n_off=GET_OFFSET(basePtr,node);
         plst->c=1;
         return 0;
    }
    if(FROM_FRONT & front)
    {
       temp=(node_sm_t*)(GET_PTR(basePtr,plst->n_off));
       node->n_off=plst->n_off;
       temp->p_off=GET_OFFSET(basePtr,node);
       node->p_off =0;
       plst->n_off=GET_OFFSET(basePtr,node);
       (plst->c)++;
    }
    else
    {
        temp=(node_sm_t*)(GET_PTR(basePtr,plst->p_off));
        temp->n_off=GET_OFFSET(basePtr,node);
        node->p_off=plst->p_off;
        node->n_off=0;
        plst->p_off=GET_OFFSET(basePtr,node);
       (plst->c)++;
    }
    return 0;
}
node_sm_t *list_in_shm_get_node(sm_list_t * plst,uint8_t * basePtr,uint8_t front)
{
   node_sm_t * temp = NULL ;
   node_sm_t * temp2 = NULL ;
   uint32_t offtemp = 0;
   if(NULL == plst || NULL == basePtr || (0 == plst->c))
     return NULL ;
   if(1 == plst->c )
   {
       temp=(node_sm_t *)(GET_PTR(basePtr,plst->n_off));
       plst->c=0;
       plst->n_off=0;
       plst->p_off=0;
       return temp ;
   }
   if(FROM_FRONT & front)
   {
      temp=(node_sm_t *)(GET_PTR(basePtr,plst->n_off));
      offtemp=temp->n_off;
      plst->n_off=offtemp;
      temp2=(node_sm_t *)(GET_PTR(basePtr,plst->n_off));
      temp2->p_off=0;
      (plst->c)--;
   }
   else
   {
      temp=(node_sm_t *)(GET_PTR(basePtr,plst->p_off));
      offtemp=temp->p_off;
      plst->p_off=offtemp;
      temp2=(node_sm_t *)(GET_PTR(basePtr,offtemp));
      temp2->n_off=0;
      (plst->c)--;
   }
   return temp ;
}
node_sm_t * get_node_from_shm(list_in_shm_handle_t * h,uint8_t flags )
{
    sm_list_t *lst=NULL ;
    node_sm_t * temp = NULL ;
    int ret=0;
    if (NULL == h )
    {
        return NULL ;
    }
    ret=sem_wait(h->sem);
    if(0 != ret )
    {
       printf("\n(%s) failed to get sem",__FUNCTION__);
       return  NULL ;
    }
    if(FROM_FREE_LIST & flags )
    {
       lst=h->pFreeListStruct;
    }
    else
    {
      lst=h->pList;
    }
    if (0 == lst || 0 == lst->c)
    {
       sem_post(h->sem);
       return NULL ;
    }
    temp=list_in_shm_get_node(lst,h->ptr,flags);
    sem_post(h->sem);
    return temp ;
}
int put_node_in_list(list_in_shm_handle_t * h,node_sm_t *node,uint8_t flags)
{
    sm_list_t *lst=NULL ;
    int ret=0;
    if (NULL == h || NULL == node)
    {
        return -1 ;
    }
    ret=sem_wait(h->sem);
    if(0 != ret )
    {
       printf("\n(%s) failed to get sem",__FUNCTION__);
       return  -1 ;
    }
    if(FROM_FREE_LIST & flags )
    {
       lst=h->pFreeListStruct;
    }
    else
    {
      lst=h->pList;
    }
    ret=list_in_shm_insert_node(lst, h->ptr, node ,flags);
    sem_post(h->sem);
    return 0;
}
void list_in_shm_finish(list_in_shm_handle_t * h)
{
     basic_shm_unmmap(h->fd, &(h->ptr));
     basic_shm_close(h->fd);
     sem_close(h->sem);
}
src/list_in_shm.h
New file
@@ -0,0 +1,65 @@
#ifndef __LIST_IN_SHM_H__
#define __LIST_IN_SHM_M__
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include "stdint.h"
#include "errno.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include "stdio.h"
#include <string.h>
typedef struct sm_list_s
{
  uint32_t n_off;
  uint32_t p_off;
  uint32_t c ;
//  uint32_t mc;
} sm_list_t;
typedef struct node_sm_s
{
    uint32_t p_off ;
    uint32_t n_off ;
    uint32_t data;
}node_sm_t ;
typedef struct list_in_shm_handle_s {
   int fd;
   uint64_t size;
   sem_t * sem;
   uint8_t * ptr ;
   sm_list_t *pFreeListStruct;
   sm_list_t *pList;
   uint8_t *pStart;
}list_in_shm_handle_t;
#define GET_OFFSET(baseptr,ptr) ((uint8_t *)ptr-(uint8_t *)baseptr)
#define GET_PTR(baseptr,offset) ((uint8_t *)baseptr+offset)
#define FROM_FREE_LIST 0x01
#define FROM_LIST      0x02
#define FROM_FRONT     0x10
#define FROM_BACK      0x20
int list_in_shm_init(list_in_shm_handle_t * h, char * name, uint32_t size,uint32_t num,char *nameSem,uint8_t init );
int list_in_shm_insert_node(sm_list_t * plst, uint8_t * basePtr , node_sm_t * node ,uint8_t front);
node_sm_t *list_in_shm_get_node(sm_list_t * plst,uint8_t * basePtr,uint8_t front);
node_sm_t * get_node_from_shm(list_in_shm_handle_t * h,uint8_t flags );
int put_node_in_list(list_in_shm_handle_t * h,node_sm_t *node,uint8_t flags);
void list_in_shm_finish(list_in_shm_handle_t * h);
#ifdef __cplusplus
}
#endif
#endif
src/memfd.c
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include "memfd.h"
#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
@@ -127,14 +128,19 @@
int basic_shm_open(int fd, pid_t pid, int flags)
{
    if(0 >= flags)
    {
        basic_shm_path_open(fd, getpid());
    int memfd = -1;
    switch(flags){
      case local_open_flag:
        memfd = basic_shm_path_open(fd, getpid());
        break;
      case remote_open_flag:
        memfd = basic_shm_path_open(fd, pid);
        break;
      default:
        mydebug("not support\n");
        break;
    }
    else
    {
        basic_shm_path_open(fd, pid);
    }
    return memfd;
}
int basic_shm_mmap(int fd, unsigned char** ppaddr)
@@ -180,10 +186,12 @@
int basic_shm_close(int fd)
{
  int ret = -1;
  if (fd >= 0) 
  {
    close(fd);
    ret = close(fd);
  }
  return ret;
}
static void mfd_assert_size(int fd, size_t size)
src/memfd.h
New file
@@ -0,0 +1,26 @@
#ifndef MEMFD_H
#define MEMFD_H
#include "unistd.h"
#ifdef __cplusplus
extern "C" {
#endif
int basic_shm_create(char *name, ssize_t len);
int basic_shm_open(int fd, pid_t pid, int flags);
int basic_shm_mmap(int fd, unsigned char** ppaddr);
int basic_shm_unmmap(int fd, unsigned char** ppaddr);
int basic_shm_close(int fd);
int basic_shm_shrink(int fd, ssize_t len);
int basic_shm_grow(int fd, ssize_t len);
enum{
   local_open_flag = 0,
   remote_open_flag
};
#ifdef __cplusplus
}
#endif
#endif
src/test_list_in_shm.c
New file
@@ -0,0 +1,88 @@
#include "list_in_shm.h"
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define SHM_NAME  "pollcontrol"
#define SEM_FILE  "/sem_pollcontrol"
#define ID 0xdeadbeef
#define MAX_NODES 1000
typedef struct data
{
    uint32_t p_off ;
    uint32_t n_off ;
    uint32_t data;
}data_t;
int main(int argc, char * argv[])
{
    list_in_shm_handle_t h = {0,};
    data_t * temp= NULL ;
    uint8_t *temp2=NULL ;
    int i =0;
    if( 2 != argc )
      exit(-1);
    if (strcmp(argv[1],"test")== 0)
    {
         list_in_shm_init(&h,SHM_NAME,sizeof(data_t),MAX_NODES,SEM_FILE,1);
#if 1
         for(i=0;i<MAX_NODES;i++)
         {
            temp=get_node_from_shm(&h,FROM_FREE_LIST);
            if(NULL != temp)
            {
               temp->data=i;
               put_node_in_list(&h,(node_sm_t *)temp,FROM_LIST);
            }
         }
        for(i=0;i<MAX_NODES;i++)
        {
           temp=get_node_from_shm(&h,FROM_LIST|FROM_FRONT);
           if(NULL != temp)
           {
              printf("\n %d %d",i,temp->data);
           }
        }
#endif
    }
    else if (strcmp(argv[1],"write")== 0)
    {
         list_in_shm_init(&h,SHM_NAME,sizeof(data_t),MAX_NODES,SEM_FILE,1);
#if 1
         for(i=0;i<MAX_NODES;i++)
         {
            temp=get_node_from_shm(&h,FROM_FREE_LIST);
            if(NULL != temp)
            {
               temp->data=i;
               put_node_in_list(&h,(node_sm_t *)temp,FROM_LIST|FROM_LIST);
            }
         }
#endif
    }
    else if (strcmp(argv[1],"read")==0)
    {
        list_in_shm_init(&h,SHM_NAME,sizeof(data_t),MAX_NODES,SEM_FILE,0);
        for(i=0;i<MAX_NODES;i++)
        {
           temp=get_node_from_shm(&h,FROM_LIST);
           if(NULL != temp)
           {
              printf("\n %d %d",i,temp->data);
           }
        }
    }
    else if (strcmp(argv[1],"dump")== 0)
    {
       list_in_shm_init(&h,SHM_NAME,sizeof(data_t),MAX_NODES,SEM_FILE,0);
       temp2=h.ptr;
       for(i=0;i<h.size;i++)
       {
             if(0 != i && i % 16 == 0 )
                printf("\n");
             printf("%02x",temp2[i]);
       }
    }
}