user19283043 user19283043 - 9 days ago 8
C Question

implementing and testing thread_create function

I'm very new in C and Linux and English is not my mother language. Sorry for those in advance.

I'm working on school project which is implementing thread api and I made the thread_create() function using clone().
The thing is when I do

thread_create(&tid1, NULL, (void *)Testcase1, 0);
,
it creates new thread but TestCase1 also includes thread_create and it doesn't seem create another thread. Let me explain with my code.

this is my thread_create below:

int foo(void* arg){
printf("Hii");
return 0;
}
int thread_create(thread_t *thread, thread_attr_t *attr, void *(*start_routine) (void *), void *arg)
{
void* stack;

stack= malloc( STACK_SIZE );
pid_t pid;

if( stack==0)
{
perror( "malloc : could not allocate stack" );
exit( 1 );
}
pid = clone( &foo ,( char* )stack+STACK_SIZE,SIGCHLD|CLONE_VM|CLONE_SIGHAND|CLONE_FS|CLONE_FILES,0 );
if(pid == -1)
{
perror("clone");
exit(2);
}
kill(pid, SIGSTOP);

Thread* newTCB = (Thread*)malloc(sizeof(Thread));
newTCB->stackSize = malloc(STACK_SIZE);
newTCB->pid = pid;
newTCB->status = THREAD_STATUS_READY;

rEnqueue(newTCB);
rPrintqueue();

free(stack);
printf("Child thread returned and stack freed.\n");
return 0;
}


And this is my test code below:

thread_create(&tid1, NULL, (void*)TestCase1, 0);


TestCase1() below:

int Tc1ThreadProc(int param)
{
int tid = 0;
int count = 0;

tid = thread_self();

count = 3;
while (count > 0)
{
/* sleep for 1 seconds */
sleep(2);
printf("Tc1ThreadProc: my thread id (%d), arg is (%d)\n", tid, param);
count--;
}
}
void TestCase1(void)
{
thread_t tid[TOTAL_THREAD_NUM];

thread_create(&tid[0], NULL, (void*)Tc1ThreadProc, (int*)1);
thread_create(&tid[1], NULL, (void*)Tc1ThreadProc, (int*)2);
thread_create(&tid[2], NULL, (void*)Tc1ThreadProc, (int*)3);

while(1){}

return ;
}


it's supposed to print
"Tc1ThreadProc: my thread id (%d), arg is (%d)\n"
this 3 times but it prints only
"Hii"
which is on foo().
How do I fix this?

Answer

You pass pointer to function "TestCase1" as argument to "thread_create", but inside "thread_create" you don't use it at all:

thread_create(&tid1, NULL, (void*)TestCase1, 0);

You're calling "clone" syscall only with pointer to "foo" function. From inside "thread_create" your "TestCase1" pointer is named "start_routine", so you need to call similar "clone" syscall, but instead pointer to "foo" you should pass pointer to "TestCase1". Something like that:

pid = clone( start_routine, (char*) stack + STACK_SIZE, SIGCHLD | CLONE_VM | CLONE_SIGHAND | CLONE_FS | CLONE_FILES, 0);