#include <sys/stack.h>
#include <sys/stack.h>
#include <sys/regset.h>
+#include <sys/lwp.h>
#include <inline-syscall.h>
-#include <sched_priv.h>
+#include <schedP.h>
#include <createthread_arch.c>
DECLARE_INLINE_SYSCALL (int, lwp_create, ucontext_t *ucp, int flags,
/* We set the thread to be initially suspended so that we can set
scheduling magic. */
int lwp_flags =
- ((attr->flags & ATTR_FLAG_DAEMON) ? THR_DAEMON : 0) |
- ((attr->flags & ATTR_FLAG_DETACHSTATE) ? THR_DETACHED : 0);
+ ((attr->flags & ATTR_FLAG_DAEMON) ? LWP_DAEMON : 0) |
+ ((attr->flags & ATTR_FLAG_DETACHSTATE) ? LWP_DETACHED : 0);
if ((attr->flags & ATTR_FLAG_THR_CREATE) == 0)
- lwp_flags |= THR_SUSPENDED;
+ lwp_flags |= LWP_SUSPENDED;
errval = INLINE_SYSCALL (lwp_create, 3, &ctx, lwp_flags, &pd->tid);
if (errval == 0 && (attr->flags & ATTR_FLAG_THR_CREATE) == 0)
{
errval = EPERM;
}
- /* Resume thread if requested. */
- if (errval == 0)
+ if (errval == 0 && !(attr->flags & ATTR_FLAG_SUSPENDED))
{
- if (!(attr->flags & ATTR_FLAG_SUSPENDED))
- errval = INLINE_SYSCALL (lwp_continue, 1, pd->tid);
+ errval = INLINE_SYSCALL (lwp_continue, 1, pd->tid);
}
+ else if (errval != 0)
+ {
+ pd->flags |= ATTR_FLAG_CREATE_FAILED;
+ INLINE_SYSCALL (lwp_continue, 1, pd->tid);
+
+ if (!IS_DETACHED (pd))
+ {
+ int result;
+ lll_wait_tid (pd->tid);
+ }
- /* Kill the thread if we didn't succeed above. */
- if (errval != 0)
- INLINE_SYSCALL (lwp_kill, 2, pd->tid, SIGKILL);
+ /* Note: if the thread is detached, start_thread will free pd;
+ otherwise the caller of create_thread will free pd. */
+ }
}
if (errval == 0)
else
{
atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second. */
-
- /* Failed. If the thread is detached, remove the TCB here since
- the caller cannot do this. The caller remembered the thread
- as detached and cannot reverify that it is not since it must
- not access the thread descriptor again. */
- if (IS_DETACHED (pd))
- __deallocate_stack (pd);
}
return errval;