[Date Prev][Date Next][Thread Prev][Thread Next][Author Index][Date Index][Thread Index]

[Mailer-Daemon: Returned mail: User unknown]



Consider this for Xanatech.  I don't know what went wrong.


Return-Path: <Mailer-Daemon>
Date: Sun, 1 Oct 89 17:59:43 PDT
From: Mailer-Daemon (Mail Delivery Subsystem)
Subject: Returned mail: User unknown
To: mark

   ----- Transcript of session follows -----
550 xanatech... User unknown
550 User unknown

   ----- Unsent message follows -----
Return-Path: <mark>
Received: by xanadu.xanadu.uucp (4.0/SMI-4.0.2) id AA07720; Sun, 1 Oct 89 17:59:43 PDT
Date: Sun, 1 Oct 89 17:59:43 PDT
From: mark (Mark S. Miller)
Message-Id: <8910020059.AA07720@xxxxxxxxxxxxxxxxxx>
To: heh
Cc: tribble, xanatech
In-Reply-To: Hugh Hoover's message of Sun, 1 Oct 89 16:24:44 PDT <8910012324.AA07016@xxxxxxxxxxxxxxxxxx>
Subject:  possible garbage collector problem...

   Date: Sun, 1 Oct 89 16:24:44 PDT
   From: heh (Hugh Hoover)

   ...
   TYPE foo=g(x);
   f(foo);

   ...

   I think that this would only be a problem with relatively uncontrolled task
   switching, or if f(x) caused a gc to occur before ensuring the object will
   stay around.

I think this is a serious problem even in the abscence of pre-emptive
task switching, but this example doesn't demonstrate the problem.  The
reason is that in the above example, the temporary should be
considered a Wimpy pointer, but the parameter of f can be declared to
be a Strong pointer.  In this case, in the abscence of pre-emption,
all will be well.  However, try:

{
    f (g(x), h(x));
}

This probably expands into something like:

{
    TYPE foo = g(x);
    TYPE bar = h(x);
    f (foo, bar);
}

The problem occurs during the call to h(x).  h(x) may do new
allocation, causing more garbage collection, while g(x)'s return value
is held onto only by a Wimpy pointer.  This shows that, even in the
absence of pre-emption, we need to take temporaries seriously in our
Wimpyness constraint: "It is ok to wimpily point at an object ONLY if
you know that object is non-garbage by virtue of strong pointers.".  I
suggest we try the following: What if both "g" and "h" were declared
as returning Strong pointers (not references to strong pointers)?  My
reading of the language definition is that the foo and bar temporaries
generated as above would then be Strong pointers, and all would be
well.  I'll try this out soon and let you know.

     For the first case, my interpretation of KeyTalk++ (our tasking model), is
   that it is not pre-emptive - and therefore shouldn't be a problem (right MarkM?)

Sorry.  The Key++ (as opposed to KeyTalk (there is no KeyTalk++))
scheduling model doesn't specify either pre-emptive or non-preemptive
scheduling.  It is expected to be one way on some platforms and the
other way on others.  Therefore, Key++ programs may not make
assumptions either way.  If we went non-pre-emptive, we would be
unable to take advantage of multi-processing hardware.  On the other
hand it might be hard to get real preemption under some operating
systems, but we can always co-routine.  If we do have to make an
eventual choice, I'd go for pre-emption always.

However, we are certainly going for Beta without either kind of
scheduling, and almost certainly going for first product without it as
well.  In many ways, we can make our code inconsistent with scheduling
(or pre-amptive scheduling), and fix it when we need to.  It would be
good to have these cases clearly marked.

However squared, garbage collectable pointing relationships are
probably not one of those cases.  Let's try to get this one right the
first time, because fixing this one later will be a real bitch.  A
valid counter-argument would be some way of automatically & statically
spotting the problem areas when we need to.  If we could do this
reliably, we could just make do with non-schedulable code the first
time.

Note that there have been repeated attempts to upgrade both Smalltalk
& Interlisp to pre-emptive scheduling over the years, but no-one ever
succeeded in spotting enough of the problem areas in the existing body
of code to fix them.

     There's a similar problem on the Mac, where an object may be moved in memory
   during allocation.  The Pascal compiler helps by flagging statements that
   pass addresses rather than handles.  This occurs when a field of an object
   is passed rather than the object itself.  (This occurs frequently when calling
   Mac Toolbox stuff)  The upshot is that there is a lot of defensive programming
   to ensure parameters will stay put.

This is the kind of automatic & static check I'm refering to.  Is this
something a future XLint could check for?  Would it be sufficient?
Note that XLint won't actually have to do this for a long time.  It'd
just be good to know that it could.