/*
* Cheesy thread.
* Linux kernel 1.3.98
*
* Melvin Smith 1996
*/
#include <linux/pthread.h>
#include <linux/unistd.h>
/* Create a thread */
int pthread_create( pthread_t *tid, const pthread_attr_t *attr,
void (*start_fun)(void *), void *arg )
{
int retval = 0;
void **stack;
int stacksize;
if( attr == 0 )
stacksize = DEFAULT_STACK_SIZE;
else
stacksize = attr->stacksize;
/*
* Create the new thread's stack
*/
stack = (void **)malloc( stacksize );
if( !stack )
{
errno = ENOMEM;
return -1;
}
/*
* Push the arg onto stack
*/
stack = (void **)( (char *)stack + stacksize );
*--stack = arg;
/*
* Trap to clone() system call
* %eax - __NR_clone, system call number (linux/unistd.h)
* %ebx - clone flags
* %ecx - new stack for thread (process)
* Return value:
* %eax - pid of child process for parent, 0 for child
*/
__asm__ __volatile__ (
"int $0x80\n\t"
"testl %0,%0\n\t" /* return val ( 0=child,other=parent ) */
"jne parent\n\t"
"call *%3\n\t" /* call start fun() for child */
"movl %2,%0\n\t" /* exit() system call number */
"int $0x80\n\t" /* exit */
"parent:\t"
:"=a" (retval)
:"0" (__NR_clone),
"i" (__NR_exit),
"r" (start_fun),
"b" (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD),
"c" (stack)
);
if( retval > 0 )
{
*tid = retval;
}
else
{
errno = -retval;
retval = -1;
}
return retval;
}
[* REST OF CODE SNIPPED *]
Here is a test main.
/** TEST MAIN **/
void task1( void * );
void task2( void * );
int val;
int main()
{
pthread_t tid1;
pthread_t tid2;
if( pthread_create( &tid1, 0, task1, 0 ) < 0 )
printf( "thread creation failed errno %d\n", errno );
printf( "created thread 1\n" );
if( pthread_create( &tid1, 0, task2, 0 ) < 0 )
printf( "thread creation failed errno %d\n", errno );
printf( "created thread 2\n" );
exit(0);
}
void task1( void * arg )
{
while( 1 )
{
printf( "T1 Inc to %d\n", val++ );
sleep( 1 );
}
}
void task2( void * arg )
{
while( 1 )
{
printf( "T2 Inc to %d\n", val++ );
sleep( 1 );
}
}