summaryrefslogtreecommitdiff
path: root/nptl/pthread_create.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2013-06-15 12:24:15 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2013-06-15 12:24:15 +0530
commit61dd6208fb1e59a423b6dfa712a3c896c34b2590 (patch)
tree3417035a17046120bfedeafe2e7db9e366380101 /nptl/pthread_create.c
parent601eb33debf0c7548f52ba72cec4b3f362105e39 (diff)
New API to set default thread attributes
This patch introduces two new convenience functions to set the default thread attributes used for creating threads. This allows a programmer to set the default thread attributes just once in a process and then run pthread_create without additional attributes.
Diffstat (limited to 'nptl/pthread_create.c')
-rw-r--r--nptl/pthread_create.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index b78bd95c46..7f714f8903 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -449,18 +449,47 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
STACK_VARIABLES;
const struct pthread_attr *iattr = (struct pthread_attr *) attr;
+ struct pthread_attr default_attr;
+ bool free_cpuset = false;
if (iattr == NULL)
- /* Is this the best idea? On NUMA machines this could mean
- accessing far-away memory. */
- iattr = &__default_pthread_attr;
+ {
+ lll_lock (__default_pthread_attr_lock, LLL_PRIVATE);
+ default_attr = __default_pthread_attr;
+ size_t cpusetsize = default_attr.cpusetsize;
+ if (cpusetsize > 0)
+ {
+ cpu_set_t *cpuset;
+ if (__glibc_likely (__libc_use_alloca (cpusetsize)))
+ cpuset = __alloca (cpusetsize);
+ else
+ {
+ cpuset = malloc (cpusetsize);
+ if (cpuset == NULL)
+ {
+ lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
+ return ENOMEM;
+ }
+ free_cpuset = true;
+ }
+ memcpy (cpuset, default_attr.cpuset, cpusetsize);
+ default_attr.cpuset = cpuset;
+ }
+ lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE);
+ iattr = &default_attr;
+ }
struct pthread *pd = NULL;
int err = ALLOCATE_STACK (iattr, &pd);
+ int retval = 0;
+
if (__builtin_expect (err != 0, 0))
/* Something went wrong. Maybe a parameter of the attributes is
invalid or we could not allocate memory. Note we have to
translate error codes. */
- return err == ENOMEM ? EAGAIN : err;
+ {
+ retval = err == ENOMEM ? EAGAIN : err;
+ goto out;
+ }
/* Initialize the TCB. All initializations with zero should be
@@ -511,8 +540,7 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
#endif
/* Determine scheduling parameters for the thread. */
- if (attr != NULL
- && __builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
+ if (__builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
&& (iattr->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)) != 0)
{
INTERNAL_SYSCALL_DECL (scerr);
@@ -551,7 +579,8 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
__deallocate_stack (pd);
- return EINVAL;
+ retval = EINVAL;
+ goto out;
}
}
@@ -561,7 +590,13 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
LIBC_PROBE (pthread_create, 4, newthread, attr, start_routine, arg);
/* Start the thread. */
- return create_thread (pd, iattr, STACK_VARIABLES_ARGS);
+ retval = create_thread (pd, iattr, STACK_VARIABLES_ARGS);
+
+ out:
+ if (__glibc_unlikely (free_cpuset))
+ free (default_attr.cpuset);
+
+ return retval;
}
versioned_symbol (libpthread, __pthread_create_2_1, pthread_create, GLIBC_2_1);