Hi Ryan,
On 11.05.2012 03:15, Ryan Brown wrote:
Hi. I'm exploring developing software that runs on Fiasco.OC/L4re, so I'm trying to understand how the various pieces fit together. If I'm following the makefiles correctly it looks like some uclibc files (like libc/inet) are getting compiled, but they seem to be making linux system calls.
Note, that not all files in uClibC are built. Instead, we only compile a subset that is semi-magically determined by the list in l4/pkg/uclibc/lib/uclibc/contrib_files.mk. Basically, you can distinguish two classes of files:
a) files that don't have dependencies on the underlying system or platform -- those are taken from the original uClibC sources in l4/pkg/uclibc/lib/contrib
b) files that depend on system calls and other infrastructure (e.g., file systems) -- those either come from our own implementation (l4/pkg/uclibc/lib/uclibc/*) or from the libc_backends package.
Anything related to making system calls falls under category b) and of course uses Fiasco system calls.
I also see the libc_backends code, and I'm not sure how this fits in. It looks like these are mostly stubs, is it expected that you'll link the final binary with the real implementation you want?
There are a couple of backends in l4/pkg/libc_backends. For instance l4/pkg/libc_backends/lib/sig implements POSIX signals on top of L4. You will notice that it uses Fiasco system calls (look for functions starting with l4_*()).
The backend idea is: every backend implements a part of POSIX functionality that depends on the system, such as signals, virtual file systems etc. You then link your application against those backends you need. For instance, if you don't need POSIX signals in your app, there's no need to link against libc_be_signal.
I also took a look at libpthreads, and I don't see much l4 specific code.
That's a feature! We reuse pthread's original functionality instead of building everything from scratch.
It looks like mutexes are implemented as spinlocks?
Not exactly. pthread's mutex implementation tries spinning first and once it finds out that the lock cannot be grabbed immediately, it goes to sleep (see calls to suspend()). That's a pretty reasonable thing to do, because it speeds up the non-contention case by not requiring any system call.
Isn't there a better way to do synchronization in fiasco?
suspend() is implemented using an L4-specific system call (see l4/pkg/uclibc/lib/libpthread/src/restart.h
Cheers, Bjoern