I am trying to implement simple user level thread library in c.when one thread start and this thread call second thread. this second thread run correctly but when it exit program crash.here is my coding.
//**********************************************
#include <setjmp.h>
typedef void *any_ptr;
/* Define Boolean type, and associated constants. */
typedef int Boolean;
typedef void (*ThreadFunc)(any_ptr);
#define TRUE ((Boolean)1);
#define FALSE ((Boolean)0);
typedef struct TheadSystem
{
queue<any_ptr> readyQ;
// currently executing thread
jmp_buf lastContext; // location on which the system jumps after all threads have exited
char name[30]; // optional name string of a thread, may be used for debugging
jmp_buf context; // saved context of this thread
signal_t *sig; // signal that wakes up a waiting thread
ThreadFunc func; // function that this thread started executing
any_ptr arg;
}TheadSystem;
void t_start(ThreadFunc f, any_ptr v, char *name);
void t_yield();
void block();
void unblock();
void t_sig(Condition cond, any_ptr val, Boolean queue_signal);
void t_fork(ThreadFunc f, any_ptr v, char *name);
void t_exit(int val);
My implementation of threads.h
#include "threads.h"
#include<iostream>
#include<queue>
using namespace std;
TheadSystem th;
queue<any_ptr> blocked_queue;
jmp_buf set_env,ready_env,yeild_buf;
void t_start(ThreadFunc f, any_ptr v, char *name){
if(!th.ready_queue.empty()){
cout<<"sorry thread already started now you have to create by t_fork:"<<endl;
}
else{
th.ready_queue.push(th.context);
if(!setjmp(th.context)){
memcpy(th.lastContext,th.context,sizeof(jmp_buf));
th.arg=v;
th.func=f;
//memcpy(th.currentThread->context,set_env,sizeof(jmp_buf));
//cout<<"when jmp buf set then:"<<endl;
th.ready_queue.push(th.context);
th.func(th.arg);
}
//cout<<"after come back from long jump:"<<endl;
}
}
void t_yield(){
jmp_buf *j=(jmp_buf *)th.ready_queue.front();
th.ready_queue.front()=th.context;
longjmp(*j,2);
}
void t_fork(ThreadFunc f, any_ptr v, char *name){
memcpy(th.lastContext,th.context,sizeof(jmp_buf));
if(!setjmp(th.context)){
f(v);
th.ready_queue.push(th.context);
}else
{
}
}//end of t_fork
void t_exit(int val){
cout<<"before long jump in t_exit"<<endl;
jmp_buf *j=(jmp_buf *)th.ready_queue.front();
th.ready_queue.pop();
longjmp(*j,2);
}
void block(){
blocked_queue.push(th.context);
jmp_buf *j=(jmp_buf *)th.ready_queue.front();
th.ready_queue.pop();
longjmp(*j,2);
}
void unblock(){
th.ready_queue.push(th.context);
jmp_buf *j=(jmp_buf *)blocked_queue.front();
blocked_queue.pop();
longjmp(*j,2);
}
my test case is
#include<iostream>
#include<setjmp.h>
#include<stdio.h>
#include "threads.h"
#include<queue>
using namespace std;
void fun2(any_ptr v){
cout<<"in 2nd function:"<<endl;
t_exit(0);
}
void helloworld(any_ptr v){
cout<<"in hello world from start"<<endl;
t_fork(fun2,NULL,"no value");
cout<<"after second thread:"<<endl;
cout<<"before exit"<<endl;
t_exit(0);
}
void main(){
cout<<"1 start"<<endl;
t_start(helloworld, NULL, "my function");
cout<<"main function"<<endl;
}//end of void main