[M3devel] darwin-generic waitpid?

Jay jay.krell at cornell.edu
Wed Dec 31 05:32:25 CET 2008


Tony, Hi, sorry, I'm a little confused.

Beware C wrappers -- don't write them.
That's what it sounded like at first.
 
Or:
Beware C wrappers -- be careful writing them.
?
 
On the second, well, yeah, ok.

I haven't actually yet improved much -- since I stick to "new" ports.
"Soon" I might take larger steps.
I'll probably first cave and add user thread support to {PPC,AMD64,SPARC{32,64}}_LINUX, I386_SOLARIS, *_OPENBSD, etc., while continuing to minimize or eliminate header clones.
And then maybe move LINUXLIBC6 to linux-common/common.
 
 
I should say..um..IF your concern is just "be careful writing C code"...
I wonder how far I should go.
I'm obessive.
I keep looking at linux-common/openbsd-common/cygwin and I wonder what I can remove.
And how.
 
 
Removing unused stuff, easy.
Wrapping functions that actually are functions, not too bad.
 
 
But types and constants..you can try to write functions to take over all their uses, but I don't think that will do for all of them. For example, struct flock I removed.
 
 
 
The "worst" cases are probably:
  Uerrno 
  Upthread 
 
 
In particular, these are the files for which C wrapping is likely to do the "most damage" with respect to efficiency and code structure. Uerrno..the way to wrap it in C is, well..one thing I do NOT want to do is go through and make up our own errno values and map back and forth everywhere. Yuck. However, one thing that seems half reasonable is to have GetEAGAIN(), GetEINVALID(), GetENOMEM(), etc. or a bulk struct { int EINVAL, ENOMEM, etc. } * GetErrnoValues(). The second version is "less chatty" but risky, like if the struct gets copied and changes size through time (versioning). The first is much safer. In both cases, the errors loses their const-ness and you can, I assume, no longer switch/case on them.
 
 
Now, error checking..efficiency..probably ok -- code that is dealing with errors doesn't have to be fast. Change the switches/cases to if/elseif/elseif ladders. I think I will do this.
 
 
Upthread, here I think part of the answer is that all of the functions have identical prototypes.
So "half" the file just goes to Common and done, no C wrapping.
That leaves the types.
sem_t, which is vaguely related, there is just one of. I think we can just declare that variable in C, since you don't like the over allocation/alignment.
But that's an unusual benefit -- something there is only one of.
 
 
For types that are created repeatedly..well, it depends. I have to look into the allocator interface.. if the objects are heap allocated, one thing you can maybe do is like:
 
 
RTAllocator(Upthread.GetSize_rwlock(), Upthread.GetAlign_rwlock()).
 
Assuming size and alignment are parameters, or assuming that alignment is always maximal.
 
 
If the objects are stack allocated, well, that breaks down.
You /could/ heap allocate them always, but that's a sort of inefficiency I'm reluctant to introduce. I don't mind turning constants, esp. seldom used ones, into function calls, or copying small structs (stat), but turning stack allocation into heap allocation, yuck.
 
 
Another answer is to leave these alone.
Generate Uerrno.i3 from Uerrno.i3.cpp and leave it that.
Maybe generate them as a matter of course in any /native/ build and compare to the "checked in" copy. Well, um, native builds also benefit from being able to run tests, so you can accomplish the same thing there -- pass the constants, type sizes, etc. to C code that asserts equivalence.
 
 
Upthread.i3 could be similar.
To address the types vs. prototypes, I'd say move the types, and probably all the initializers, into a per-system Upthreadtypes.i3, or Usysdep.i3.
 
 
Usocket.i3 is similar -- identical prototypes, but constants vary.
Move the constants into "Usysdep.i3"? Or use accessor functions?
 
 
I have to look at the code more besides.
I don't have a plan.
 
Anyway, at the very least, we have:
 
jay at ppca:/dev2/cm3/m3-libs/m3core/src/unix$ wc -l linux-common/*.i3
  415 total
 
openbsd-common => 516
 
wc -l linux-libc6/*.i3
 
4011
 
Not bad to be at 10%, and user threads won't regress all that much.
Maybe stop there?
Well, Uutsname.i3 is probably going away. It has just one user.
 

 - Jay


----------------------------------------
> From: hosking at cs.purdue.edu
> To: jay.krell at cornell.edu
> Date: Wed, 31 Dec 2008 11:47:48 +1100
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] darwin-generic waitpid?
>
> Sure, I understand. I think what you are doing is great for improving
> the reliability of the C-interface code. Are you able to test all the
> platforms? I am worried we are going to have bugs introduced that
> someone (you!) will need to chase down.
>
> On 31 Dec 2008, at 11:09, Jay wrote:
>
>>
>> I'd like to avoid cloning any headers, and use clear portable C
>> wrappers to bridge between Modula-3 and stuff written/declared in C.
>> e.g. no bit fields.
>>
>> These are contrary goals.
>>
>> Or, at least, only clone headers that are essentially identical
>> across all Posix platforms, or which the only variables are
>> endianness and word size.
>>
>> There are a few possible compromises.
>> Currently there is linux-common, openbsd-common.
>> I would NOT like to add netbsd-common, freebsd-common, solaris-common.
>> As such, I'm pushing stuff from "*-common" to plain "Common".
>>
>> As well, by not cloning header content that is unused in the cm3
>> tree, much is saved.
>> Compare the number of lines in LINUXLIBC6 vs. linux-common.
>> But I'd like to get further than that.
>>
>> Similarly, not cloning header content that doesn't present a
>> portable interface, which tends to lead to it not being used, since
>> most of the cm3 code is factored only on Posix vs. Win32, and not
>> one Posix superset or another.
>>
>> I also believe that C is "everywhere" and will remain "everywhere".
>> Except very constrained "safe" environments like a web browser or
>> Java-only Google phone, where Modula-3 is about as far as being able
>> to run as C is.
>>
>> I think C wrappers are very preferable to cloning headers.
>>
>> The endian-ness is actually abstracted out in normal C code.
>> There's the various macros for cracking the 32 bit status.
>> Ok, maybe that is apples and oranges. It is abstracted out in the
>> client C code and the client Modula-3 code, except that Modula-3
>> client code uses LOOPHOLE. Both the C headers and Modula-3 headers
>> are "messy", the C headers sometimes more so, such as to cater to
>> other (BSD) interfaces.
>>
>> I realize there are the Win32 headers to be concerned with as well.
>>
>> - Jay
>>
>> ----------------------------------------
>>> From: hosking at cs.purdue.edu
>>> To: jay.krell at cornell.edu
>>> Date: Wed, 31 Dec 2008 10:47:46 +1100
>>> CC: m3devel at elegosoft.com
>>> Subject: Re: [M3devel] darwin-generic waitpid?
>>>
>>> On 30 Dec 2008, at 18:51, Jay wrote:
>>>
>>>>
>>>> It looks like waitpid's output is endian-dependent, and that
>>>> therefore darwin-generic is wrong on some architectures, asis linux-
>>>> common and openbsd-common.
>>>>
>>>>
>>>> I expect to fix this shortly, by replacing all the Modula-3 result
>>>> bitfields with uint8_t and
>>>> having a C wrapper do the translation.
>>>
>>> I am concerned that so much C wrapper stuff is starting to creep in.
>>> I want to be able to see the endianness in the Modula-3 code, not
>>> have
>>> it squirrelled away in C code. What if I don't have a C compiler?
>>> Jay, please be careful with your assumptions about platforms always
>>> having C.
>>>
>>>> As well, for increased portability, the flags will be input uint8_t
>>>> fields in the record, rather than platform-dependent flags.
>>>>
>>>>
>>>> - Jay
>>>
>


More information about the M3devel mailing list