Archive for July, 2008

Not seeing the code right in front of your eyes

Thursday, July 24th, 2008

I’m in the process of making PLT Scheme multiprocessor/multi os thread aware.
Everyone knows that globals are the arch enemy of multiprocessor code. Needless to say, PLT Scheme has plenty of globals from is origin as a single processor/single os thread app.

One such global is called kernel_modidx ( the plt scheme kernel module index )
There is some init code that sets these globals.


REGISTER_SO(kernel_symbol);
REGISTER_SO(kernel_modname);
REGISTER_SO(kernel_modidx);
kernel_symbol = scheme_intern_symbol("#%kernel");
kernel_modname = scheme_intern_resolved_module_path(kernel_symbol);
kernel_modidx = scheme_make_modidx(scheme_make_pair(quote_symbol, scheme_make_pair(kernel_symbol, scheme_null)), scheme_false, kernel_modname);

As you can see kernel_modname includes the kernel_symbol, kernel_modidx includes the kernel_symbol and the kernel_modname. This is very important for things to work later.

You would think that calling this init code twice would work the same way the second time as it did the first. It took me two days to hunt down why it doesn’t.

Taking a look at scheme_make_modidx you will see the special case that if kernel_modidx is defined that scheme_make_modidx will not make a new modidx, but will return the old one.

Its not that obfuscated, I just missed it the first thousand times I stepped through the code.


Scheme_Object *scheme_make_modidx(Scheme_Object *path,
Scheme_Object *base_modidx,
Scheme_Object *resolved)
{
Scheme_Modidx *modidx;

if (SCHEME_MODNAMEP(path))
return path;

if (SCHEME_PAIRP(path)
&& SAME_OBJ(SCHEME_CAR(path), quote_symbol)
&& SCHEME_PAIRP(SCHEME_CDR(path))
&& SAME_OBJ(SCHEME_CADR(path), kernel_symbol)
&& SCHEME_NULLP(SCHEME_CDR(SCHEME_CDR(path)))
&& kernel_modidx)
return kernel_modidx;