main() { int i,fd; $DESCRIPTOR(gsdnam1,"gsd3"); $DESCRIPTOR(gsdnam2,"gsd4"); struct _va_range range1, range2; struct _secid id1, id2; range1.va_range$ps_start_va=0x10000000; range1.va_range$ps_end_va=0x10008000; range2.va_range$ps_start_va=0x20020000; range2.va_range$ps_end_va=0x20030000; id1.secid$l_version=0; id2.secid$l_version=0; fd=open("/file",O_RDONLY); sys$create_region_32(0x8000,0,0,0,0,0,range1.va_range$ps_start_va); sys$create_region_32(0x10000,0,0,0,0,0,range2.va_range$ps_start_va); sys$crmpsc(&range1,0,0,SEC$M_GBL,&gsdnam1,&id1,0,fd,2,0,0,0); sys$crmpsc(&range2,0,0,SEC$M_GBL,&gsdnam2,&id2,0,fd,2,1,0,0); for(i=0; i<4; i++) { volatile unsigned long * l1=range1.va_range$ps_start_va+0x2000; volatile unsigned long * l2=range2.va_range$ps_start_va+0x1000; (*l1)++; printf("%x %x\n",getpid(),*l1); sleep(2); (*l2)++; printf("%x %x\n",getpid(),*l2); sleep(2); } close(fd); }
/* * This routine maps a file into a private section. Note that this * method of accessing a file is by far the fastest under VMS. * The routine may fail (i.e. return 0) for several reasons, for * example: * - There is no more room for storing the info on sections. * - The process is out of open file quota, channels, ... * - fd does not describe an opened file. * - The file is already opened for write access by this process * or another process * - There is no free "hole" in virtual memory that fits the * size of the file */ static int _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) { char name[256]; struct FAB fab; unsigned short channel; char *inadr[2], *retadr[2]; unsigned long status; long size; if (no_mapped >= MAX_MAPPED) return(0); /* * We cannot use a file descriptor, we * must open the file once more. */ if (getname((int)fd, name, 1) == NULL) return(0); /* prepare the FAB for a user file open */ fab = cc$rms_fab; fab.fab$l_fop |= FAB$V_UFO; fab.fab$b_fac = FAB$M_GET; fab.fab$b_shr = FAB$M_SHRGET; fab.fab$l_fna = name; fab.fab$b_fns = strlen(name); status = sys$open(&fab); /* open file & get channel number */ if ((status&1) == 0) return(0); channel = (unsigned short)fab.fab$l_stv; inadr[0] = inadr[1] = (char *)0; /* just an address in P0 space */ /* * Map the blocks of the file up to * the EOF block into virtual memory. */ size = _tiffSizeProc(fd); status = sys$crmpsc(inadr, retadr, 0, SEC$M_EXPREG, 0,0,0, channel, TIFFhowmany(size,512), 0,0,0); ddd if ((status&1) == 0) { sys$dassgn(channel); return(0); } *pbase = (tdata_t) retadr[0]; /* starting virtual address */ /* * Use the size of the file up to the * EOF mark for UNIX compatibility. */ *psize = (toff_t) size; /* Record the section in the table */ map_table[no_mapped].base = retadr[0]; map_table[no_mapped].top = retadr[1]; map_table[no_mapped].channel = channel; no_mapped++; return(1); }
rlSharedMemory::rlSharedMemory(const char *shmname, unsigned long Size, int rwmode) { #ifdef RLUNIX struct shmid_ds buf; status = OK; name = new char[strlen(shmname)+1]; strcpy(name,shmname); _size = Size + sizeof(*mutex); // create file fdlock = open(name, O_RDWR | O_CREAT, rwmode ); if(fdlock < 0) { int ret; char buf[1024]; sprintf(buf,"could not write shm=%s\n",shmname); ret = ::write(1,buf,strlen(buf)); if(ret < 0) exit(-1); sprintf(buf,"you have to run this program as root !!!\n"); ret = ::write(1,buf,strlen(buf)); if(ret < 0) exit(-1); status=ERROR_FILE; exit(-1); } // old stuff, without suggestions from Stefan Lievens //shmkey = ftok(name,0); // //id = shmget(shmkey, _size, IPC_CREAT); //shmkey = ftok(name, 'R'); shmkey = ftok(name, 'b'); //id = shmget(shmkey, _size, 0600 | IPC_CREAT); id = shmget(shmkey, _size, rwmode | IPC_CREAT); if(id < 0) { status=ERROR_SHMGET; return; } base_adr = (char *) shmat(id,NULL,0); if(base_adr == NULL) { status=ERROR_SHMAT; return; } if(shmctl(id, IPC_STAT, &buf) != 0) { status=ERROR_SHMCTL; return; }; mutex = (pthread_mutex_t *) base_adr; user_adr = base_adr + sizeof(*mutex); flock(fdlock,LOCK_UN); #endif #ifdef __VMS int file_existed = 0; long ret,fd,page_size,pagelets,pagelet_size,file_block_size,flags,item,ident[2]; FILE *fp; ADD add_in,add_ret; struct dsc$descriptor_s section_name; struct FAB fab; status = OK; name = new char[strlen(shmname)+1]; strcpy(name,shmname); _size = Size + sizeof(*mutex); // The file block size is fixed file_block_size = 512; // Bytes // Get the page size item = SYI$_PAGE_SIZE; ret = lib$getsyi( &item , &page_size , 0 , 0 , 0 , 0 ); if(ret != SS$_NORMAL) { status=ERROR_FILE; return; } // Fill descriptor for section name section_name.dsc$w_length = strlen(name); section_name.dsc$a_pointer = name; section_name.dsc$b_dtype = DSC$K_DTYPE_T; section_name.dsc$b_class = DSC$K_CLASS_S; // The pagelet size is fixed pagelet_size = 512; // Bytes // Get memory if(_size % page_size == 0) pagelets = _size / pagelet_size; else pagelets = (_size / page_size + 1) * (page_size / pagelet_size); ret = sys$expreg(pagelets,&add_ret,0,0); if(ret != SS$_NORMAL) { status=ERROR_FILE; return; } // Set the addresses base_adr = (char *) add_ret.start; user_adr = base_adr + sizeof(*mutex); mutex = (pthread_mutex_t *) base_adr; if(base_adr == NULL) { status=ERROR_SHMAT; return; } // Fill the fab fab = cc$rms_fab; // Initialize fab fab.fab$b_fac = fab.fab$b_fac | FAB$M_PUT | FAB$M_DEL | FAB$M_GET | FAB$M_UPD; fab.fab$l_fna = name; fab.fab$b_fns = strlen(name); fab.fab$l_fop = fab.fab$l_fop | FAB$M_CIF // create file if not existent | FAB$M_CTG // contiguous | FAB$M_UFO; // user open fab.fab$b_shr = fab.fab$b_shr // shareble access | FAB$M_SHRPUT | FAB$M_UPI; fab.fab$l_alq = pagelets * pagelet_size / file_block_size; // Open the section file ret = sys$create (&fab); if(ret != RMS$_NORMAL && ret != RMS$_CREATED) { sys$close (&fab); status=ERROR_FILE; return; } // Set the channel fd = fab.fab$l_stv; // Fill the input address add_in.start = add_ret.start; add_in.end = add_ret.end; // Clear ident ident[0] = 0; ident[1] = 0; // Set flags flags = 0; flags = SEC$M_GBL | SEC$M_WRT | SEC$M_PERM; // Create and map the section ret = sys$crmpsc(&add_in ,&add_ret, (long)0 , // acmode flags , // flags §ion_name , // gsdnam &ident , // ident (long)0 , // relpag (short)fd , // chan pagelets , // pagcnt (long)0 , // vbn (long)0 , // prot (long)0 // pfc ); if(ret != SS$_NORMAL && ret != SS$_CREATED) { sys$close(&fab); status=ERROR_FILE; return; } // Test the section addresses if(add_in.start != add_ret.start || add_in.end != add_ret.end) { sys$close(&fab); status=ERROR_FILE; return; } // Close the section file ret = sys$close(&fab); // rlwthread_mutex_init(mutex,NULL); if(file_existed == 0) myinit(mutex); #endif #ifdef RLWIN32 HANDLE hShmem; //int file_existed; status = OK; name = new char[strlen(shmname)+1]; strcpy(name,shmname); _size = Size + sizeof(HANDLE); // sizeof(*mutex); //file_existed = 1; hSharedFile = CreateFile(name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if(hSharedFile == INVALID_HANDLE_VALUE) { //file_existed = 0; hSharedFile = CreateFile(name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL ); } if(hSharedFile == INVALID_HANDLE_VALUE) { status=ERROR_FILE; return; } //char *global_name = new char[strlen(name)+40]; //strcpy(global_name,"Global\\"); strcat(global_name, name); //for(int i=7; i<strlen(global_name); i++) //{ // if (global_name[i] == ':') global_name[i] = '_'; // else if(global_name[i] == '\\') global_name[i] = '_'; // else if(global_name[i] == '.') global_name[i] = '_'; // else if(global_name[i] == ' ') global_name[i] = '_'; //} hShmem = CreateFileMapping( hSharedFile, NULL, // no security attributes PAGE_READWRITE, // read/write access 0, // size: high 32-bits _size, // size: low 32-bits 0); // name of map object // changed by FMakkinga 25-03-2013 global_name); // global_name); // name of map object //delete [] global_name; if(hShmem == NULL) { status=ERROR_FILE; return; } base_adr = (char *) MapViewOfFile( hShmem, // object to map view of FILE_MAP_WRITE, // read/write access 0, // high offset: map from 0, // low offset: beginning 0); // default: map entire file if(base_adr == NULL) { status=ERROR_FILE; return; } id = (int) hShmem; shmkey = (int) hSharedFile; mutex = (pthread_mutex_t *) base_adr; user_adr = base_adr + sizeof(*mutex); memset(&overlapped, 0, sizeof(overlapped)); // Changed by FMakkinga 22-03-2013 UnlockFileEx(hSharedFile,0,_size,0,&overlapped); #endif if(rwmode == 0) return; // no warning of unused parameter }
sect_sHead * sect_Alloc ( pwr_tStatus *sts, pwr_tBoolean *created, sect_sHead *shp, size_t size, char *name, unsigned int flags ) { pwr_tStatus lsts = 1; sect_sHead *lshp = NULL; if (shp == NULL) shp = lshp = (sect_sHead *) calloc(1, sizeof(*lshp)); if (shp == NULL) pwr_Return(NULL, sts, 2/*SECT__VIRMEM*/); do { if (shp->flags.b.mapped) { lsts = 2/*SECT__WASMAPPED*/; break; } shp->base = NULL; segName(shp, name); #if defined(OS_ELN) || defined (OS_VMS) shp->namedsc.dsc$w_length = strlen(name); shp->namedsc.dsc$b_dtype = DSC$K_DTYPE_T; shp->namedsc.dsc$b_class = DSC$K_CLASS_S; shp->namedsc.dsc$a_pointer = shp->name; #endif #if defined(OS_ELN) ker$create_area(&lsts, &shp->area, &shp->base, size, &shp->namedsc, NULL); if (EVEN(lsts)) break; shp->flags.b.mapped = 1; *created = (lsts != KER$_AREA_EXISTS); if (*created) memset(shp->base, 0, size); #elif defined(OS_VMS) { pwr_tUInt32 inadr[2]; pwr_tUInt32 retadr[2]; inadr[0] = 10000; inadr[1] = inadr[0] + size; lsts = sys$crmpsc(inadr, retadr, 0, SEC$M_WRT | SEC$M_EXPREG | SEC$M_GBL | SEC$M_PAGFIL, &shp->namedsc, NULL, 0, 0, (((size + 511) / 512) + 1), 0, 0, 0); if (EVEN(lsts)) { errh_Error("sect_Alloc, new section: %s, size = %d\n%m", name, size, lsts); break; } shp->base = (void *)retadr[0]; shp->sectadr[0] = retadr[0]; shp->sectadr[1] = retadr[1]; shp->size = retadr[1] - retadr[0] + 1; shp->flags.b.mapped = 1; pwr_Assert(size <= shp->size); *created = (lsts == SS$_CREATED); if (*created) errh_Info("sect_Alloc, new section: %s, size = %d", name, size); } #elif defined(OS_LYNX) { int shm_fd; int shMemFlags = O_RDWR; mode_t shMemMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; *created = 0; /* This is the only way I know to find out if the memory is created */ shm_fd = shm_open(shp->name, shMemFlags, shMemMode); if (sect_must_create && shm_fd != -1) { /* Do we need to check errno ? */ // printf("sect_Alloc: %s already exists. It will be unlinked and created\n", shp->name); if (shm_unlink(shp->name) == -1) { lsts = 2; perror("sect_Alloc: shm_unlink"); break; } shMemFlags |= O_CREAT | O_EXCL; shm_fd = shm_open(shp->name, shMemFlags, shMemMode); if(shm_fd == -1) { lsts = 2; perror("sect_Alloc: shm_open, O_CREATE"); break; } *created = 1; } else if(shm_fd == -1) { if (errno == ENOENT) { /* It didn't exist */ shMemFlags |= O_CREAT | O_EXCL; shm_fd = shm_open(shp->name, shMemFlags, shMemMode); if(shm_fd == -1) { lsts = 2; perror("sect_Alloc: shm_open, O_CREATE "); break; } else *created = 1; } else { lsts = 2; perror("sect_Alloc: shm_open "); break; } } /* Set size */ if (ftruncate(shm_fd, size) != 0) { close(shm_fd); if (*created) shm_unlink(shp->name); lsts = 2; perror("sect_Alloc: ftruncate "); break; } shp->base = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); if (shp->base == MAP_FAILED) { close(shm_fd); if (*created) shm_unlink(shp->name); lsts = 2; perror("sect_Alloc: mmap "); break; } close(shm_fd); shp->size = size; shp->flags.b.mapped = 1; lsts = 1; } #elif defined OS_POSIX { int shm_fd; int shMemFlags = O_RDWR; mode_t shMemMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; key_t shm_key; int shm_id; *created = 0; /* Create unique key */ shm_fd = open(shp->name, shMemFlags, shMemMode); if (sect_must_create && shm_fd != -1) { /* Do we need to check errno ? */ errh_Info("sect_Alloc: %s already exists. It will be unlinked and created\n", shp->name); if (unlink(shp->name) == -1) { lsts = 2; errh_Error("sect_Alloc: unlink failed on !%s! errno: %d", shp->name, errno); break; } shMemFlags |= O_CREAT | O_EXCL; shm_fd = open(shp->name, shMemFlags, shMemMode); if(shm_fd == -1) { lsts = 2; errh_Error("sect_Alloc: open O_CREATE failed errno: %d", errno); break; } *created = 1; } else if(shm_fd == -1) { if (errno == ENOENT) { /* It didn't exist */ if ( !(flags & sect_mFlags_Create)) { lsts = 2; errh_Error("sect_Alloc: Couldn't attach shm section size"); break; } shMemFlags |= O_CREAT | O_EXCL; shm_fd = open(shp->name, shMemFlags, shMemMode); if(shm_fd == -1) { lsts = 2; errh_Error("sect_Alloc: open O_CREATE | O_EXCL failed errno: %d", errno); break; } else { *created = 1; } } else { lsts = 2; errh_Error("sect_Alloc: open failed errno: %d", errno); break; } } /* Get shm key */ shm_key = ftok(shp->name, 'P'); close(shm_fd); /* Create shm section */ shm_id = shmget(shm_key, size, IPC_CREAT | 0660); if (shm_id == -1) { lsts = 2; errh_Error("sect_Alloc: Couldn't attach/create shm section size: %d. Check shmmax.", size); break; } shp->base = shmat(shm_id, (void *)NULL, 0); if (shp->base == (void *)-1) { if (*created) unlink(shp->name); lsts = 2; errh_Error("sect_Alloc: shmat failed"); break; } shp->size = size; shp->flags.b.mapped = 1; lsts = 1; } #endif if (*created) errh_Info("Mapped %s, base: %x, size: %d", shp->name, shp->base, shp->size); pwr_Return(shp, sts, lsts); } while (0); /* Something went wrong, clean up! */ if (lshp != NULL) free(lshp); pwr_Return(NULL, sts, lsts); }