From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 30-NOV-1990 06:28:31.36
To:	MRGATE::"ARISIA::EVERHART"
CC:	
Subj:	Shareable images  Summary (and how to make a fortran library shareable)

Received:  by crdgw1.ge.com (5.57/GE 1.80)
	 id AA06227; Fri, 30 Nov 90 06:12:12 EST
Received: From UCBVAX.BERKELEY.EDU by CRVAX.SRI.COM with TCP; Thu, 29 NOV 90 15:10:04 PST
Received: by ucbvax.Berkeley.EDU (5.63/1.42)
	id AA15676; Thu, 29 Nov 90 14:49:47 -0800
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 29 Nov 90 23:59:49 GMT
From: daemon@bloom-beacon.mit.edu
Organization: M.I.T. Lab for Nuclear Science
Subject: Shareable images  Summary (and how to make a fortran library shareable)
Message-Id: <1990Nov29.211321.25819@athena.mit.edu>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

-Message-Text-Follows-

  I would like to thank the many people who helped me with my question,
I got about 10 very helpful replies. Follows is my summary about what
I learned this week. In addition to answers to my questions :

   Question 1 How do you get demand-zero pages in shareable images.

   Question 2 How do you make a  shareable image with a user defined
              common block size

   I've added some related things I learned: 

   3.  Easy instructions for turning your Library file into a shareable 
     image. *These instructions are for FORTRAN libraries, you might
     have to modify them for other languages.*

   4.  Using Link /SYMBOL qualifier to  create .STB files. If you have
     a large library that includes a general purpose interactive interface
     (we do), then this enables you to use the interactive interface program
     as a kind of 'runtime library' for programs.  For us combining the general
     purpose interface with the user code is a real advantage.


  1. Demand-zero compression is not allowed by default for shareable images.
    To get it add the following to the option file. You have to know
    the name of the writable psect you want to be demand zero. For Fortran 
    libraries this is probably the name of a COMMON block. For instance if 
    you have  COMMON /USER/SPACE(1000000)  in the image and you want that 
    common block to be demand zero pages add the following to the linker option
    file:

     UNSUPPORTED=1  !Allows demand-zero compression
     psect_attr=USER,NOSHR  !Can't share demand zero pages

    The UNSUPPORTED word makes people nervous, including me. However
    no one who replied seem to know of a case personally were this caused 
    problems. Though there were several "rumours" of situations were it
    is a problem. I've had no trouble with it.


  2. How to get a variable size common block. Create a second sharable
   image that just contains the common block, and perhaps a function
   to return the size of the common. As long as the common block is
   declared /NOSHR users can substitue their own version since it does not
   have to be installed.

      For instance:

      INTEGER FUNCTION COM_SIZE
      parameter (isize=1000000)
      COMMON/USER/SPACE(isize)
      COM_SIZE=ISIZE
      return
      end


     In the library declare the common as follows

     Parameter (min_size=1)
     COMMON/USER/SPACE(min_size)

     As long as ISIZE>MIN_SIZE it will work. To change the space
    of the common just recompile and link COM_SIZE. You don't need
    to relink the library. You can have several premade versions
    COM_SIZE_BIG.EXE, COM_SIZE_SMALL.EXE, COM_SIZE.EXE and use the
    appropiate version by pointing to them with the logical COM_SIZE.
    Of course the library can't be compiled /CHECK=BOUNDS. To guarentee
    that the library won't need to be relinked COM_SIZE
    should have a transfer vector setup as follows: (this basically
    right out of the linker manual)

    File XFER.MAR   
    ; Transfer vectors for paw user code
    ;
      .title myxfr
      .psect $$xfrvectors,exe,nowrt

      .transfer com_size
      .mask com_size
      jmp l^com_size+2

      .end


   These are compiled and linked as follows to produce the image, the
COLLECT= line in the option file pulls in the COMXFR macro object.

    $LINK/SHARE PAWC_SIZE,SYS$INPUT:/opt
    UNSUPPORTED=1               !allows demand zero compression (not neccesary)
    collect=xxfervector,,xfer  !gets transfer vector macro object
    psect_attr=USER,noshr      !make common blocks not shared
    ^Z



  3. How to turn an existing library into a shareable image automatically.

     Assume you have a library USERLIB that you would like to make shared,
  here is how to do it without a lot of work.

        LIBRARY/LIS=SYMBOLS.DAT/NAMES USERLIB (/NAMES is important!!)
        Every symbol listed must go into a option file on a line like

        UNIVERSAL=SYMBOLXXX

  The following fortran program UNIVERSAL will do this for you, I've
  included it at the end of this message. To use it

   $LIBRARY/LIS=SYMBOLS.DAT/NAMES USERLIB
   $DEFINE FOR002 SYMBOLS.DAT
   $DEFINE FOR003 UNIVERSAL_SYMBOLS.OPT
   $Run UNIVERSAL

  Link the library /share.

   $LINK/SHARE=NL:/MAP=USERLIB.MAP DUMMY.OBJ,UNIVERSAL_SYMBOLS/OPT,-
                   USERLIB/LIB,NECCESARY_LIBRARIES/LIB

  The DUMMY.OBJ is just a program that does nothing. I needed it because
  the linker wouldn't let the only module be a library. Alternatively
  you you could use a /include= statement. The UNIVERSAL_SYMBOLS.OPT
  creates a reference to every routine in the library so the linker pulls them
  all out. Every writable PSECT must be declared /NOSHR. (Unless you want 
  to share data between programs). To do this you need a seperate linker option
  file to declare these psects /NOSHR. The option file has lines that
  look like this: 

        PSECT_ATTR=USER,NOSHR

  You can find the writable psects from the map file created above. Or
  I've included the fortran program NOSHARE at the end of this message which
  will do it for you. To run it do the following

       $SEARCH/OUTPUT=WRT_PSECTS.DAT USERLIB.MAP " SHR"," WRT"/MATCH=AND
       $DEFINE FOR002 WRT_PSECTS.DAT
       $DEFINE FOR003 NOSHR_PSECTS.OPT
       $RUN NOSHARE.

  Finally link the shareable image:

       $LINK/SHARE DUMMY.OBJ,UNIVERSAL_SYMBOLS/OPT,NOSHR_PSECTS/OPT,-
                   necessary_other_libraries/lib


  4. Another useful hack for shareable images. It turns out that
   this was more appropiate for us than creating a shareable library. 
   When you might use this is when you have a library which also includes 
   a large interactive interface. We have such a situation, but of course
   people need to able to call the library routines directly, to automate 
   certain processes.Its nice to do this from within the interactive interface
   because its supports debugging, since you can use all the library utilities
   to look at what you are doing. So what you do is make the USER code
   a shareable image, and give the interactive image the ability to call
   the user code. If the user code can call the subroutines in the interactive
   interface, then it in effect acts as a runtime library. That is there
   is only one copy of the library code. It is in the interactive interface
   program. Everyone runs the same executable to get access to it. The user
   interface program calls the users program as a subroutine. By using a 
   transfer vectors and putting the user code in a shareable image, the 
   main image doesn't have to be relinked when the user code is changed.
   The only trick is giving the user program the ability to call the 
   library routines in the main image. Here's how you can give the user
   access to all the routines in the main image.


   Create a dummy routine  USER_HOOK.FOR.  Make it a shareable image.
   In the large interactive interface program add a call to USER_HOOK.
   Be sure to link with a transfer vector section.

   Link the interface routine   /SYMBOL to create a .STB file. 

   Users edit USER_HOOK.FOR to create thier programs. When they link
   include the .STB file to resolve those references to library 
   routines in the main image. Define the process logical USER_HOOK
   to point to the users version of USER_HOOK.EXE




C-------------------------------------------------------------
      PROGRAM  UNIVERSAL
C Author Chuck Parsons  11/28/90
C
C Searches Library listing input from unit 2 and outputs a option
C file on unit 3 declaring the symbols to be universal
C
      CHARACTER*132 LINE
      CHARACTER*32  SYMBOL
      LOGICAL SPACE
C
C Throw away the header
C
      DO I=1,7
        READ(2,11)LINE
11      FORMAT(A132)
      ENDDO
C
C Read lines until end of file
C
      DO WHILE (.TRUE.)
        READ(2,11,END=100)LINE
C
C Ignore Blank and "Module" lines
C
        IF((LINE.NE.' ').AND.(LINE(1:6).NE.'Module'))THEN
C
C Parse out symbol names seperated by single space
C
          J=1
          DO I=1,132
            IF('A'.LE.LINE(I:I).LE.'A')THEN
               LINE(J:J)=LINE(I:I)
               J=J+1
               SPACE=.FALSE.
            ELSEIF(.NOT.SPACE)THEN
               LINE(J:J)=' '
               J=J+1
               SPACE=.TRUE.
            ENDIF
          ENDDO
C
C loop over symbols writing out UNIVERSAL=
C
          do while (line.ne.' ')
            symbol=line(1:index(line,' '))
                line=line(index(line,' ')+1:)
            if (symbol.ne.' ')write(3,10)symbol
10          format(' UNIVERSAL=',A)
          enddo
        endif
      enddo
100   close(2)
      close(3)
      end

C-------------------------------------------------------------
C-------------------------------------------------------------
      PROGRAM  NOSHARE
C Author Chuck Parsons  11/28/90
C
C  Searches Output of:
C	$SEARCH/OUTPUT=FOR002.DAT LINKER.MAP " WRT"," SHR"/MATCH=AND
C  To create OPTION file declaring them to be NOSHR
C  Input on Unit 2
C  Output on Unit 3
C
      CHARACTER*132 LINE
      CHARACTER*32  SYMBOL,LAST_SYMBOL
C Read lines until end of file
      LAST_SYMBOL=' '
      DO WHILE (.TRUE.)
        READ(2,11,END=100)LINE
11      FORMAT(A132)
        SYMBOL=LINE(1:INDEX(LINE,' '))
C
C Don't list psects multiple times.
        IF(LAST_SYMBOL.NE.SYMBOL)WRITE(3,10)SYMBOL(1:INDEX(SYMBOL,' '))
10          FORMAT(' PSECT_ATTR=',A,',NOSHR')
        LAST_SYMBOL=SYMBOL
      ENDDO
100   CLOSE(2)
      CLOSE(3)
      end

