<<< DUA0:[NOTES$LIBRARY]VAX_VMS.NOTE;1 >>> -< SIG VAX/VMS >- ================================================================================ Note 506.0 "Mapping" des fichiers 4 replies DECUSF::BLOCH_L "L. Bloch CNAM tel. 40 27 24 12" 15 lines 28-SEP-1989 14:27 -------------------------------------------------------------------------------- Il existe sur les systèmes d'exploitation Apollo/Aegis et Unix BSD une possibilité très intéressante de mise en correspondance ("mapping") d'un fichier quelconque avec la mémoire virtuelle. Une fois le "mapping" fait, le système renvoie un pointeur vers une adresse en mémoire virtuelle et on peut alors accéder au contenu du fichier comme s'il était en mémoire. Le fichier sur disque est utilisé comme fichier de pagination. Cela permet de mettre en mémoire virtuelle très vite des fichiers beaucoup plus gros que le fichier de pagination système. Une telle possibilité existerait-elle dans VMS ? Et si non, comment faire à peu près la même chose ? D'avance merci à ceux qui auraient une réponse. S. Bortzmeyer INRETS ================================================================================ Note 506.1 "Mapping" des fichiers 1 of 4 DECUSF::GERARD_G "G. Gerard ENST centre de calcul" 2 lines 28-SEP-1989 14:40 -< ca existe ... >- -------------------------------------------------------------------------------- Le system service $CRMPSC avec le service RMS OPEN UFO fait ca tres bien je crois. ================================================================================ Note 506.2 "Mapping" des fichiers 2 of 4 DECUSF::OURGHANLIA_B "Bernard, VMS/VAXClusters" 177 lines 28-SEP-1989 20:48 -< Un exemple... >- -------------------------------------------------------------------------------- Il ne manquerait plus que l'on ne sache pas faire sous VMS quelque chose que l'on fait sous U__X !!! Un exemple en BASIC : 1. Creer le fichier MAP_SECTION_FILE.BAS 2. Creer le fichier MAP_SECTION_FILE.OPT 3. Compiler MAP_SECTION_FILE.BAS : $BASIC MAP_SECTION_FILE 4. Linker MAP_SECTION_FILE : $LINK MAP_SECTION_FILE,- MAP_SECTION_FILE/OPT ============================================================================== ! MAP_SECTION_FILE.BAS ! OPTION TYPE = EXPLICIT EXTERNAL LONG FUNCTION sys$crmpsc, & sys$deltva, & sys$dassgn EXTERNAL LONG CONSTANT sec$m_wrt, & sec$m_dzro, & rms$_created ! Common area to pass CHANNEL number and RMS_status. ! COMMON (open_info) LONG sec_chan, rms_status ! Common area to which the file will be mapped. The ! array may be dimensioned as required, but it should ! be large enough to contain the file (or portion of ! the file) that we intend to map. Note that this common ! area (psect) MUST be aligned on a page boundary, and ! is accomplished by specifying the PAGE attribute in ! the linker options file. ! COMMON (my_section) STRING sec_array(31%) = 512% DECLARE LONG stat, & in_adr(1), & ret_adr(1), & sec_flags, & cnt ! Open the file with the USEROPEN keyword specifying our ! useropen routine to set the User File Open (UFO) option ! and obtain the channel number. Note that the FILESIZE ! clause is used on the open to pre-extend the file. If ! FILESIZE is not specified, the initial allocation will ! be zero, and the $CRMPSC service will fail. ! OPEN 'virtual.dat' AS FILE #1%, ORGANIZATION VIRTUAL, & FILESIZE 32%, USEROPEN get_chan ! Get the starting and ending virtual addresses of our ! common area. These addresses will be passed to the ! $CRMPSC service and will determine where the section ! is mapped. The $CRMPSC service will "adjust" our ! ending address to the next page boundary. ! in_adr(0%) = LOC(sec_array(0%)) in_adr(1%) = LOC(sec_array(31%)) ! Initialize the flag mask. ! ! SEC$M_WRT - Pages form a read/write section. ! SEC$M_DZRO - Pages are demand-zero pages. ! ! Check the 'rms_status' saved from $CREATE in the USEROPEN ! routine. If the file did not exist and was created, we ! want to initialize the section to zeros by setting the ! DZRO flag. If the file already exists, we DO NOT want to ! initialize the section. ! IF rms_status = rms$_created THEN sec_flags = sec$m_wrt OR sec$m_dzro ELSE sec_flags = sec$m_wrt END IF ! Call the $CRMPSC service to create and map the section. ! The file associated with SEC_CHAN will be mapped as a ! private read/write section in memory. Note that we are ! not passing the PAGCNT argument and will default to the ! size of the section file. ! stat = sys$crmpsc ( in_adr() BY REF, & ret_adr() BY REF,, & sec_flags BY VALUE,,,, & sec_chan BY VALUE,,,, ) IF (stat AND 1%) = 0% THEN CALL lib$stop (stat BY VALUE) \ END IF PRINT "Address range requested: ";in_adr(0%);"-";in_adr(1%) PRINT "Address range actually mapped: ";ret_adr(0%);"-";ret_adr(1%) ! Access the section by referencing the variables in the ! common area. ! FOR cnt = 0% TO 31% sec_array(cnt) = "TEST_" + NUM1$(cnt) NEXT cnt done: ! Call $DELTVA to unmap and delete the section. Note that ! deleting the virtual address space occupied by the section ! does not delete the section file. When a process unmaps a ! private section, all modified pages are written back to the ! disk. Optionally, the Update Section File on Disk ($UPDSEC) ! service can be used to ensure that all modified pages are ! written back to the disk at regular intervals. ! stat = sys$deltva (ret_adr() BY REF,,) IF (stat AND 1%) = 0% THEN CALL lib$stop (stat BY VALUE) \ END IF ! Call $DASSGN to deassign the channel and close the file. ! stat = sys$dassgn (sec_chan BY VALUE) IF (stat AND 1%) = 0% THEN CALL lib$stop (stat BY VALUE) \ END IF END FUNCTION LONG get_chan ( fabdef user_fab, & rabdef user_rab, & LONG channel ) ! ! USEROPEN routine to set the UFO bit and obtain ! the channel number from RMS. ! OPTION TYPE = EXPLICIT EXTERNAL LONG FUNCTION sys$create ! Include the RMS Data Structure Definitions. ! %INCLUDE "$fabdef" %FROM %LIBRARY "sys$library:basic$starlet" %INCLUDE "$rabdef" %FROM %LIBRARY "sys$library:basic$starlet" ! Common area used to pass CHANNEL number and ! RMS_status to caller. ! COMMON (open_info) LONG sec_chan, rms_status ! Initialize the file processing options (FOP). ! ! UFO (User file open) - This option is required and ! indicates that the file will be opened for user I/O. ! The channel will be assigned in the access mode of ! the caller. ! ! CBT (Contiguous best try) ! ! CIF (Create-if nonexistent) - If the file does not exist, ! it is created. Otherwise, an existing file will be opened. ! user_fab::fab$l_fop = user_fab::fab$l_fop OR & fab$m_ufo OR & fab$m_cbt OR & fab$m_cif ! Call $CREATE to create and/or open the file. ! rms_status = sys$create (user_fab) ! Save the channel number. ! sec_chan = user_fab::fab$l_stv ! Set the status and return. ! get_chan = rms_status END FUNCTION ============================================================================== ! MAP_SECTION_FILE.OPT ! ! LINKER options file to assign the PAGE attribute to a ! program section. The specified PSECT will be aligned ! on a page boundary. ! PSECT_ATTR = MY_SECTION, PAGE ================================================================================ Note 506.3 "Mapping" des fichiers 3 of 4 DECUSF::MANET_P "Philippe - SECMAI" 79 lines 23-OCT-1989 17:44 -< Un autre exemple en C >- -------------------------------------------------------------------------------- /* ** ** MapFile.c -- Map a section to an existing file. ** */ #include #include #include #include static long sec_chan; /* channel associated to the section */ static unsigned long sec_addr[2]; /* address range for the section */ /* ** ** map_file() -- map the file specified by name and return starting address. ** */ char *map_file (char *name) { struct FAB fab; long status; unsigned long sec_flags; unsigned long in_addr[2]; /* * Open the file with the User File Open bit set, since we do not want RMS * to do more than just locating and opening the file. */ fab = cc$rms_fab; fab.fab$l_fna = name; fab.fab$b_fns = strlen(name); fab.fab$l_fop = FAB$M_UFO; fab.fab$b_rtv = 255; /* keep retrieval pointers in memory */ status = sys$open (&fab, 0, 0); if (!(status & 1)) exit (status); /* * Create and map a read only section to the file just opened. The address * range will be in P0 space, but since we do not know the size or structure * of the file, ask $CRMPSC to allocate memory (with flag bit SEC$M_EXPREG). */ sec_chan = fab.fab$l_stv; sec_flags = SEC$M_EXPREG; in_addr[0] = in_addr[1] = 0x200; status = sys$crmpsc (in_addr, sec_addr, 0, sec_flags, 0, 0, 0, sec_chan, 0, 0, 0, 0); if (!(status & 1)) exit (status); return ((char *) sec_addr[0]); } /* ** ** unmap_file() -- free space allocated in map_file() and close the file. ** */ void unmap_file() { long status; status = sys$deltva (sec_addr, 0, 0); if (!(status & 1)) exit (status); status = sys$dassgn (sec_chan); if (!(status & 1)) exit (status); } ================================================================================ Note 506.4 "Mapping" des fichiers 4 of 4 DECUSF::BLOCH_L "L. Bloch CNAM tel. 40 27 24 12" 3 lines 7-NOV-1989 17:36 -< Merci .. >- -------------------------------------------------------------------------------- Au nom de Stéphane Bortzmeyer, merci à tous pour ces contributions décisives.