Find the answer to your Linux question:
Results 1 to 4 of 4
Hello Linux gurus, I am writing a program that is supposed to be an emulation of a Unix shell. It has its own concept of a process and its own ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jun 2004
    Location
    Poland
    Posts
    2

    functions from ucontext.h


    Hello Linux gurus,

    I am writing a program that is supposed to be an emulation of a Unix shell. It has its own concept of a process and its own scheduler. I use setcontext() and swapcontext() to swap my processes.

    In order for the processes to be swapped periodically, I have arranged SIGALRM to be delivered to my program every 10 ms ( isn't that too short amount of time? ) , and the scheduler is the signal handler which messes up with process queues and finally calls swapcontext to swap the old context out and run a new one. In order for the scheduler not to be interrupted by itself, I mask SIGALRM during its execution.

    This setup basically works, sometimes I am able to spawn as much as a million processes.
    The problem is that sometimes - very rarely - I experence a segfault. I've been trying to isolate the problem for past 2 weeks now. Finally I decided to RTFM. Here is what I read in

    file://localhost/usr/doc/glibc-doc/html/chapters_23.html

    "It is not allowed to do the context switching from the signal handler directly since neither setcontext nor swapcontext are functions which can be called from a signal handler."

    Damn! The question: how in the world am I supposed to write my scheduler then? I know I could use sigsetjmp() and siglongjmp(), but I'd very much rather stick to ucontext.h functions.

    Could anyone give me a hint?

    Leszek Koltunski

    You can take a look at the code at www.3miasto.net/~leszek/progs/cam/camel.html

  2. #2
    Linux Guru
    Join Date
    Oct 2001
    Location
    Täby, Sweden
    Posts
    7,578
    No, I'd have been very surprised if that would have worked. =)
    The signal handler uses a very special stack and I'm actually surprised it works at all when you're switching stacks back and forth within it.

    The thing is, the ucontext calls are very specifically designed for cooperative multitasking, and thus I think there is really no good way to use them to implement preemptive multitasking.

    What you want to do is probably first of all to set up a seperate stack for the signal handler using the sigaltstack call. Then you probably want to write a signal handler that manipulates its stack in order to return to another stack and thread. I've been working a slight bit with these things previously, but I don't remember all the details, in particular not how the stack looks around the signal handler call. However, seeing that you seem like a competent person, you can probably study it yourself. Make a program that registers a signal handler and sends a signal to itself, then make it core dump and study the stack in GDB or something. Also, read up on the sigreturn() syscall in arch/i386/kernel/signal.c of the kernel source code. It handles the bulk of signal returns.

  3. #3
    Just Joined!
    Join Date
    Jun 2004
    Location
    Poland
    Posts
    2
    Thx Dol,

    I'll study that code and report back with my results.

    Would you happen to know about any documentation on how the stacks are manipulated during signal handling/ context switching? My googling results in a bunch of useless man pages...

  4. #4
    Linux Guru
    Join Date
    Oct 2001
    Location
    Täby, Sweden
    Posts
    7,578
    Well, with the ucontext switching, it's just a matter of storing another value into ESP, namely the one you've allocated when you initialized the context. Those stacks aren't exactly manipulated. It's just that as part of switching from one context, that context's stack pointer is saved into the context struct. Thus, if you switch from a sighandler, it's the sighandler's stack pointer that gets saved, which will likely get you into trouble.

    When invoking the sighandler, well, like I said, I don't actually remember, unfortunately. I don't think that there is any documentation on it, since it's supposed to be opaque to the application programmer. Thus, the best way to find out is most likely to check signal.c in the kernel source.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •