unix compatible signals

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.
Post Reply
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

unix compatible signals

Post by durand »

I need to provide support for unix compatible signals in my system and I was wondering if anyone has done this before and has some valuable knowledge and tricks to share with me?

I'm implementing my libUNIX library to provide unix source code compatibility with minimal OS hooks required. So one of my goals while adding signal support is to keep as much logic as possible in the userland library and implement as few OS system calls as is necessary.

So if anyone's done this already, what would you consider the bare requirements of the kernel in order to support signals?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:unix compatible signals

Post by Pype.Clicker »

well, the first thing to know is whether your kernel has a way to interrupt a running thread and to force it to execute some code or not.

If you have something (events/messages mechanism?) that allows such "interrupting", then you're almost ready to implement signals from there (reading the message content, and figuring out that it should be translated into a SIGINT, for instance, and then see in the user-library variables whether you have something registered to handle SIGINTs or if you should instruct the kernel to terminate your thread instead.
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:unix compatible signals

Post by durand »

I was thinking of providing an additional state that a process could be in - a signal state. When in this state, only a registered signal handling thread will be executed while all other previously running threads are put into a paused state waiting to be resumed.

The signal handling thread could then do it's thing, manipulate internal library structures, modify other thread states, call registered signal handlers, etc. It would then indicate end-of-signal (EOS) when it's done it's job and the process state would return to normal.

This seems like a decent way to deliver signals but I would like some experienced input. Does it sound okay?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:unix compatible signals

Post by Pype.Clicker »

hmm ... cannot sort out whether a "special state" is required or just being allowed to flag other threads as "no execution atm. thanks" would be enough.

true, the signal processing stuff shouldn't occur as long as the supposed-to-be-interrupted thread is running on the CPU (e.g. on multi-CPU systems)

true, if there's an exception or whatever caused _by_ that thread, then that thread is suspended anyway.

Other threads could be just still running, unaware of a sibling thread in "waiting for my SEGV issue to be solved". Which leads to one of the rare case where your signal handler has to mess with on-stack resources -- which can sound odd as there are now two stacks involved.

It could lead to trouble only if the handler does some longjmp, imho -- couldn't remind whether that's a clever idea or something to avoid, though.
durand
Member
Member
Posts: 193
Joined: Wed Dec 21, 2005 12:00 am
Location: South Africa
Contact:

Re:unix compatible signals

Post by durand »

Hmm.. yeah. A special state wouldn't be necessary, I think. I need to read up on signals and see what the normal behaviour is. It would be an immediate pause of the application while the signal handler does it work.. but this pause is probably not necessary.

The more I think about it, the more I like this single handler approach with events being delivered by the kernel. You could provide kernel APIs to save, modify local thread stacks and then change it's point to the signal handler with the correct information. The thread context could be passed as one of the pieces of information provided by the kernel - which could then be used as part of the whole signal subsystem.

I think you could implement signals with the majority of logic in the userland library this way.

Plus you could use this hook as a generic debugging interface. Signals could be a subset of all the events which could be delivered in this fashion.

So, i guess my solution would be to:
  • Implement an event-hook system into the kernel.
  • Make sure exceptions are delivered as events where possible.
  • Introduce a few system calls which provide access to this event-hook system for inter-process signals.
The rest is up to userland. That should do it...
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:unix compatible signals

Post by Solar »

Aside from the technical implementation, be aware that the numerical value of signals (just like the value of the errno constants) differs between various Unixes, and that the exact semantics of some of these constants differ as well.
Every good solution is obvious once you've found it.
User avatar
spix
Member
Member
Posts: 128
Joined: Mon Jun 26, 2006 8:41 am
Location: Millicent, South Australia
Contact:

Re:unix compatible signals

Post by spix »

Hi Durand

I am also implementing signals at present in my own kernel, i'm not sure if i have fully understood signals yet, but this is what I am thinking: I am using syscalls for sigaction, which specifiys the location of the signal handler function, this is stored in the task's structure.

when a signal is raised, it is recorded in the relevent process's task(s) structure.

My kernel interrupts on a timer, which determins if a process switch is to occur, however before the process is switched it checks if there are any pending signals to handle, if there is, it does the relevent signal function.

That's where I am at, how to make it do the relevant function i am not sure. Signal handlers that are defined by sigaction are in userland and exist in only the relevant task's memory space.

So, I think the best way to switch to the signal handler would be to modify the stack such as when it irets to the new process, the eip is set to the signal handler and the old eip that got interrupted is pushed further down, so when the signal handler returns the old eip is what it returns to..

then there is all that alternate stack stuff, with sigaltstak. not sure where that fits in yet..

hope that is of some help, i'm not sure if it's correct, but thats my understanding so far, i know your os is microkernel so your implementation will be quite different to mine i guess

andrew
Post Reply