Threads in my OS live a very short life and they are ended with by calling an exit thread system call. This can be pure exit thread call or a send message call which can also exit the thread if desired. The reason for this is to avoid a "tail", basically that the scheduler must run the last of the thread if there was context switch because of the send call. This model works quite well and reduces the number of context switches but it has a side effect that the stack frame deconstructors are not run automatically due to the function never exits in the world of C++. This can be solved by calling all the deconstructors implicitly but it is kind of ugly and it is easy to forget which can lead that program leaks memory which kind of defeats one of the benefits of C++.
In my case I use GCC and I wonder if there is any way to tell the compiler to insert all the stack frame deconstructors before these exit thread system calls?
Implicitly run ALL C++ stack frame deconstructors?
-
- Member
- Posts: 595
- Joined: Mon Jul 05, 2010 4:15 pm
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Implicitly run ALL C++ stack frame deconstructors?
Throw an "exit thread exception" and catch it in the thread's start routine. Otherwise, no.
How is GCC supposed to know what destructors need to be run, except for by walking the stack?
And, of course, this will be slower than just letting the normal flow of code unwind things.
I'd suggest making the return value of the thread's entry point be how you activate this optimization. Its the only comprehensive way to bring a threads' lifetime to an end.
How is GCC supposed to know what destructors need to be run, except for by walking the stack?
And, of course, this will be slower than just letting the normal flow of code unwind things.
I'd suggest making the return value of the thread's entry point be how you activate this optimization. Its the only comprehensive way to bring a threads' lifetime to an end.
-
- Member
- Posts: 595
- Joined: Mon Jul 05, 2010 4:15 pm
Re: Implicitly run ALL C++ stack frame deconstructors?
Just exit thread is easy as then you can just return to thread start stack frame. It is the merged send and exit that makes it more difficult. One possibility is that in the thread function, the send and exit function is really just setting up a stack structure and this structure is passed downwards as a pointer to the thread creation frame, the thread creation frame then do appropriate action depending on what the struct contains.
Re: Implicitly run ALL C++ stack frame deconstructors?
Code: Select all
#define BEGIN_FUNC() {
#define END_FUNC(x) } _outlab: return x; _exitlab: syscall_exit()
#define SEND_AND_EXIT(x) do {syscall_send(x); goto _exitlab;} while(0)
int f() {
BEGIN_FUNC();
DO STUFF
SEND_AND_EXIT(4);
END_FUNC(0);
}
-
- Member
- Posts: 595
- Joined: Mon Jul 05, 2010 4:15 pm
Re: Implicitly run ALL C++ stack frame deconstructors?
Code: Select all
#define BEGIN_FUNC() {
#define END_FUNC(x) } _outlab: return x; _exitlab: syscall_exit()
#define SEND_AND_EXIT(x) do {syscall_send(x); goto _exitlab;} while(0)
int f() {
BEGIN_FUNC();
DO STUFF
SEND_AND_EXIT(4);
END_FUNC(0);
}
If there are lots of cleaning up to do, then a separate send could be beneficial as a higher priority thread would be able run earlier before the cleaning. Many times though, it is just about sending an integer and then exit and there was no dynamic allocation, the "tail" of the thread will then be very small.
In practice you can do this manually, tell the programmer you have to call a second function if you want to do anything that requires deconstructors. Basically:
Code: Select all
MyThreadFunction()
{
int retval = MyRealThreadFunctionThatDoestheWork();
SendIntegerAndExit(retval, somethread);
}