SUBROUTINE DYN0_MAP( NDIM, DIMS, MTYPE, PTR, STATUS ) *+ * Name: * DYN0_MAP * Purpose: * Map a dynamic array of elements of type MTYPE * Language: * Starlink Fortran * Invocation: * CALL DYN0_MAP( NDIM, DIMS, MTYPE, PTR, STATUS ) * Description: * Tries to allocate an area of mapped memory from either the process * heap or by mapping an HDS file. * Arguments: * NDIM = INTEGER (given) * Dimensionality of required dynamic array * DIMS[] = INTEGER (given) * Dimensions of the required dynamic array * MTYPE = CHARACTER*(*) (given) * The type of the elements (HDS style type name) * PTR = INTEGER (returned) * Address of the newly allocated dynamic memory section * STATUS = INTEGER (given and returned) * The global status. * Examples: * {routine_example_text} * {routine_example_description} * Pitfalls: * {pitfall_description}... * Notes: * {routine_notes}... * Prior Requirements: * {routine_prior_requirements}... * Side Effects: * {routine_side_effects}... * Algorithm: * {algorithm_description}... * Accuracy: * {routine_accuracy} * Timing: * {routine_timing} * External Routines Used: * {name_of_facility_or_package}: * {routine_used}... * Implementation Deficiencies: * {routine_deficiencies}... * References: * DYN Subroutine Guide : http://www.sr.bham.ac.uk/asterix-docs/Programmer/Guides/dyn.html * Keywords: * package:dyn, usage:private * Copyright: * Copyright (C) University of Birmingham, 1995 * Authors: * RJV: Bob Vallance (ROSAT, University of Birmingham) * DJA: David J. Allan (Jet-X, University of Birmingham) * {enter_new_authors_here} * History: * 16 Jun 1992 (DJA): * Use PSX call to get small amounts of memory. Chooses * scratch file name depending on OS. * 4 Jan 1993 (DJA): * Use process pid to create uniquely named files. Removes * restriction on multiple processes sharing scratch space. * 7 Apr 1993 (DJA): * Delete file if created but not mapped. Error reporting tidied up. * 20 Mar 1995 (DJA): * Renamed to from DYN_MAP. No longer works in pages. * 11 Sep 1995 (DJA): * Handle both HDS and ADI style types. * {enter_changes_here} * Bugs: * {note_any_bugs_here} *- * Type Definitions: IMPLICIT NONE ! No implicit typing * Global Constants: INCLUDE 'SAE_PAR' ! Standard SAE constants INCLUDE 'ADI_PAR' INCLUDE 'DAT_PAR' INCLUDE 'PRM_PAR' * Global Variables: INCLUDE 'DYN_CMN' ! DYN common block * DYN_ISINIT = LOGICAL (given) * DYN class definitions loaded? * DYS_ISEQ = INTEGER (given and returned) * File name sequence number * Arguments Given: INTEGER NDIM ! See above INTEGER DIMS(*) CHARACTER*(*) MTYPE * Arguments Returned: INTEGER PTR ! * Status: INTEGER STATUS ! Global status * External References: EXTERNAL CHR_LEN INTEGER CHR_LEN EXTERNAL DYN0_BLK ! Ensures inclusion * Local Constants: INTEGER MAXSYS PARAMETER ( MAXSYS = 1024*1024*4 ) * Local Variables: CHARACTER*132 FNAME ! Scratch file name CHARACTER*8 HPID ! Process identifier ! in zero padded hex CHARACTER*(DAT__SZLOC) LOC ! Temp file locator CHARACTER*80 SDIR ! Scratch directory path INTEGER FC ! 1st useful MTYPE char INTEGER FID ! ADI file identifier INTEGER FLEN ! Length of FNAME used INTEGER NBYTE ! Total # bytes needed INTEGER NELM ! Total # elements INTEGER PID ! Process identifier INTEGER SIZE ! Size in elements LOGICAL GOTSCR ! Got scratch area yet? LOGICAL GOTPID ! Got process pid? LOGICAL GOTSYS ! Got VM from heap? LOGICAL VALID ! LOC a valid locator? * Local Data: DATA GOTSCR, GOTPID/.FALSE., .FALSE./ SAVE SDIR,GOTSCR,GOTPID,HPID *. * Check inherited global status. IF ( STATUS .NE. SAI__OK ) RETURN * Check initialised IF ( .NOT. DYN_ISINIT ) CALL DYN0_INIT() * HDS style type? FC = 1 IF ( MTYPE(1:1) .EQ. '_' ) FC = 2 * Determine element size in bytes IF ( (MTYPE(FC:FC) .EQ. 'I') .OR. (MTYPE(FC:FC) .EQ. 'L') ) THEN SIZE = VAL__NBI ELSE IF ( MTYPE(FC:FC) .EQ. 'R' ) THEN SIZE = VAL__NBR ELSE IF ( MTYPE(FC:FC) .EQ. 'D' ) THEN SIZE = VAL__NBD ELSE IF ( (MTYPE(FC:FC) .EQ. 'W') .OR. : (MTYPE(FC:FC+1) .EQ. 'UW') ) THEN SIZE = VAL__NBW ELSE IF ( (MTYPE(FC:FC) .EQ. 'B') .OR. : (MTYPE(FC:FC+1) .EQ. 'UB') ) THEN SIZE = VAL__NBB ELSE CALL MSG_SETC( 'TYPE', MTYPE ) STATUS = SAI__ERROR CALL ERR_REP( ' ', 'Unrecognised element type /^TYPE/', STATUS ) END IF * Work out number of bytes CALL ARR_SUMDIM( NDIM, DIMS, NELM ) NBYTE = SIZE * NELM * User requested valid amount of memory? IF ( (NBYTE .GT. 0) .AND. (STATUS .EQ. SAI__OK) ) THEN * Initialise GOTSYS = .FALSE. FID = ADI__NULLID * Get small amounts from system pool IF ( NBYTE .LE. MAXSYS ) THEN CALL PSX_MALLOC( NBYTE, PTR, STATUS ) IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_ANNUL( STATUS ) ELSE GOTSYS = .TRUE. END IF END IF * If bigger or system call was unsuccesful create mapped disk section IF ( (NBYTE.GT.MAXSYS) .OR. .NOT. GOTSYS ) THEN * Know scratch area yet? IF ( .NOT. GOTSCR ) THEN CALL PSX_GETENV( 'AST_SCRATCH', SDIR, STATUS ) IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_ANNUL( STATUS ) SDIR = ' ' END IF GOTSCR = .TRUE. END IF * Know process id yet? IF ( .NOT. GOTPID ) THEN CALL PSX_GETPID( PID, STATUS ) IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_ANNUL( STATUS ) PID = 1 END IF GOTPID = .TRUE. * Format in hex WRITE( HPID, '(Z8.8)' ) PID END IF * Create unique filename CALL MSG_FMTI( 'N', 'I4.4', DYS_ISEQ ) DYS_ISEQ = DYS_ISEQ + 1 CALL MSG_SETC( 'PID', HPID//'_' ) CALL MSG_MAKE( 'DYN_^PID^N.TMP', FNAME, FLEN ) IF ( SDIR .GT. ' ' ) THEN FNAME = SDIR(:CHR_LEN(SDIR))//FNAME(:FLEN) FLEN = FLEN + CHR_LEN(SDIR) END IF * Try to create and map the file CALL HDS_NEW( FNAME(:FLEN), 'DYN', '_BYTE', 1, NBYTE, LOC, : STATUS ) CALL DAT_MAPV( LOC, '_BYTE', 'WRITE', PTR, NBYTE, STATUS ) CALL ADI1_PUTLOC( LOC, FID, STATUS ) * Failed? If so, create new error context and try deleting the * file. HDS unfortunately can create files which it cannot then * erase. IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_BEGIN( STATUS ) * Locator is valid? Don't even try deleting the file otherwise CALL DAT_VALID( LOC, VALID, STATUS ) IF ( VALID ) THEN CALL HDS_ERASE( LOC, STATUS ) END IF * Restore error context CALL ERR_END( STATUS ) END IF * Report error if failure IF ( STATUS .NE. SAI__OK ) THEN CALL ERR_REP( ' ', 'Unable to create dynamic memory', : STATUS ) CALL MSG_SETI('NBYTE',NBYTE) CALL ERR_REP( ' ', '^NBYTE bytes were requested'// : ' - check space on AST_SCRATCH', STATUS ) END IF END IF ELSE STATUS = SAI__ERROR CALL ERR_REP(' ', 'Dynamic memory of zero length requested', : STATUS ) END IF * Add to internal list CALL DYN0_MAPADD( PTR, NELM, NBYTE, FID, STATUS ) * Tidy up IF ( STATUS .NE. SAI__OK ) THEN CALL AST_REXIT( 'DYN0_MAP', STATUS ) END IF END SUBROUTINE DYN0_MAPADD( PTR, NITEM, NBYTE, FID, STATUS ) *+ * Name: * DYN0_MAPADD * Purpose: * Add details of a mapped memory section to the internal store * Language: * Starlink Fortran * Invocation: * CALL DYN0_MAPADD( PTR, NITEM, NBYTE, FID, STATUS ) * Description: * Tries to allocate an area of mapped memory from either the process * heap or by mapping an HDS file. * Arguments: * PTR = INTEGER (given) * Address of the section * NITEM = INTEGER (given) * Number of mapped elements * NBYTE = INTEGER (given) * Number of mapped bytes * FID = INTEGER (GIVEN) * ADI file identifier if file section * STATUS = INTEGER (given and returned) * The global status. * Examples: * {routine_example_text} * {routine_example_description} * Pitfalls: * {pitfall_description}... * Notes: * {routine_notes}... * Prior Requirements: * {routine_prior_requirements}... * Side Effects: * {routine_side_effects}... * Algorithm: * {algorithm_description}... * Accuracy: * {routine_accuracy} * Timing: * {routine_timing} * External Routines Used: * {name_of_facility_or_package}: * {routine_used}... * Implementation Deficiencies: * {routine_deficiencies}... * References: * DYN Subroutine Guide : http://www.sr.bham.ac.uk/asterix-docs/Programmer/Guides/dyn.html * Keywords: * package:dyn, usage:private * Copyright: * Copyright (C) University of Birmingham, 1995 * Authors: * RJV: Bob Vallance (ROSAT, University of Birmingham) * DJA: David J. Allan (Jet-X, University of Birmingham) * {enter_new_authors_here} * History: * 20 Mar 1995 (DJA): * Renamed to DYN_MAP_ADD. No longer works in pages. * 21 Dec 1995 (DJA): * Added diagnostic output * {enter_changes_here} * Bugs: * {note_any_bugs_here} *- * Type Definitions: IMPLICIT NONE ! No implicit typing * Global Constants: INCLUDE 'SAE_PAR' ! Standard SAE constants * Global Variables: INCLUDE 'DYN_CMN' ! DYN common block * DYS_DIAG = LOGICAL (given) * Package diagnostics on? * DYS_PTR = INTEGER (given and returned) * DYN memory addresses * DYS_NBYTE = INTEGER (returned) * DYN memory sizes * DYS_NITEM = INTEGER (returned) * DYN memory number of elements * DYS_FID = INTEGER (returned) * DYN file identifiers * Arguments Given: INTEGER PTR ! See above INTEGER NITEM, NBYTE, FID * Status: INTEGER STATUS ! Global status * Local Variables: INTEGER I ! Loop over slots LOGICAL FOUND ! Found a free slot? *. * Check inherited global status. IF ( STATUS .NE. SAI__OK ) RETURN * Look for a free slot I = 1 FOUND = .FALSE. DO WHILE ( (I.LE.DYN__NMAX) .AND. .NOT. FOUND ) IF ( DYS_PTR(I) .EQ. 0 ) THEN FOUND = .TRUE. ELSE I = I + 1 END IF END DO * Use next slot IF ( FOUND ) THEN * Initialise fields of slot DYS_PTR(I) = PTR DYS_NBYTE(I) = NBYTE DYS_NITEM(I) = NITEM DYS_FID(I) = FID * Diagnostic? IF ( DYS_DIAG ) THEN CALL MSG_SETI( 'PTR', PTR ) CALL MSG_SETI( 'NB', NBYTE ) CALL ADP_OUT( 'DYN: Allocated ^NB bytes at address ^PTR' ) END IF ELSE STATUS = SAI__ERROR CALL ERR_REP( ' ', 'Run out of internal DYN slots', STATUS ) END IF END