Atomicity
Posted: Tue Sep 09, 2014 6:35 pm
Hi!
A few days ago I posted a question(s) about Memory Management. (which led to a _BIG_ discussion ). I've finally managed to provide basic C code for the VFS, KERNEL, MM, LIB, SYSCALL, ARCH (only i386) submodules of the kernel, with a few drivers compiled inside the kernel. Now I want to go by a modular, multitasking model by starting implementing the Process/Driver manager. My problem is with atomicity.
My #include <lib/def.h> file contains all the kernel's basic defs and REALLY most common utilities, such as UInt32, NULL, or Size. Here, Atomic() is a macro which I should use to make a specific section of code atomic
It's code is:
Now let's see for example my PMContextSwitch() function (in <proc/task.c>):
As you can see, the atomicity here is only a prevention and/or optimization, but it's still an example. Returning to the Atomicity problem, how can I implement _AtomicEnter/Exit(), in x86 for example? I DON'T want to use spinlocks or semaphores, as I think they're too and unneeded. There MUST be a way to do this, probabling doing a CLI, but from then on, my mind is just blank.
A few days ago I posted a question(s) about Memory Management. (which led to a _BIG_ discussion ). I've finally managed to provide basic C code for the VFS, KERNEL, MM, LIB, SYSCALL, ARCH (only i386) submodules of the kernel, with a few drivers compiled inside the kernel. Now I want to go by a modular, multitasking model by starting implementing the Process/Driver manager. My problem is with atomicity.
My #include <lib/def.h> file contains all the kernel's basic defs and REALLY most common utilities, such as UInt32, NULL, or Size. Here, Atomic() is a macro which I should use to make a specific section of code atomic
It's code is:
Code: Select all
/* ArchImplement is a previous #define that marks a symbol as defined by arch-specific code
Note: In my kernel every function used by, and only by a macro internally is preceded by a '_'
*/
ArchImplement void _AtomicEnter();
ArchImplement void _AtomicExit();
/* Make a specific part of code completely atomic and thread-safe
It's hackish (for supporting commas) I know, but it works well :)
The _NE version just doesn't exits the atomicity by itself. This is done
by the Atomic(...) extension if necessary.
*/
#define Atomic_NE(...) AtomicEnter(); __VA_ARGS__;
#define Atomic(...) Atomic_NE(__VA_ARGS__); _AtomicExit();
Code: Select all
/* Arch-independent context switch code. It must be able to change
all machine-specific stuff and process all hackish operations needed
to set user/kernel-space, virtual memory, registers and other things
specific as per process/thread.
volatile void PMContextSwitch(Bool autoSelect, PID pid)
{
/* If autoselect == true, ignore pid and continue the chain. If false, switch to pid */
Process *new = autoselect ? _runningProcess->next : PMGetProcess(pid);
/* ContextSwitch() is an ArchImplement-ish function which (obviously) changes
to another context. ContextSwitch() is responsible for disabling the atomicity as
its final act before the actual far jump. If it fails, a Kernel Panic will ocurr. (An
simple exception message here isn't enough to know how torepair the damage made).
*/
Atomic_NE(
ContextSwitch(new);
);
}