clone.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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 <sched.h>
  17. #include <sys/syscall.h>
  18. int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...)
  19. {
  20. register unsigned long rval __asm__ ("r2") = -EINVAL;
  21. if (fn && child_stack) {
  22. register unsigned long syscall __asm__ ("r3");
  23. register unsigned long arg0 __asm__ ("r4");
  24. register unsigned long arg1 __asm__ ("r5");
  25. /* Clone this thread. */
  26. rval = TRAP_ID_SYSCALL;
  27. syscall = __NR_clone;
  28. arg0 = flags;
  29. arg1 = (unsigned long)child_stack;
  30. __asm__ __volatile__ ("trap "
  31. : "=r" (rval), "=r" (syscall)
  32. : "0" (rval),"1" (syscall), "r" (arg0), "r" (arg1)
  33. );
  34. if (rval == 0) {
  35. /* In child thread, call fn and exit. */
  36. arg0 = (*fn) (arg);
  37. syscall = __NR_exit;
  38. __asm__ __volatile__ ("trap "
  39. : "=r" (rval), "=r" (syscall)
  40. : "1" (syscall), "r" (arg0));
  41. }
  42. }
  43. __syscall_return (int, rval);
  44. }