Shock horror an actual post about liblfds.
I’ve been working on the test application.
With the additon of position independent data structure variants, I need to be able to spawn processes and use shared memory, for testing.
I have a number of platforms to think about, to form an abstraction layer over;
There’s also kernel mode to think about, but kernels don’t have processes as such, and so they don’t have shared memory as such. I do in principle want to test user-mode and kernel-mode code executing concurrently on the same data structure instance, but then I’ll need to really actually make something work in the kernel for both Windows and Linux. I’m familiar with Windows kernel programming, so I could do that (install a driver, then the test app communicates with it), but I’m not familiar with Linux kernel programming (I’ve a kbuild build of liblfds, but it’s not *used* in anything; I have no idea if it’s a valid build) so these aren’t on the cards right now.
Shared memory is pretty much identical across Windows and Linux so that’s no problem.
No clue how it works on Android – Googling shows up various Java APIs – hopefully Linux under the covers.
Embedded platforms don’t have processes, well, they have one process, *the* process, so no shared memory.
Where embedded doesn’t offer processes or shared memory, the test app needs to run differently on different platforms, or, rather, depending on what’s available in the platform abstraction layer; position independent tests only happen if there’s support for shared memory and processes.
A weaker form of position independent testing is available just by running them in the same address space, over multiple threads, so that might be something which happens if processes/shared are not available.
Then we come to processes.
Process are completely different between Linux and Windows.
Linux uses fork(). You call fork, and then you have two processes, and they each get a different return value from fork.
Windows uses CreateProcess, which takes a *pathname to an executable*, and spawns a new process running that executable. Parent and child by default have rights to access each others memory, child can inherit handles, etc.
These two things really are *not* the same.
Consider my use case; I want to spawn one process per logical core, have it open up a block of shared memory, and then, when everyone is ready (I’ll spinlock on a value in the shared memory) run a particular test.
One problem to begin with is that the design of libtest is based around threads; a “test” is a function which inits a threadset, and that spawns threads which are given a function pointer to the test code. This needs now to be a processset, not a threadset; this wouldn’t be too bad under Linux – but under Windows, to make a process, I have to give a *pathname* to an executable! and that means, if I want just one test binary (and I do), I need to invoke the test binary *with command line arguments such that it knows what to do and will participate in the test which should now be run*.
This is nuts. Invoking new processes should not involve work on the command line parser.
I can get around a bit I suppose by having just one special command line argument, which tells the test programme to open up shared memory and get its instructions from there.