Bart Veer wrote:
"Jifl" == Jonathan Larmour <[email protected]> writes:<snip>>> Jifl, is there a preferred way to ensure initialisation of the>> stdio streams in the file descriptor table? I note that open() >> in the file I/O package uses:>> >> CYG_REFERENCE_OBJECT(stdin);>> CYG_REFERENCE_OBJECT(stdout); >> CYG_REFERENCE_OBJECT(stderr);>> >> Is this addressing the same issue that we're observing with>> uSTL? Jifl> I think there's a more fundamental problem, not specific to Jifl> uSTL (so I think Uwe's workaround isn't really appropriate). Jifl> That is that something like: Jifl> write(STDOUT_FILENO, buf, n); Jifl> can't be guaranteed to just work, at present. That's a bug. Jifl> I think those CYG_REFERENCE_OBJECT lines (and surrounding Jifl> ifdef) need to move out of open() and into cyg_fd_init(). Jifl> Theoretically cyg_fp_get() would be slightly better, but Jifl> that is called a lot, and there is a trivial but non-zero Jifl> overhead to CYG_REFERENCE_OBJECT. I'd appreciate Nick's Jifl> opinion on this proposal if possible though. It does mean Jifl> that including the fileio package at all in a configuration Jifl> would then guarantee pulling in stdin/stdout/stderr, even Jifl> irrespective of use. Maybe the number of people this would Jifl> affect is too small to care about. Maybe there should be a Jifl> default-enabled option, to allow it to be turned off to Jifl> remove that dependency. Jifl> Taking the usual principle of "leave it to the user", I Jifl> think I'd personally lean towards the latter. I think there is another approach which might fit in better with linker garbage collection. Instead of #define'ing STDOUT_FILENO as 1, declare it as an extern const char. Then provide the variable STDOUT_FILENO in some module which causes the necessary initialization to happen. It is slightly more expensive: a bit of space for the const variable, an extra memory access for the write() call. However it would eliminate the need for CYG_REFERENCE_OBJECT's and it would allow linker garbage collection to work as normal. Obviously code which uses write(1, buf, n) would still be broken, and http://www.opengroup.org/onlinepubs/009695399/basedefs/unistd.h.html requires that STDOUT_FILENO be defined as 1. Hence my proposal would not be fully standards-compliant.
While that's an interesting workaround, I think your last paragraph is the killer, chiefly because I think write(1, buf, n) should still be able to work. *However*, maybe the config option could instead be between standards compliant mode, and "not quite right, but may often still work" mode.
Unfortunately we have another problem. I've looked at the output of our recent compilers, and I see that CYG_REFERENCE_OBJECT no longer appears to be effective :-(. The reference gets removed by more aggressive compiler optimisation at -O2. This is a much wider problem than just stdin/out/err of course.
Solving that efficiently may be difficult (although I don't consider the current implementation to necessarily be efficient either, when it worked, anyway). Managing to get the reference into .text/.rodata would probably be better than .data/.bss. Even better would be if it were possible to play tricks to get it into a non-loadable section, although that starts to venture into the world of HAL-specific stuff. I see a .comment section though. Something along those lines might work (and by overridable by specific HALs if needed).
But I've experimented (admittedly briefly) and not got as far as even making the reference. I've tried using various attributes, nested functions, volatiles, embedding asm(".word " #__object__ ";"), etc. It may be that we can only do this properly using HAL-specific inline asm :-(. The least worst idea I've had which actually creates a reference is to have a real function cyg_reference_object(void*) and call it with the address of the object to reference, but which returns immediately.
Any other ideas? At least there are not many uses of CYG_REFERENCE_OBJECT. Jifl -- --["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
