Re: Problem with ucontext_t struct in signal handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



XComp wrote:

> I want to switch between user contexts using a signal handler  
> (something like a preemptive scheduler for userlevel threads). I've  
> found several sources, which say that it's not a good idea to use  
> setcontext or swapcontext in a signal handler. Nevertheless there also  
> exists at least one sample code of such an preemptive scheduler, which  
> seems to work well, at least on my machine (Ubuntu 8.04 with linux  
> kernel 2.6.24-22): www.seas.upenn.edu/~cse381/context_demo.c
> 
> // [...]
> static ucontext_t thread_context;
> static ucontext_t scheduler_context;
> 
> int thread_finished;
> int i;
> 
> static void simple_function(void) {
> 	// do nothing but counting
> 	for (i = 0; i < 1000000000; ++i) { }
> 
> 	if (i == 1000000000) {
> 		printf("\n[Thread Function]\t1st counting worked fine...");
> 	} else {
> 		printf("\n[Thread Function]\tError: Counting didn't finished  (%d)...", i);
> 	}
> 
> 	thread_finished = 1;
> }
> 
> static void other_function() {
> 	// thread_finished is a global variable, which is set to 1, if the  thread function is finished
> 	while(thread_finished != 1) { swapcontext(&scheduler_context,  &thread_context); }
> }
> 
> static void signal_handler_function(int sig_nr, siginfo_t* info, void  *old_context) {
> 	if (sig_nr == SIGPROF) {
> 		// saves the thread context
> 		thread_context = *((ucontext_t*) context);
> 
> 		// swaps back to scheduler context
> 		setcontext(&scheduler_context);
> 	}
> }
> // [...]
> 
> I ran into the following problem which belongs to the code above. I  
> interrupted simple_function several times by using a ITimer. But the  
> for-loop doesn't finish successfully everytime. Often the if condition  
> is false.

It seems likely that either the registers or the stack (wherever "i"
is stored) is getting trashed. What is "i" in the cases where the test
fails?

> But it does not cancel after the first signal is raised.  
> I've found out that using the third parameter old_context for storing  
> the old context is the reason. But I don't know why.

Note that the old_context parameter to the signal handler won't be
pointing to any of your context "slots". When a signal occurs, the
current context will be saved in a ucontext_t on the current context's
stack, and the old_context argument will point to that.

It needs to be borne in mind that a ucontext_t isn't "the context"
itself. It's merely a structure for storing information about a
context, either for receiving information (e.g. getcontext) or
providing it (e.g. setcontext).

> So I thought there might be a problem in the kernel. Am I right?

I don't think so.

> I was afraid to post the whole code, so I hope that this code
> snippet is enough.

It would help if it was accurate (e.g. the signal handler refers to
"context" which isn't declared anywhere; is this supposed to be the
old_context parameter?) and more complete.

> I would appreciate if someone can give me a comment whether this  
> strange behaviour is because of a wrong thinking of mine or because of  
> a error in the kernel which needs to be fixed.

I suspect the former.

-- 
Glynn Clements <glynn@xxxxxxxxxxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Assembler]     [Git]     [Kernel List]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [C Programming]     [Yosemite Campsites]     [Yosemite News]     [GCC Help]

  Powered by Linux