clone.c 1.9 KB

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