Reputation: 143
I am trying to implement a version of pthread_create
just for the heck of it using the clone()
system call. I am curious as to how pthread
free's the stack memory after the thread has exited. This is what I have tried:
struct ThreadInfo{...}
void ThreadPrint(){...}
void HandleThread(args){
ThreadInfo* info = (cast here)args;
info->callfunction;
free(info->stack)
}
void CreateThread(callfunction){
ThreadInfo info = {};
info.stack = //alloc stack
info.callfunction = callfunction;
clone(HandleThread,...,&info)
}
int main(){
CreateThread(ThreadPrint);
}
This method doesn't work because the process still needs to use its stack during the free()
function call in HandleThread
. It's probably because the return address is lost when the stack is free'd and free cannot return anymore so maybe using a raw system call might work. Other than that I am not sure how I to free the thread's stack without using a separate process.
EDIT: To those who are interested, this is the system call I made to have the thread free its own stack.
__asm__ volatile (
"mov $11,%%rax\n" //call munmap
"mov %[addr],%%rdi\n"
"mov %[len],%%rsi\n"
"syscall\n"
"xor %%rdi,%%rdi\n"
"mov $60,%%rax\n"//manually call exit
"syscall\n":: [addr] "g" (info->stack), [len] "g" (info->stacksize)
);
As far as I know, you have to use inline assembly. Using the C function wrapper will leave the thread with no where to return to. If anyone has a better solution, I would love to hear it. Better yet, if anyone knows the internals of the pthread library, would love to hear that. Thanks.
Upvotes: 1
Views: 969
Reputation: 58510
Managing thread stacks is done by glibc The library uses mmap
to allocate thread stacks and munmap
to free them.
Recall that threads can be joinable or detached.
For a joinable thread, deallocating all of its resources can be deferred until pthread_join
is called on it. The threading library can deallocate its stack at that time (or mark it free for re-use).
When a detached thread terminates, even if the library isn't notified of this, it will eventually hunt down the unused stack and recycle it.
Upvotes: 1
Reputation: 11638
You don't free the stack in the thread you just created. The parent process ie your main thread owns the stack and it would free it when the thread returns.
The man page has an example of using clone including creating the stack properly.
http://linux.die.net/man/2/clone
You need to setup a data structure that tracks the threads along with their stacks so when you test to see if the child is still alive or get a signal that it's dead you can cleanup.
Upvotes: 1