[M3devel] RC merge

Jay K jay.krell at cornell.edu
Sun Sep 13 20:02:24 CEST 2009


 > The Id type and MyId function is simply a convenience

But what do we do about it?
It is out there and being used.
It ought not have been, but it was and is.

The safety hole SetCurrentHandlers(WhateverState()) was also out there as I understand.

Should break the existing users?
And/or move MyId to Thread.i3?
Or ThreadFSafe.i3?

I really don't think the way it was is the best choice.
At the very least, ThreadF should either be interface instead of Interface and/or UNSAFE.
But those options have the collateral damage of breaking users of ThreadF.MyId.
I chose a route that doesn't have that damage and contains any churn to within m3core.

 - Jay

From: hosking at cs.purdue.edu
To: jay.krell at cornell.edu
Date: Sun, 13 Sep 2009 13:43:48 -0400
CC: mika at async.async.caltech.edu; m3devel at elegosoft.com
Subject: Re: [M3devel] RC merge

Safe code can't do anything with a value of type ADDRESS except pass it around.  It must use unsafe operations (NARROW) to turn it into something usable.
I think you misunderstood ThreadF in the first place.  It has always been logically unsafe, if not UNSAFE.  I don't want ThreadF ever to come to be something that people outside the runtime system rely on.  The Id type and MyId function is simply a convenience, but not and never has been part of the standard interfaces.
Can we please just revert back to the way it has always been? 
On 13 Sep 2009, at 09:51, Jay K wrote:The functions are meant to be unsafe either way.
ThreadF.i3 clearly had a safety hole before, but not due to the functions "in question".

Good point about passing in ADDRESSes..but I'm not entirely sure I understand/agree.
Can safe code ("directly") generate any ADDRESSes at all? Or only get them from
unsafe code in the first place?
ADDRESS only comes from ADR, right? And ADR isn't allowed in safe? I'll check.

IF safe code CAN generate ADDRESSes, then this was a hole:
PROCEDURE SetCurrentHandlers(h: ADDRESS);

and perhaps these:
PROCEDURE SuspendOthers ();
(* Suspend all threads except the caller's *)

PROCEDURE ResumeOthers ();

Though probably not the second, since safe code can trivially hang/deadlock on its own.

The public safe ThreadF.i3 now just:

(*-------------------------------------------------- showthreads support ---*)

TYPE
  State = {
        alive    (* can run *),
        waiting  (* waiting for a condition via Wait *),
        locking  (* waiting for a mutex to be unlocked *),
        pausing  (* waiting until some time is arrived *),
        blocking (* waiting for some IO *),
        dying    (* done, but not yet joined *),
        dead     (* done and joined *)
    };

(*-------------------------------------------------------------- identity ---*)

TYPE
  Id = INTEGER;

PROCEDURE MyId(): Id RAISES {};
(* return Id of caller *)


Everything else I moved to the non-public ThreadInternal.i3.


> But in Modula-3 whether an interface is unsafe or not *is* a boolean.

Understood, but I still think even in unsafe code, LOOPHOLE should be minimized.
C and C++ programmers are often taught to minimize casts, esp. reinterpret_cast.
I think that guidance carries over to Modula's LOOPHOLE, even if you are already unsafe
for other reasons.

 - Jay


> To: jay.krell at cornell.edu
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] RC merge 
> Date: Sun, 13 Sep 2009 02:44:50 -0700
> From: mika at async.async.caltech.edu
> 
> Jay K writes:
> ...
> >
> >Imagine you are a somewhat prolific fairly happy C or C++ programmer. The w=
> >hole world is unsafe=2C but recieves a fair amount of static checking and i=
> >s therefore largely correct and perhaps doesn't even suffer much from the l=
> >ack of safety.
> >
> >=20
> >
> > void* GetFoo(void)=3B=20
> >
> > void* GetBar(void)=3B=20
> >
> >=20
> >
> >or
> >
> >=20
> >
> > Foo_t* GetFoo(void)=3B=20
> >
> > Bar_t* GetBar(void)=3B=20
> >
> >=20
> >
> >?
> >
> >=20
> >
> >Definitely the second.
> >
> >=20
> >
> >Perhaps perhaps perhaps perhaps a function should be able to be declared to=
> > return an UNTRACED REF Foo.Something=2C without actually importing Foo or =
> >defining Something?
> >
> >=20
> >
> >Clearly the safety of an /interface/ is more subtle than a boolean.
> >
> >Some functions may be safe and others unsafe.
> >
> >Even some uses of functions.
> >
> >Imagine for example:
> >
> >=20
> >
> >PROCEDURE GetFoo(): UNTRACED REF Foo.Something=3B
> >
> >=20
> >
> >Perhas a safe function could call this function=2C as long as it only compa=
> >res the return value to NIL?
> >
> >Actually storing it in a variable would require IMPORT Foo=2C and if FOO is=
> > declared UNSAFE=2C then that would
> >
> >pollute the caller. Or maybe merely declaring a variable of UNTRACED is eno=
> >ugh to wreck safety?
> 
> But in Modula-3 whether an interface is unsafe or not *is* a boolean.
> It's very clearly defined what it means in the Green Book.
> 
> If you don't declare your GetFoo as UNSAFE you can write
> 
> VAR x := GetFoo; BEGIN (* manipulate fields of x *) END
> 
> in safe code.
> 
> Declaring GetFoo to return ADDRESS won't let you do that. Hence,
> it's safer, if there's a safety problem with manipulating the fields.
> 
> An interface can hardly assume that it is the only one injecting objects
> of type ADDRESS into the "safe world" so if you're allowing the safe world
> to pass these objects back in your interface you have to sanity-check
> them anyhow. You do not, however, need to worry about the fields having
> been changed by the safe code.
> 
> If you need some more subtle properties than that you probably ought
> to be writing UNSAFE code in the first place. Or is there some trickery
> you can do along the lines of what we came up with for small integers
> in pointers?
> 
> Mika

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090913/30461461/attachment-0002.html>


More information about the M3devel mailing list