clone.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #define _GNU_SOURCE
  2. #include <malloc.h>
  3. #include <unistd.h>
  4. #include <sys/types.h>
  5. #include <sys/wait.h>
  6. #include <signal.h>
  7. #include <sched.h>
  8. #include <stdio.h>
  9. #include <sys/syscall.h>
  10. #include <asm/prctl.h>
  11. // 64kB stack
  12. #define FIBER_STACK (1024 * 64)
  13. __thread int mypid = 0;
  14. unsigned long gettls (void)
  15. {
  16. unsigned long tls;
  17. syscall(__NR_arch_prctl, ARCH_GET_FS, &tls);
  18. return tls;
  19. }
  20. int thread_function (void * argument)
  21. {
  22. mypid = getpid();
  23. int * ptr = (int *) argument;
  24. printf("in the child: pid (%016lx) = %d\n", (unsigned long) &mypid, mypid);
  25. printf("in the child: pid = %d\n", getpid());
  26. printf("in the child: tls = %08lx\n", gettls());
  27. printf("child thread exiting\n");
  28. printf("argument passed %d\n", *ptr);
  29. return 0;
  30. }
  31. int main (int argc, const char ** argv)
  32. {
  33. void * stack;
  34. pid_t pid;
  35. int varx = 143;
  36. mypid = getpid();
  37. printf("in the parent: pid = %d\n", getpid());
  38. // Allocate the stack
  39. stack = malloc(FIBER_STACK);
  40. if (stack == 0) {
  41. perror("malloc: could not allocate stack");
  42. _exit(1);
  43. }
  44. printf("child_stack: %016lx-%016lx\n", (unsigned long) stack,
  45. (unsigned long) stack + FIBER_STACK);
  46. // Call the clone system call to create the child thread
  47. pid = clone(&thread_function, (void *) stack + FIBER_STACK,
  48. CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM,
  49. &varx);
  50. printf("clone() creates new thread %d\n", pid);
  51. if (pid == -1) {
  52. perror("clone");
  53. _exit(2);
  54. }
  55. // Wait for the child thread to exit
  56. pid = waitpid(0, NULL, __WALL);
  57. if (pid == -1) {
  58. perror("waitpid");
  59. _exit(3);
  60. }
  61. // Free the stack
  62. free(stack);
  63. printf("in the parent: pid (%016lx) = %d\n", (unsigned long) &mypid, mypid);
  64. printf("in the parent: pid = %d\n", getpid());
  65. printf("in the parent: tls = %08lx\n", gettls());
  66. return 0;
  67. }