basic clone() support

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@40 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-03-22 17:31:38 +00:00
parent 612384d771
commit 1b6b029e40
14 changed files with 327 additions and 44 deletions

View file

@ -4,7 +4,7 @@ CFLAGS=-Wall -O2 -g
LDFLAGS=
ifeq ($(ARCH),i386)
TESTS=test2 sha1-i386 test-i386
TESTS=testclone testsig testthread sha1-i386 test-i386
endif
TESTS+=sha1
@ -16,9 +16,15 @@ hello: hello.c
$(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
strip hello
test2: test2.c
testclone: testclone.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
testsig: testsig.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
testthread: testthread.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
# i386 emulation test (test various opcodes) */
test-i386: test-i386.c test-i386-code16.S \
test-i386.h test-i386-shift.h test-i386-muldiv.h

61
tests/testclone.c Normal file
View file

@ -0,0 +1,61 @@
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <inttypes.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sched.h>
int thread1_func(void *arg)
{
int i;
char buf[512];
for(i=0;i<10;i++) {
snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg);
write(1, buf, strlen(buf));
usleep(100 * 1000);
}
return 0;
}
int thread2_func(void *arg)
{
int i;
char buf[512];
for(i=0;i<20;i++) {
snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg);
write(1, buf, strlen(buf));
usleep(120 * 1000);
}
return 0;
}
#define STACK_SIZE 16384
void test_clone(void)
{
uint8_t *stack1, *stack2;
int pid1, pid2, status1, status2;
stack1 = malloc(STACK_SIZE);
pid1 = clone(thread1_func, stack1 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1");
stack2 = malloc(STACK_SIZE);
pid2 = clone(thread2_func, stack2 + STACK_SIZE,
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2");
while (waitpid(pid1, &status1, 0) != pid1);
while (waitpid(pid2, &status2, 0) != pid2);
printf("status1=0x%x\n", status1);
printf("status2=0x%x\n", status2);
printf("End of clone test.\n");
}
int main(int argc, char **argv)
{
test_clone();
return 0;
}

24
tests/testsig.c Normal file
View file

@ -0,0 +1,24 @@
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler(int sig)
{
printf("alarm signal=%d\n", sig);
alarm(1);
}
int main(int argc, char **argv)
{
struct sigaction act;
act.sa_handler = alarm_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
alarm(1);
for(;;) {
sleep(1);
}
return 0;
}

50
tests/testthread.c Normal file
View file

@ -0,0 +1,50 @@
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <inttypes.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sched.h>
void *thread1_func(void *arg)
{
int i;
char buf[512];
for(i=0;i<10;i++) {
snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg);
write(1, buf, strlen(buf));
usleep(100 * 1000);
}
return NULL;
}
void *thread2_func(void *arg)
{
int i;
char buf[512];
for(i=0;i<20;i++) {
snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg);
write(1, buf, strlen(buf));
usleep(150 * 1000);
}
return NULL;
}
void test_pthread(void)
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, thread1_func, "hello1");
pthread_create(&tid2, NULL, thread2_func, "hello2");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("End of pthread test.\n");
}
int main(int argc, char **argv)
{
test_pthread();
return 0;
}