bdoor.tcl 5.54 KB
#
# Copyright (C) 1998 by the Board of Trustees
#    of Leland Stanford Junior University.
# Copyright (C) 1998 Digital Equipment Corporation
#
# This file is part of the SimOS distribution.
# See LICENSE file for terms of the license.
#

###
### ALPHA VERSION
###

#
# Copyright (C) 1996-1998 by the Board of Trustees
#    of Leland Stanford Junior University.
# 
# This file is part of the SimOS distribution. 
# See LICENSE file for terms of the license. 
#

FileSourced osf/bdoor.tcl


###
### bdoor command
###
### Now slightly more complicated than it used to be: index all
### variables with the PID of the bdoor process.  This allows
### multiple simultaneous running bdoor processes (as happens,
### for example, during multiple slave startup of a hive system
### with more than two cells)
###

if [info exists bdoorExecutable] {

    ###
    ### assume that we have the statically linked version of bdoor
    ###
    console "loading symbol table from $bdoorExecutable\n"
    symbol load bdoor $bdoorExecutable
    set staticBypass 8
    set BDOORANN(main)         [expr [symbol read bdoor::main] + $staticBypass]
    set BDOORANN(mainEval)     [symbol read bdoor::mainEval]
    set BDOORANN(mainEvalLoop) [symbol read bdoor::mainEvalLoop]
    set BDOORANN(buf)         [symbol read bdoor::buf]
    console "BDOORANN(buf) = $BDOORANN(buf) \n"
} else {
    ###
    ### legacy
    ###
    source sym-bdoor.tcl
    set BDOORANN(main)         $BDOOR(main)
    set BDOORANN(mainEval)     $BDOOR(mainEval)
    set BDOORANN(mainEvalLoop) $BDOOR(mainEvalLoop)
    set BDOORANN(buf)          $BDOOR(buf)
}


# console "TCL: Setting bdoor ann at [symbol read bdoor::main:START]\n"

set bdoor(streamEnabled) 0

set xxcount 0

annotation set pc $BDOORANN(main) -tag bdoor {
    set pid $PID($CPU)
    set machine $M($CPU)
    set bdoor($machine,$pid,argc) $a0
    set bdoor($machine,$pid,argv) $a1
    console "BDOOR main argc=$a0 argv=$a1\n"
}

annotation set pc $BDOORANN(mainEval) -tag bdoor {
    set pid     $PID($CPU)
    set machine $M($CPU)

    if [info exists bdoor($machine,$pid,argc)] {
        # this if test will fail if we are restoring from
        # a checkpoint... the 'bdoor doCheckpoint' ran in the
        # first execution of simos, setting argc and argv, but
        # in the restore we hit the eval annotation first

        set argc $bdoor($machine,$pid,argc)
        set argv $bdoor($machine,$pid,argv)
	
	console "TCL BDOOR argc=$argc argv=$argv pc=$pc \n"


        if {$argc > 1} {
            assert {$PROCESS($CPU) == "bdoor"}
            set bdoorString ""
            for {set i 1} {$i < $argc} {incr i} {
		set bdoorArg [readString [Double [expr $argv+$i*8]]]
                set bdoorString "$bdoorString $bdoorArg"
            }

            console "TCL: $bdoorString\n"

            # hack: ensure that stream is only called when this bdoor is
            # active and will read the result.  If someone tries something
            # fancy the pids won't match and the stream will be a nop.
            
            set bdoor(streamEnabled) 1
            set errno [catch { eval $bdoorString } msg]
            set bdoor(streamEnabled) 0
            if {$errno != 0} {
                console "BDOOR ERROR: $msg\n"
            }
            
        }        
        unset bdoor($machine,$pid,argc) bdoor($machine,$pid,argv)
    } else {
	console "BDOOR mainEval: after checkpoint\n"
    }
}

annotation set pc $BDOORANN(mainEvalLoop) -tag bdoor {
    set pid $PID($CPU)
    set machine $M($CPU)
    if [info exists bdoor($machine,$pid,fid)] {

        # this if test will fail if the user is not running
        # a stream, or if we are restoring a checkpoint

        set fid $bdoor($machine,$pid,fid)
        set len $bdoor($machine,$pid,len)
        set chunk $bdoor($machine,$pid,chunk)

        set sizeLeft [expr $len - ($chunk * 4096)]
        set bytes    [expr ($sizeLeft < 4096) ? $sizeLeft : 4096]

	# console "BDOOR mainEvalLoop: bytes=$bytes &count=$BDOOR(count)\n"
        if {$bytes > 0} {
            if [info exists bdoorExecutable] {
                symbol set bdoor::count $bytes
  	    } else {
                set MEMORY($BDOOR(count)) $bytes
            }

	    binary putmem $fid $BDOORANN(buf) $bytes
            incr bdoor($machine,$pid,chunk)
        } else {
            if [info exists bdoorExecutable] {
                symbol set bdoor::count 0
	    } else { 
                set MEMORY($BDOOR(count)) 0
            }
            binary close $fid
            unset bdoor($machine,$pid,fid) bdoor($machine,$pid,len) bdoor($machine,$pid,chunk)
        }
    }
}

proc stream {hostFileName} {
    global bdoor PID CPU M

    if {! $bdoor(streamEnabled)} {
        console "TCL BDOOR: can't invoke 'stream' if bdoor process is not active\n"
    } else {
        set pid $PID($CPU)
        set machine $M($CPU)
        if [file exists $hostFileName] {
            set bdoor($machine,$pid,fid)   [binary open $hostFileName r]
            set bdoor($machine,$pid,len)   [file size $hostFileName]
            set bdoor($machine,$pid,chunk) 0
        } else {
            console "TCL BDOOR: file $hostFileName does not exist\n"
        }
    }
}

proc streamImmediate {streamData} {
    global bdoor PID CPU M

    if {! $bdoor(streamEnabled)} {
        console "TCL BDOOR: can't invoke 'stream' if bdoor process is not active\n"
    } else {
        set pid $PID($CPU)
        set machine $M($CPU)
        set bdoor($machine,$pid,fid)   [binary immediate "$streamData"]
        set bdoor($machine,$pid,len)   [string length $streamData]
        set bdoor($machine,$pid,chunk) 0
    }
}

registerUserAnns bdoor bdoor