Usermode and processes.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
eXeCuTeR
Member
Member
Posts: 63
Joined: Tue Dec 09, 2008 12:43 pm

Re: Usermode and processes.

Post by eXeCuTeR »

pcmattman wrote:
eXeCuTeR wrote:
pcmattman wrote: (we actually have up to 16 kernel stacks per thread, one for each level of nesting, to avoid stack corruption).
Level of nesting? what do you mean?
Slightly difficult concept to explain... :)

Basically, when an event is sent to a thread, that thread is automatically interrupted. This is sort of like an IRQ firing, except local to a thread (events are, essentially, a form of IPC - this is not entirely true, but simplifies the explanation). Because the thread can be interrupted at any time, its context must be saved somewhere. We allow threads to be interrupted even while handling events - so we can't just have a dedicated "event stack".

When an event is dispatched to a thread, the thread's old context is saved onto its current stack. For this example, this is at nesting level 1. The nesting level is incremented to 2, and execution of the event begins. If another event is dispatched to the thread, the context is saved onto the current stack (which is now the second nesting level stack) and the nesting level is incremented to 3.

As each event finishes being handled, the nesting level is reduced by one and the previous context is restored.

The idea is that interrupts and further events (and even ring3/ring0 transitions) don't corrupt the kernel stack for a thread. This is our solution to one of our bigger stack corruption bugs.
Thanks!
So I have 2 questions:
1. How can you determine the maximum level of nesting? you just define a specific maximum level of nsting and create kernel stacks correspondingly for each process?
2. Why not define events as IPC? and BTW, you refer to events as signals?

p.s: Sorry for lousy English; If something isn't clear, let me know.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Usermode and processes.

Post by pcmattman »

1. How can you determine the maximum level of nesting? you just define a specific maximum level of nsting and create kernel stacks correspondingly for each process?
We have a hard limit that's basically a #define - no new stacks are allocated for nesting levels above that limit. The stacks are allocated on-demand too, so if you only ever use nesting level 0 there won't be 15 other stacks being unused (for performance, once a stack is allocated, it's kept at that nesting level until the thread is killed even if it's no longer in use).
2. Why not define events as IPC? and BTW, you refer to events as signals?
We do use the event system for signals in the POSIX subsystem... but we also have worked hard to keep as much POSIX out of the kernel as possible. The semantics of events are also different to conventional POSIX signals. Naming them "signals" when they don't work anything like POSIX signals is misleading and confusing.
eXeCuTeR
Member
Member
Posts: 63
Joined: Tue Dec 09, 2008 12:43 pm

Re: Usermode and processes.

Post by eXeCuTeR »

pcmattman wrote:
1. How can you determine the maximum level of nesting? you just define a specific maximum level of nsting and create kernel stacks correspondingly for each process?
We have a hard limit that's basically a #define - no new stacks are allocated for nesting levels above that limit. The stacks are allocated on-demand too, so if you only ever use nesting level 0 there won't be 15 other stacks being unused (for performance, once a stack is allocated, it's kept at that nesting level until the thread is killed even if it's no longer in use).
2. Why not define events as IPC? and BTW, you refer to events as signals?
We do use the event system for signals in the POSIX subsystem... but we also have worked hard to keep as much POSIX out of the kernel as possible. The semantics of events are also different to conventional POSIX signals. Naming them "signals" when they don't work anything like POSIX signals is misleading and confusing.
Yeah, figured that it'll be on-demand, no reason else.

Hmm, so signals are basically POSIX and events are not? I can't really see a difference between them. Mind explaining?
And just to verify (pretty much relates to my last question) - Can one have in one kernel also signal manager and an event manager or it'll be just stupid since they both represent same concept?
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Usermode and processes.

Post by pcmattman »

Hmm, so signals are basically POSIX and events are not? I can't really see a difference between them. Mind explaining?
In our OS, POSIX signals build upon the event system - the event system isn't built around POSIX signals. The actual mechanism for POSIX signals in Pedigree is actually quite hacky because it's built on the event system.

Events support serialisation of C++ class data that's able to be deserialised on the other side, and how that data is interpreted is completely up to the protocol. The "POSIX signal" event encodes the signal number in that serialised data, for example. AFAIK the equivalent in POSIX is some form of IPC? I'm not too sure though.

At the most basic level though, events interrupt context, and signals interrupt contexts. So in that sense there is no difference.
And just to verify (pretty much relates to my last question) - Can one have in one kernel also signal manager and an event manager or it'll be just stupid since they both represent same concept?
Depends at what level each manager is abstracted.

In Pedigree, the "POSIX signal" stuff sits in our POSIX subsystem, which is an optional module. Obviously much of our current userspace depends on the POSIX subsystem, but it is possible to have a build of Pedigree that runs without actually including the POSIX subsystem. The "Event" stuff sits in the kernel proper and is available for use in every different subsystem: native, POSIX, etc... I can develop my own libraries and run applications without ever touching POSIX because there's a distinct separation.

It really is a design thing: whether you decide to make stuff like POSIX modular or a definite part of the system will directly affect how you implement these things, and whether you do need to separate POSIX signals from "kernel events".
eXeCuTeR
Member
Member
Posts: 63
Joined: Tue Dec 09, 2008 12:43 pm

Re: Usermode and processes.

Post by eXeCuTeR »

pcmattman wrote:
Hmm, so signals are basically POSIX and events are not? I can't really see a difference between them. Mind explaining?
In our OS, POSIX signals build upon the event system - the event system isn't built around POSIX signals. The actual mechanism for POSIX signals in Pedigree is actually quite hacky because it's built on the event system.

Events support serialisation of C++ class data that's able to be deserialised on the other side, and how that data is interpreted is completely up to the protocol. The "POSIX signal" event encodes the signal number in that serialised data, for example. AFAIK the equivalent in POSIX is some form of IPC? I'm not too sure though.

At the most basic level though, events interrupt context, and signals interrupt contexts. So in that sense there is no difference.
And just to verify (pretty much relates to my last question) - Can one have in one kernel also signal manager and an event manager or it'll be just stupid since they both represent same concept?
Depends at what level each manager is abstracted.

In Pedigree, the "POSIX signal" stuff sits in our POSIX subsystem, which is an optional module. Obviously much of our current userspace depends on the POSIX subsystem, but it is possible to have a build of Pedigree that runs without actually including the POSIX subsystem. The "Event" stuff sits in the kernel proper and is available for use in every different subsystem: native, POSIX, etc... I can develop my own libraries and run applications without ever touching POSIX because there's a distinct separation.

It really is a design thing: whether you decide to make stuff like POSIX modular or a definite part of the system will directly affect how you implement these things, and whether you do need to separate POSIX signals from "kernel events".
I think I got it - you actually mean that signals are just a way of IPC and that is wrapped by the event system (=event system just holds generic callbacks to could handle different event types, like signals for instance) - well, basically signals represent one type of event. Also, if I got you right, what other type of events are you fimiliar with?

Should I create a special system call for sending signals? e.g: whenever a process finishes executing, it invokes a system call with SIG_CHLD in one of the registers, so the handler of this system call changes the state of the parent process (child will also pass the process id of parent in one of the registers), or how else could it be done?
In fact, I already got 0x80 interrupts designed for users in the IDT entry, and I seperate each system call with a unique identifier stored in EAX. I could just create a new identifier for signals. Is this a good design?
One more pretty dumb thing I forgot to ask: on a sane system, should all exceptions can be invoked from usermode? e.g: int 3, int 14? common sense tells that only some of them should and some other don't.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Usermode and processes.

Post by pcmattman »

I think I got it - you actually mean that signals are just a way of IPC and that is wrapped by the event system (=event system just holds generic callbacks to could handle different event types, like signals for instance) - well, basically signals represent one type of event. Also, if I got you right, what other type of events are you fimiliar with?
Basically, yes. In Pedigree the event system is also used for:
  • Timeouts: an event is created to interrupt the thread at a specific point in time in the future. This is used for Semaphore/Mutex acquires with timeouts.
  • "select events": Work with the POSIX select system call to notify the select call that a descriptor has changed state
  • Input events: our input manager uses events to notify userspace of keyboard and mouse input
These are specific to our design - there's no real generic answer here.
Should I create a special system call for sending signals? e.g: whenever a process finishes executing, it invokes a system call with SIG_CHLD in one of the registers, so the handler of this system call changes the state of the parent process (child will also pass the process id of parent in one of the registers), or how else could it be done?
This is up to you. If you do this you may as well implement POSIX signal(), raise() and kill() - what you end up doing really depends on your design goals.
One more pretty dumb thing I forgot to ask: on a sane system, should all exceptions can be invoked from usermode? e.g: int 3, int 14? common sense tells that only some of them should and some other don't.
A #PF in Pedigree's userspace sends a "thread needs an unexpected exit" notification to the relevant subsystem, which in the case of POSIX, sends SIGSEGV (the handler for which kills the program). I honestly can't remember what the other interrupts do: I'm pretty sure at the moment they hit the kernel handler and halt the system still.
Post Reply