mem_unit
Henry Cejtin
henry@sourcelight.com
Sat, 16 Mar 2002 01:10:52 -0600
I think that thing that link with the new libraries just won't run with the
old ones. The converse is false, but on the other hand the new libraries
might fix some bugs in the old ones. I don't think there really is an
alternative to providing both. At least with Red Hat the combinatorial
explosion isn't quite so bad. The old Red Hat has the older glibc, the older
type of RPM and the older kernel. The newer Red Hats have the reverse. For
other distributions things could be a mix-and-match, but I think that if we
provide both of these (say the old being Red Hat 6.* based (the different
values of * should all be mutually compatible) and the newer one being 7.*
then we should be ok.
As to the mem_unit problem and the different kernels, here is the situation:
The old include files do not have a mem_unit field in the struct, but the
struct has some padding so its size is the same as if it had the extra
fields. This extra padding is zero'd out in the old kernels. Hence you
have:
Compiled with old includes, any kernel:
no mem_unit field.
Compiled with new includes, running on old kernel:
mem_unit will always be 0.
Compiled with new includes, running on new kernel:
mem_unit will be 1 (or bigger on big-memory or big-swap machines).
One option would be to simple include the struct definition in our own
include file (basically from /usr/include/linux/kernel.h of a new kernel).
This way we will ALWAYS have mem_unit defined. The code would then check if
the value was 0 (meaning it is running under an old kernel) and use 1
instead.
The alternative option would be to never have the code do
s.mem_unit
where s was of type `struct sysinfo', but instead to always do
SI_MEMUNIT(s)
Then we would use one of 2 include files: if being compiled on an new
machine, the include file would contain
#define SI_MEMUNIT(s) (s).mem_unit
and if being compiled on an old machine it would contain
#define SI_MEMUNIT(s) ((s), 1)
(The funny right-hand-side is just so that any side effects are handled. It
almost certainly makes no difference, but it is better to be safe and the C
compiler will optimize it away.)
The second approach has several disadvantages: one is that the source code no
longer reflects either option, but a new world, which is a pain to keep
straight. The second disadvantage is that MLton executables made on old
systems will not run properly on big-memory machines running new kernels.
The first solution doesn't suffer from either of these, but has the uglyness
of the struct definition being copied into our source.
For the second solution you would need some kind of configure program to see
which include files you have. This just involves trying to compile something
that refers to the mem_unit member and seeing if it compiles successfully.
Not a big deal, but definitely another minor pain.