1 /* S H A R E D M E M O R Y D R I V E R 2 ======================================= 3 4 by Jerzy.Borkowski@obs.unige.ch 5 6 09-Mar-98 : initial version 1.0 released 7 23-Mar-98 : shared_malloc now accepts new handle as an argument 8 */ 9 10 11 #include <sys/ipc.h> /* this is necessary for Solaris/Linux */ 12 #include <sys/shm.h> 13 #include <sys/sem.h> 14 15 #ifdef _AIX 16 #include <fcntl.h> 17 #else 18 #include <sys/fcntl.h> 19 #endif 20 21 /* configuration parameters */ 22 23 #define SHARED_MAXSEG (16) /* maximum number of shared memory blocks */ 24 25 #define SHARED_KEYBASE (14011963) /* base for shared memory keys, may be overriden by getenv */ 26 #define SHARED_FDNAME ("/tmp/.shmem-lockfile") /* template for lock file name */ 27 28 #define SHARED_ENV_KEYBASE ("SHMEM_LIB_KEYBASE") /* name of environment variable */ 29 #define SHARED_ENV_MAXSEG ("SHMEM_LIB_MAXSEG") /* name of environment variable */ 30 31 /* useful constants */ 32 33 #define SHARED_RDONLY (0) /* flag for shared_(un)lock, lock for read */ 34 #define SHARED_RDWRITE (1) /* flag for shared_(un)lock, lock for write */ 35 #define SHARED_WAIT (0) /* flag for shared_lock, block if cannot lock immediate */ 36 #define SHARED_NOWAIT (2) /* flag for shared_lock, fail if cannot lock immediate */ 37 #define SHARED_NOLOCK (0x100) /* flag for shared_validate function */ 38 39 #define SHARED_RESIZE (4) /* flag for shared_malloc, object is resizeable */ 40 #define SHARED_PERSIST (8) /* flag for shared_malloc, object is not deleted after last proc detaches */ 41 42 #define SHARED_INVALID (-1) /* invalid handle for semaphore/shared memory */ 43 44 #define SHARED_EMPTY (0) /* entries for shared_used table */ 45 #define SHARED_USED (1) 46 47 #define SHARED_GRANUL (16384) /* granularity of shared_malloc allocation = phys page size, system dependent */ 48 49 50 51 /* checkpoints in shared memory segments - might be omitted */ 52 53 #define SHARED_ID_0 ('J') /* first byte of identifier in BLKHEAD */ 54 #define SHARED_ID_1 ('B') /* second byte of identifier in BLKHEAD */ 55 56 #define BLOCK_REG (0) /* value for tflag member of BLKHEAD */ 57 #define BLOCK_SHARED (1) /* value for tflag member of BLKHEAD */ 58 59 /* generic error codes */ 60 61 #define SHARED_OK (0) 62 63 #define SHARED_ERR_MIN_IDX SHARED_BADARG 64 #define SHARED_ERR_MAX_IDX SHARED_NORESIZE 65 66 67 #define DAL_SHM_FREE (0) 68 #define DAL_SHM_USED (1) 69 70 #define DAL_SHM_ID0 ('D') 71 #define DAL_SHM_ID1 ('S') 72 #define DAL_SHM_ID2 ('M') 73 74 #define DAL_SHM_SEGHEAD_ID (0x19630114) 75 76 77 78 /* data types */ 79 80 /* BLKHEAD object is placed at the beginning of every memory segment (both 81 shared and regular) to allow automatic recognition of segments type */ 82 83 typedef union 84 { struct BLKHEADstruct 85 { char ID[2]; /* ID = 'JB', just as a checkpoint */ 86 char tflag; /* is it shared memory or regular one ? */ 87 int handle; /* this is not necessary, used only for non-resizeable objects via ptr */ 88 } s; 89 double d; /* for proper alignment on every machine */ 90 } BLKHEAD; 91 92 typedef void *SHARED_P; /* generic type of shared memory pointer */ 93 94 typedef struct SHARED_GTABstruct /* data type used in global table */ 95 { int sem; /* access semaphore (1 field): process count */ 96 int semkey; /* key value used to generate semaphore handle */ 97 int key; /* key value used to generate shared memory handle (realloc changes it) */ 98 int handle; /* handle of shared memory segment */ 99 int size; /* size of shared memory segment */ 100 int nprocdebug; /* attached proc counter, helps remove zombie segments */ 101 char attr; /* attributes of shared memory object */ 102 } SHARED_GTAB; 103 104 typedef struct SHARED_LTABstruct /* data type used in local table */ 105 { BLKHEAD *p; /* pointer to segment (may be null) */ 106 int tcnt; /* number of threads in this process attached to segment */ 107 int lkcnt; /* >=0 <- number of read locks, -1 - write lock */ 108 long seekpos; /* current pointer position, read/write/seek operations change it */ 109 } SHARED_LTAB; 110 111 112 /* system dependent definitions */ 113 114 #ifndef HAVE_FLOCK_T 115 typedef struct flock flock_t; 116 #define HAVE_FLOCK_T 117 #endif 118 119 #ifndef HAVE_UNION_SEMUN 120 union semun 121 { int val; 122 struct semid_ds *buf; 123 unsigned short *array; 124 }; 125 #define HAVE_UNION_SEMUN 126 #endif 127 128 129 typedef struct DAL_SHM_SEGHEAD_STRUCT DAL_SHM_SEGHEAD; 130 131 struct DAL_SHM_SEGHEAD_STRUCT 132 { int ID; /* ID for debugging */ 133 int h; /* handle of sh. mem */ 134 int size; /* size of data area */ 135 int nodeidx; /* offset of root object (node struct typically) */ 136 }; 137 138 /* API routines */ 139 140 #ifdef __cplusplus 141 extern "C" { 142 #endif 143 144 void shared_cleanup(void); /* must be called at exit/abort */ 145 int shared_init(int debug_msgs); /* must be called before any other shared memory routine */ 146 int shared_recover(int id); /* try to recover dormant segment(s) after applic crash */ 147 int shared_malloc(long size, int mode, int newhandle); /* allocate n-bytes of shared memory */ 148 int shared_attach(int idx); /* attach to segment given index to table */ 149 int shared_free(int idx); /* release shared memory */ 150 SHARED_P shared_lock(int idx, int mode); /* lock segment for reading */ 151 SHARED_P shared_realloc(int idx, long newsize); /* reallocate n-bytes of shared memory (ON LOCKED SEGMENT ONLY) */ 152 int shared_size(int idx); /* get size of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ 153 int shared_attr(int idx); /* get attributes of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ 154 int shared_set_attr(int idx, int newattr); /* set attributes of attached shared memory segment (ON LOCKED SEGMENT ONLY) */ 155 int shared_unlock(int idx); /* unlock segment (ON LOCKED SEGMENT ONLY) */ 156 int shared_set_debug(int debug_msgs); /* set/reset debug mode */ 157 int shared_set_createmode(int mode); /* set/reset debug mode */ 158 int shared_list(int id); /* list segment(s) */ 159 int shared_uncond_delete(int id); /* uncondintionally delete (NOWAIT operation) segment(s) */ 160 int shared_getaddr(int id, char **address); /* get starting address of FITS file in segment */ 161 162 int smem_init(void); 163 int smem_shutdown(void); 164 int smem_setoptions(int options); 165 int smem_getoptions(int *options); 166 int smem_getversion(int *version); 167 int smem_open(char *filename, int rwmode, int *driverhandle); 168 int smem_create(char *filename, int *driverhandle); 169 int smem_close(int driverhandle); 170 int smem_remove(char *filename); 171 int smem_size(int driverhandle, LONGLONG *size); 172 int smem_flush(int driverhandle); 173 int smem_seek(int driverhandle, LONGLONG offset); 174 int smem_read(int driverhandle, void *buffer, long nbytes); 175 int smem_write(int driverhandle, void *buffer, long nbytes); 176 177 #ifdef __cplusplus 178 } 179 #endif 180