Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] View of /sml/trunk/src/runtime/mach-dep/signal-util.c
ViewVC logotype

View of /sml/trunk/src/runtime/mach-dep/signal-util.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 569 - (download) (as text) (annotate)
Tue Mar 7 04:01:07 2000 UTC (19 years, 8 months ago) by blume
File size: 4847 byte(s)
- size info in BOOTLIST
     * no fixed upper limits for number of bootfiles or length of
       bootfile names in runtime
     * falling back to old behavior if no BOOTLIST size info found
- allocation size heuristics in .run-sml
     * tries to read cache size from /proc/cpuinfo (this is important for
        small-cache Celeron systems!)
- install.sh robustified
- CM manual updates
- paranoid mode
     * no more CMB.deliver() (i.e., all done by CMB.make())
     * can re-use existing sml.boot.* files
     * init.cmi now treated as library
     * library stamps for consistency checks
- sml.boot.<arch>-<os>/PIDMAP file
     * This file is read by the CM startup code.  This is used to minimize
       the amount of dynamic state that needs to be stowed away for the
       purpose of sharing between interactive system and user code.
- CM.Anchor.anchor instead of CM.Anchor.{set,cancel}
     * Upon request by Elsa.  Anchors now controlled by get-set-pair
       like most other CM state variables.
- Compiler.CMSA eliminated
     * No longer supported by CM anyway.
- fixed bugs in pickler that kept biting Stefan
     * past refs to past refs (was caused by the possibility that
       ad-hoc sharing is more discriminating than hash-cons sharing)
     * integer overflow on LargeInt.minInt
- ml-{lex,yacc} build scripts now use new mechanism
  for building standalone programs
- fixed several gcc -Wall warnings that were caused by missing header
  files, missing initializations, etc., in runtime (not all warnings
  eliminated, though)
/* signal-util.c
 *
 * COPYRIGHT (c) 1995 by AT&T Bell Laboratories.
 *
 * System independent utility routines for supporting signals and
 * software polling.
 */

#include <stdio.h>
#include "ml-base.h"
#include "ml-limits.h"
#include "ml-state.h"
#include "vproc-state.h"
#include "ml-objects.h"
#include "ml-signals.h"
#include "system-signals.h"


/* ChooseSignal:
 *
 * Choose which signal to pass to the ML handler and setup the ML state
 * vector accordingly.
 * WARNING: This should be called with signals masked to avoid race
 * conditions.
 */
void ChooseSignal (vproc_state_t *vsp)
{
    ASSERT(vsp->vp_numInQ > 0);

  /* record the signal and count */
    vsp->vp_sigCode = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].sigNum;
    vsp->vp_sigCount = vsp->vp_pendingSigQ[vsp->vp_nextPendingSig].count;
    if (IS_SYSTEM_SIG(vsp->vp_sigCode))
	vsp->vp_numPendingSysSigs -= vsp->vp_sigCount;
    else
        vsp->vp_numPendingSigs -= vsp->vp_sigCount;

  /* advance the pending queue */
    if ((--vsp->vp_numInQ == 0) || (++vsp->vp_nextPendingSig == NUM_SIGS))
	vsp->vp_nextPendingSig = 0;

#ifdef SIGNAL_DEBUG
SayDebug ("ChooseSignal: sig = %d, count = %d\n",
vsp->vp_sigCode, vsp->vp_sigCount);
#endif

} /* end of ChooseSignal */


/* EnqueueSignal:
 *
 * Add a signal to the pending queue; if the signal is already present, then
 * bump its count.
 */
void EnqueueSignal (vproc_state_t *vsp, int sigCode)
{
    int		i, j;

#ifdef SIGNAL_DEBUG
SayDebug("EnqueueSignal: numInQ = %d, sig = %d\n", vsp->vp_numInQ, sigCode);
#endif

    ASSERT(vsp->vp_numInQ >= 0);

    for (i = vsp->vp_nextPendingSig, j = vsp->vp_numInQ;  --j >= 0; ) {
	if (vsp->vp_pendingSigQ[i].sigNum == sigCode)
	    break;
	if (++i == NUM_SIGS) i = 0;
    }
    if (j < 0) {
	vsp->vp_pendingSigQ[i].sigNum = sigCode;
	vsp->vp_pendingSigQ[i].count = 1;
	vsp->vp_numInQ++;
    }
    else
	vsp->vp_pendingSigQ[i].count++;

} /* end of EnqueueSignal */


/* MakeResumeCont:
 *
 * Build the resume continuation for a signal or poll event handler.
 * This closure contains the address of the resume entry-point and
 * the registers from the ML State.
 *
 * At least 4K avail. heap assumed.
 */
ml_val_t MakeResumeCont (ml_state_t *msp, ml_val_t resume[])
{
  /* allocate the resumption closure */
    ML_AllocWrite(msp,  0, MAKE_DESC(10, DTAG_record));
    ML_AllocWrite(msp,  1, PTR_CtoML(resume));
    ML_AllocWrite(msp,  2, msp->ml_arg);
    ML_AllocWrite(msp,  3, msp->ml_cont);
    ML_AllocWrite(msp,  4, msp->ml_closure);
    ML_AllocWrite(msp,  5, msp->ml_linkReg);
    ML_AllocWrite(msp,  6, msp->ml_pc);
    ML_AllocWrite(msp,  7, msp->ml_exnCont);
    ML_AllocWrite(msp,  8, msp->ml_varReg);
    ML_AllocWrite(msp,  9, msp->ml_calleeSave[0]);
    ML_AllocWrite(msp, 10, msp->ml_calleeSave[1]);
    ML_AllocWrite(msp, 11, msp->ml_calleeSave[2]);

    return ML_Alloc(msp, 11);

} /* end of MakeResumeCont */


/* MakeHandlerArg:
 *
 * Build the argument record for the ML signal handler.  It has the type
 *
 *   val sigHandler : (int * int * unit cont) -> 'a
 *
 * The first argument is the signal code, the second is the signal count and the
 * third is the resumption continuation.  The ML signal handler should never
 * return.
 * NOTE: maybe this should be combined with ChooseSignal???
 */
ml_val_t MakeHandlerArg (ml_state_t *msp, ml_val_t resume[])
{
    ml_val_t	resumeCont, arg;
    vproc_state_t *vsp = msp->ml_vproc;

    resumeCont = MakeResumeCont(msp, resume);

  /* allocate the ML signal handler's argument record */
    REC_ALLOC3(msp, arg,
	INT_CtoML(vsp->vp_sigCode), INT_CtoML(vsp->vp_sigCount),
	resumeCont);

#ifdef SIGNAL_DEBUG
SayDebug ("MakeHandlerArg: resumeC = %#x, arg = %#x\n", resumeCont, arg);
#endif
    return arg;

} /* end of MakeHandlerArg */


/* LoadResumeState:
 *
 * Load the ML state with the state preserved in resumption continuation
 * made by MakeResumeCont.
 */
void LoadResumeState (ml_state_t *msp)
{
    ml_val_t	    *contClosure;
#ifdef SIGNAL_DEBUG
SayDebug ("LoadResumeState:\n");
#endif

    contClosure = PTR_MLtoC(ml_val_t, msp->ml_closure);

    msp->ml_arg			= contClosure[1];
    msp->ml_cont		= contClosure[2];
    msp->ml_closure		= contClosure[3];
    msp->ml_linkReg		= contClosure[4];
    msp->ml_pc			= contClosure[5];
    msp->ml_exnCont		= contClosure[6];
    msp->ml_varReg		= contClosure[7];
    msp->ml_calleeSave[0]	= contClosure[8];
    msp->ml_calleeSave[1]	= contClosure[9];
    msp->ml_calleeSave[2]	= contClosure[10];

} /* end of LoadResumeState */


/* GCSignal:
 *
 * Record a garbage collection signal (if enabled).  Return true, if a signal
 * was recorded.
 */
bool_t GCSignal (vproc_state_t *vsp)
{
    if (vsp->vp_gcSigState == ML_SIG_ENABLED) {
	vsp->vp_numPendingSigs++;
	EnqueueSignal (vsp, RUNSIG_GC);
	return TRUE;
    }
    else
	return FALSE;

} /* end of GCSignal */


root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0