clone.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /*
  2. * libc/sysdeps/linux/nios2/clone.c -- `clone' syscall for linux/nios2
  3. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  4. *
  5. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  6. *
  7. *
  8. * Copyright (C) 2004,05 Microtronix Datacom Ltd
  9. * Copyright (C) 2002,03 NEC Electronics Corporation
  10. * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
  11. *
  12. * Written by Miles Bader <miles@gnu.org>
  13. * Nios2 port by Wentao Xu
  14. */
  15. #include <errno.h>
  16. #include <sys/syscall.h>
  17. int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg)
  18. {
  19. register unsigned long rval asm ("r2") = -EINVAL;
  20. if (fn && child_stack) {
  21. register unsigned long syscall asm ("r3");
  22. register unsigned long arg0 asm ("r4");
  23. register unsigned long arg1 asm ("r5");
  24. /* Clone this thread. */
  25. rval = TRAP_ID_SYSCALL;
  26. syscall = __NR_clone;
  27. arg0 = flags;
  28. arg1 = (unsigned long)child_stack;
  29. asm volatile ("trap "
  30. : "=r" (rval), "=r" (syscall)
  31. : "0" (rval),"1" (syscall), "r" (arg0), "r" (arg1)
  32. );
  33. if (rval == 0) {
  34. /* In child thread, call fn and exit. */
  35. arg0 = (*fn) (arg);
  36. syscall = __NR_exit;
  37. asm volatile ("trap "
  38. : "=r" (rval), "=r" (syscall)
  39. : "1" (syscall), "r" (arg0));
  40. }
  41. }
  42. __syscall_return (int, rval);
  43. }