clone.c 2.1 KB

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