From:	CSBVAX::CSBVAX::MRGATE::"SMTP::CAMPUS.SWARTHMORE.EDU::JAMISON" 29-MAR-1989 17:14
To:	MRGATE::"ARISIA::EVERHART"
Subj:	SHOWDEF  2/2


Received: from physics.swarthmore.edu by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 9583; Wed, 29 Mar 89 16:22:40 EST
Return-path: JAMISON%campus.swarthmore.edu@CUNYVM.CUNY.EDU
Received: from campus.swarthmore.edu by physics.swarthmore.edu; Wed, 29 Mar 89
 15:18 EST
Date: Wed, 29 Mar 89 15:02 EST
From: "John L. Jamison x8508" <JAMISON%campus.swarthmore.edu@CUNYVM.CUNY.EDU>
Subject: SHOWDEF  2/2
To: everhart%arisia.decnet@crd.ge.com
X-VMS-To: IN%"everhart%arisia.decnet@crd.ge.com"

+-+-+-+ Beginning of part 2 +-+-+-+
X        .library "SYS$LIBRARY:LIB"
X    `032
X        $STATEDEF
X        $PCBDEF
X        $PHDDEF
X        $ACBDEF
X        $IPLDEF
X        $PRIDEF
X        $PSLDEF
X        $LNMDEF
X        $LNMSTRDEF
X    `032
Xlnm_size = LNM$C_NAMLENGTH + LNMX$T_XLATION
Xdd_size  = 256
X    `032
X        .psect  $LOCAL, PIC,USR,CON,REL,LCL,NOSHR,NOEXE,RD,WRT,NOVEC,LONG
X    `032
Xpid:     .long  0
Xdevice:  .blkb  lnm_size
Xddstring:.blkb  dd_size
X    `032
X        .psect  $CODE, PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT,NOVEC,LONG
X    `032
X        .entry  lib_default_dir,`094m<r2,r3,r4,r5,r6,r7,r8>
X    `032
X        clrb    device+lnmx$t_xlation   ;default to zero length strings
X        clrb    ddstring
X        movl    @4(ap),r0               ;prepare the pid
X        jsb     G`094exe$epid_to_ipid      ;convert to internal form
X        movl    r0,pid
X        bneq    5$                      ;check for
X        pushl   #ss$_nonexpr            ;non-existent process
X        brb     10$                     ;blank strings and return
X    `032
X5$:     $cmkrnl_s routin=get_defdir     ;get into kernel mode for the
X                                        ;real work
X        pushl   r0                      ;save return status
X    `032
X10$:    movl    8(ap),r6                ;get address of destination descr
X        movw    (r6),r7                 ;grab length of destination string
X        cvtbw   device+lnmx$t_xlation,r8 ;grab length of device string
X        movab   @4(r6),r6               ;get address of destination string
X        movc5   r8,device+lnmx$t_xlation+1,#`094A/ /,-
X                r7,(r6)                 ;install device string
X        tstl    r0                      ;see if any room left
X        bneq    20$
X        subw2   r8,r7                   ;compute the remaining length
X        bleq    20$                     ;if none left just punt
X        addw2   r8,r6                   ;compute new address
X        cvtbw   ddstring,r8             ;get length of dd string
X        movc5   r8,ddstring+1,#`094A/ /,-
X                r7,(r6)                 ;install dd string
X    `032
X20$:    movl    (sp)+,r0                ;retrieve status
X        ret
X    `032
Xacb_l_origpid   =       acb$l_ast                 ;pid of requestor
Xacb_l_imgcnt    =       acb$l_astprm              ;image count in PHD
Xacb_l_retloc    =       acb$l_kast+4              ;address to return data
Xacb_s_retloc    =       4                         ;size of that address
X;adjacency of next two items required
Xacb_t_device    =       acb_l_retloc+acb_s_retloc ;SYS$DISK translation
Xacb_s_device    =       lnm_size                  ;maximum size of it
Xacb_t_ddstring  =       acb_t_device+acb_s_device ;default directory string
Xacb_s_ddstring  =       dd_size                   ;directory string size
Xacb_k_size      =       acb_t_ddstring+acb_s_ddstring ;total size of acb
X                                                  ;ast code follows data
X    `032
X; Routine to return device and directory data from the other process
X    `032
X; Note that code to execute in other process' context follows data
X; in ast control block.
X    `032
X        .enable lsb
X    `032
X        .entry  get_defdir,`094m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
X    `032
X        movl    #<acb_k_size+codelen>,r1 ;size of non-paged buffer
X        jsb     G`094exe$allocbuf          ;allocate buffer for code and data
X        blbs    r0,1$                   ;skip if no error
X        ret                             ;return
X    `032
X1$:     movl    r2,r5                   ;save address of packet
X        movl    pid,acb$l_pid(r5)       ;set target pid
X        movb    #<1@acb$v_kast>,acb$b_rmod(r5)    ;set special kernel ast
X        movab   acb_k_size(r5),acb$l_kast(r5)     ;set address for ast
X        movab   device,acb_l_retloc(r5) ;set address of return location
X        movl    G`094ctl$gl_pcb,r4         ;get address of current pcb
X        movl    pcb$l_pid(r4),acb_l_origpid(r5)   ;set pid for return
X        movl    pcb$l_phd(r4),r4        ;get PHD address
X        movl    phd$l_imgcnt(r4),acb_l_imgcnt(r5) ;sequence number of image
X        pushr   #`094m<r5>                 ;save regs for movc3
X        movc3   #codelen,code,@acb$l_kast(r5)     ;copy code segment
X        popr    #`094m<r5>                 ;restore registers
X    `032
X; The AST is queued to the destination process unless it has delete or
X; suspend pending set, or is currently suspended.
X    `032
X        movl    pid,r2                  ;get target pid before synching
X    `032
Xbegin_lock:
X        setipl  lock_ipl                ;raise IPL to synch, lock code
X    `032
X        movl    r2,r0                   ;Call system routine for PCB
X        jsb     G`094exe$ipid_to_pcb       ;Since its not related to the PID
X        movl    r0,r4
X        movl    #ss$_nonexpr,r0         ;assume non-existent process
X        tstl    r4                      ;see if we had an error
X         bneq   7$                      ;skip if not
X        brw     10$                     ;exit if so
X    `032
X7$:     cmpl    pcb$l_pid(r4),r2        ;is pid same?
X        bneq    10$                     ;br if not
X        tstl    pcb$l_jib(r4)           ;see if it has a jib
X        beql    10$                     ;if not, don't try to queue the AST
X        bbs     #pcb$v_delpen,pcb$l_sts(r4),10$ ;br if delete pending
X        movl    #ss$_suspended,r0       ;assume suspended process
X        bbs     #pcb$v_suspen,pcb$l_sts(r4),10$ ;br if suspend pending
X        cmpw    #sch$c_susp,pcb$w_state(r4)
X        beql    10$                     ;or if process suspended
X        cmpw    #sch$c_suspo,pcb$w_state(r4)
X        beql    10$                     ;or process suspended out of memory
X        cmpw    #sch$c_mwait,pcb$w_state(r4)
X        beql    10$                     ;or in MWAIT
X        movzbl  #pri$_ticom,r2          ;set priority increment class
X        jsb     G`094sch$qast              ;queue ast for target
X    `032
X; If process is in compute state and at a lower priority than the requesting
X; process, boost its current priority to the requesting process's current
X; priority. (Required because event reporting won't normallly boost a COM
X; state process's priority).
X    `032
X        cmpw    #sch$c_com,pcb$w_state(r4) ;process in compute state?
X        beql    8$
X        cmpw    #sch$c_como,pcb$w_state(r4) ;or compute out of memory?
X        bneq    9$
X8$:     movl    G`094ctl$gl_pcb,r3         ;get requestor's PCB address
X        movb    pcb$b_pri(r3),r0        ;get requestor's current priority
V        cmpb    r0,pcb$b_pri(r4)        ;other process have a higher priority
X?
X        bgequ   9$                      ;if GEQU yes, don't boost priority
V        cmpb    #16,r0                  ;will boost be into realtime priority
X?
X        bgtru   9$                      ;if GEQU yes, don't boost priority
X        jsb     G`094sch$chsep             ;boost other process's priority
X9$:     brw     out_and_wait            ;successful AST queued, go wait
X    `032
X; We were unable to deal with the specified process. Deallocate the system
X; buffer and return.
X    `032
X10$:    pushl   r0                      ;push error code
X        movl    r5,r0                   ;get addr of AST packet
X        jsb     G`094exe$deanonpaged       ;deallocate the block
X        setipl  #0                      ;restore IPL
X        popl    r0                      ;restore status
X        ret                             ;and return
X    `032
X; The AST is queued and the other process can handle it now. Lower
X; IPL and wait for the response.
X    `032
Xout_and_wait:
X        setipl  #0                      ;lower our IPL
X        $HIBER_S                        ;SKAST will wake us up
X        ret                             ;we're finished, return
X    `032
Xlock_ipl:
X        .long   ipl$_synch              ;locate here to insure lock
X    `032
Xend_lock:
X        assume  <end_lock-begin_lock> le 512
X    `032
X; Code placed in non-paged buffer executed in
X; destination process context.
X    `032
X        .enable lsb
X    `032
Xcode:   pushr   #`094m<r6,r7>              ;we need these registers
X        movl    r5,r7                   ;save ACB in non-volatile register
X    `032
X; We now translate SYS$DISK in the destination process context. This
X; is done with calls to the internal LNM$ system routines.
X    `032
X; Translate SYS$DISK
X    `032
X        movzbl  #8,r0                   ;set logical name length
X        movq    #`094A/SYS$DISK/,-(sp)     ;push logical name onto stack
X        moval   (sp),r1                 ;set logical name addr
X        movzbl  process_table,r2        ;length of table name
X        moval   process_table+1,r3      ;process name table name
X        movl    #psl$c_user,r5          ;access mode = user
X        moval   acb_t_device(r7),r6     ;point at lmnx buffer we have
X        jsb     G`094lnm$search_one        ;search for the logical name
X        addl    #8,sp                   ;clean stack
X        blbs    r0,44$                  ;Exit on any error
X        clrb    acb_t_device(r7)        ;Error - return zero length string
X    `032
X; Now get the default directory string
X    `032
X44$:    movab   acb_t_ddstring(r7),r2   ;get addr to put default directory
X        movab   G`094pio$gt_ddstring,r1    ;get addr of def dir
X        movb    (r1),(r2)+              ;copy length
X        movzbl  (r1)+,r0                ;convert to longword
X        movc3   r0,(r1),(r2)            ;copy string
X    `032
X        movl    r7,r5                   ;restore ACB address
X        popr    #`094m<r6,r7>              ;restore r6, r7
X    `032
X        movl    acb_l_origpid(r5),acb$l_pid(r5) ;turn the block around
X        movab   b`09420$,acb$l_kast(r5)    ;new AST routine
X        movb    #<1@acb$v_kast>,acb$b_rmod(r5) ;set kast again
X    `032
X6$:     setipl  #ipl$_synch             ;raise IPL to synch, lock code
X    `032
X        movl    acb_l_origpid(r5),r0    ;Get caller PID
X        jsb     G`094exe$ipid_to_pcb       ;Convert to PCB
X        movl    r0,r1
X    `032
X        cmpl    pcb$l_pid(r1),acb$l_pid(r5) ;same PID in both places
X        bneq    8$                      ;br if not
X        bbs     #pcb$v_delpen,pcb$l_sts(r1),8$ ;error if delete pending
X        clrl    r2                      ;null priority increment
X        jsb     G`094sch$qast              ;queue the AST
X        setipl  #ipl$_astdel            ;drop back to AST delivery level
X        rsb
X    `032
X; If the process did not exist, or was marked for delete, deallocate the
X; blocks and return.
X    `032
X8$:     setipl  #ipl$_astdel            ;drop back to AST delivery level
X        movl    r5,r0                   ;get buffer address
X        jmp     @#exe$deanonpaged       ;deallocate it and exit
X    `032
Xprocess_table:
X        .ascic  /LOG$PROCESS/
X    `032
X; This is the special kernel mode AST code for the requesting process
X; that copies the data from the system buffer to the requestor's address
X; space.  It first checks to see if the process is running the same image
X; that started all this.  If not, it punts, deallocating the buffer and
X; exiting.
X    `032
X20$:    movl    G`094ctl$gl_phd,r3         ;get process header address
X        cmpl    phd$l_imgcnt(r3),acb_l_imgcnt(r5) ;see if the same
X        beql    21$                     ;br if okay
X        movl    r5,r0                   ;set buffer address
X        jmp     G`094exe$deanonpaged       ;release the buffer and return
X    `032
X21$:    movab   acb_t_device(r5),r0     ;get addr of data
X        movl    acb_l_retloc(r5),r1     ;get addr to move data to
X        pushr   #`094m<r5>                 ;save ACB address
X        movc3   #<acb_s_device+acb_s_ddstring>,(r0),(r1) ;copy info
X        popr    #`094m<r5>                 ;restore ACB
X    `032
X25$:    movl    acb$l_pid(r5),r1        ;get pid for wake
X        movl    G`094ctl$gl_pcb,r4         ;get pid
X        setipl  #ipl$_synch             ;raise to synch
X        jsb     G`094sch$wake              ;wake process
X        setipl  #ipl$_astdel            ;lower ipl
X        movl    r5,r0                   ;set address for release
X        jmp     G`094exe$deanonpaged       ;free block and exit
X    `032
Xcodelen = .-code                        ;size of code segment
X    `032
X        .end
$ GOSUB UNPACK_FILE
$ EXIT
-+-+-+-+-+ End of part 2 +-+-+-+-+-
