[rtems commit] posix: Add POSIX thread affinity attribute support.
Jennifer Averett
jennifer at rtems.org
Fri Mar 7 15:08:50 UTC 2014
Module: rtems
Branch: master
Commit: 185e46f6a05295755f0f4522cf44c93ec8cbd7d1
Changeset: http://git.rtems.org/rtems/commit/?id=185e46f6a05295755f0f4522cf44c93ec8cbd7d1
Author: Jennifer Averett <jennifer.averett at oarcorp.com>
Date: Fri Jan 31 08:54:45 2014 -0600
posix: Add POSIX thread affinity attribute support.
With the addition of pthread affinity information in pthread_attr_t,
the existing code for pthread_attr_t had to be adjusted.
---
cpukit/posix/include/rtems/posix/pthreadimpl.h | 69 +++++++++++++++++++++++-
cpukit/posix/src/pthread.c | 52 ++++++++++++++----
cpukit/posix/src/pthreadattrinit.c | 5 +-
cpukit/posix/src/pthreadcreate.c | 19 ++++++-
4 files changed, 129 insertions(+), 16 deletions(-)
diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h
index a65f849..c4ace76 100644
--- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
+++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
@@ -24,6 +24,7 @@
#include <rtems/posix/threadsup.h>
#include <rtems/score/objectimpl.h>
#include <rtems/score/thread.h>
+#include <rtems/score/assert.h>
#ifdef __cplusplus
extern "C" {
@@ -48,7 +49,7 @@ POSIX_EXTERN Objects_Information _POSIX_Threads_Information;
/**
* This variable contains the default POSIX Thread attributes.
*/
-extern const pthread_attr_t _POSIX_Threads_Default_attributes;
+extern pthread_attr_t _POSIX_Threads_Default_attributes;
/**
* When the user configures a set of POSIX API initialization threads,
@@ -77,6 +78,23 @@ void _POSIX_Threads_Manager_initialization(void);
RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void );
/**
+ * @brief Copy POSIX Thread attribute structure.
+ *
+ * This routine copies the attr2 thread attribute structure
+ * to the attr1 Thread Attribute structure.
+ *
+ * @param[in] dst_attr is a pointer to the thread attribute
+ * structure to copy into.
+ *
+ * @param[out] src_attr is a pointer to the thread attribute
+ * structure to copy from.
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Copy_attributes(
+ pthread_attr_t *dst_attr,
+ const pthread_attr_t *src_attr
+);
+
+/**
* @brief Free POSIX control block.
*
* This routine frees a pthread control block to the
@@ -110,6 +128,15 @@ RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Get(
);
/**
+ * @brief POSIX threads initialize user threads body.
+ *
+ * This routine initializes the thread attributes structure.
+ */
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Initialize_attributes(
+ pthread_attr_t *attr
+);
+
+/**
* @brief Check if a POSIX thread control block is NULL.
*
* This function returns @c TRUE if the_pthread is @c NULL and @c FALSE
@@ -177,6 +204,14 @@ int _POSIX_Thread_Translate_sched_param(
);
/*
+ * rtems_pthread_attribute_compare
+ */
+int rtems_pthread_attribute_compare(
+ const pthread_attr_t *attr1,
+ const pthread_attr_t *attr2
+);
+
+/*
* _POSIX_Threads_Allocate
*/
@@ -186,6 +221,24 @@ RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void )
}
/*
+ * _POSIX_Threads_Copy_attributes
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Copy_attributes(
+ pthread_attr_t *dst_attr,
+ const pthread_attr_t *src_attr
+)
+{
+ *dst_attr = *src_attr;
+#if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
+ _Assert(
+ dst_attr->affinitysetsize == sizeof(dst_attr->affinitysetpreallocated)
+ );
+ dst_attr->affinityset = &dst_attr->affinitysetpreallocated;
+#endif
+}
+
+/*
* _POSIX_Threads_Free
*/
@@ -210,6 +263,20 @@ RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Get (
}
/*
+ * _POSIX_Threads_Initialize_attributes
+ */
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Initialize_attributes(
+ pthread_attr_t *attr
+)
+{
+ _POSIX_Threads_Copy_attributes(
+ attr,
+ &_POSIX_Threads_Default_attributes
+ );
+}
+
+/*
* _POSIX_Threads_Is_null
*/
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 5988a5e..f432b1b 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -17,10 +17,12 @@
#if HAVE_CONFIG_H
#include "config.h"
#endif
+#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include <limits.h>
+#include <assert.h>
#include <rtems/system.h>
#include <rtems/config.h>
@@ -46,13 +48,14 @@
* NOTE: Be careful .. if the default attribute set changes,
* _POSIX_Threads_Initialize_user_threads will need to be examined.
*/
-const pthread_attr_t _POSIX_Threads_Default_attributes = {
- true, /* is_initialized */
- NULL, /* stackaddr */
- 0, /* stacksize -- will be adjusted to minimum */
- PTHREAD_SCOPE_PROCESS, /* contentionscope */
- PTHREAD_INHERIT_SCHED, /* inheritsched */
- SCHED_FIFO, /* schedpolicy */
+pthread_attr_t _POSIX_Threads_Default_attributes = {
+ .is_initialized = true, /* is_initialized */
+ .stackaddr = NULL, /* stackaddr */
+ .stacksize = 0, /* stacksize -- will be adjusted to minimum */
+ .contentionscope = PTHREAD_SCOPE_PROCESS, /* contentionscope */
+ .inheritsched = PTHREAD_INHERIT_SCHED, /* inheritsched */
+ .schedpolicy = SCHED_FIFO, /* schedpolicy */
+ .schedparam =
{ /* schedparam */
2, /* sched_priority */
#if defined(_POSIX_SPORADIC_SERVER) || \
@@ -63,13 +66,19 @@ const pthread_attr_t _POSIX_Threads_Default_attributes = {
0 /* sched_ss_max_repl */
#endif
},
+
#if HAVE_DECL_PTHREAD_ATTR_SETGUARDSIZE
- 0, /* guardsize */
+ .guardsize = 0, /* guardsize */
#endif
#if defined(_POSIX_THREAD_CPUTIME)
- 1, /* cputime_clock_allowed */
+ .cputime_clock_allowed = 1, /* cputime_clock_allowed */
+ #endif
+ .detachstate = PTHREAD_CREATE_JOINABLE, /* detachstate */
+ #if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
+ .affinitysetsize = 0,
+ .affinityset = NULL,
+ .affinitysetpreallocated = {{0x0}}
#endif
- PTHREAD_CREATE_JOINABLE, /* detachstate */
};
/*
@@ -187,7 +196,7 @@ static bool _POSIX_Threads_Create_extension(
created->API_Extensions[ THREAD_API_POSIX ] = api;
/* XXX check all fields are touched */
- api->Attributes = _POSIX_Threads_Default_attributes;
+ _POSIX_Threads_Initialize_attributes( &api->Attributes );
api->detachstate = _POSIX_Threads_Default_attributes.detachstate;
api->schedpolicy = _POSIX_Threads_Default_attributes.schedpolicy;
api->schedparam = _POSIX_Threads_Default_attributes.schedparam;
@@ -346,6 +355,27 @@ User_extensions_Control _POSIX_Threads_User_extensions = {
*/
void _POSIX_Threads_Manager_initialization(void)
{
+ #if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
+ pthread_attr_t *attr;
+ int i;
+ int max_cpus = 1;
+
+ /* Initialize default attribute. */
+ attr = &_POSIX_Threads_Default_attributes;
+
+ /* We do not support a cpu count over CPU_SETSIZE */
+ max_cpus = _SMP_Get_processor_count();
+ assert( max_cpus <= CPU_SETSIZE );
+
+ /* Initialize the affinity to be the set of all available CPU's */
+ attr->affinityset = &attr->affinitysetpreallocated;
+ attr->affinitysetsize = sizeof( *attr->affinityset );
+ CPU_ZERO_S( attr->affinitysetsize, &attr->affinitysetpreallocated );
+
+ for (i=0; i<max_cpus; i++)
+ CPU_SET_S(i, attr->affinitysetsize, attr->affinityset );
+ #endif
+
_Objects_Initialize_information(
&_POSIX_Threads_Information, /* object information table */
OBJECTS_POSIX_API, /* object API */
diff --git a/cpukit/posix/src/pthreadattrinit.c b/cpukit/posix/src/pthreadattrinit.c
index cf0ecab..3dc6644 100644
--- a/cpukit/posix/src/pthreadattrinit.c
+++ b/cpukit/posix/src/pthreadattrinit.c
@@ -34,6 +34,7 @@ int pthread_attr_init(
if ( !attr )
return EINVAL;
- *attr = _POSIX_Threads_Default_attributes;
- return 0;
+ _POSIX_Threads_Initialize_attributes( attr );
+
+ return 0;
}
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index b780ecc..b148372 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -27,6 +27,7 @@
#include <rtems/posix/priorityimpl.h>
#include <rtems/posix/pthreadimpl.h>
#include <rtems/posix/time.h>
+#include <rtems/score/cpusetimpl.h>
#include <rtems/score/threadimpl.h>
#include <rtems/score/apimutex.h>
#include <rtems/score/stackimpl.h>
@@ -136,6 +137,14 @@ int pthread_create(
if ( rc )
return rc;
+#if defined(RTEMS_SMP)
+#if __RTEMS_HAVE_SYS_CPUSET_H__
+ rc = _CPU_set_Is_valid( attr->affinityset, attr->affinitysetsize );
+ if ( rc != 0 )
+ return EINVAL;
+#endif
+#endif
+
/*
* Currently all POSIX threads are floating point if the hardware
* supports it.
@@ -179,19 +188,25 @@ int pthread_create(
0, /* isr level */
name /* posix threads don't have a name */
);
-
if ( !status ) {
_POSIX_Threads_Free( the_thread );
_RTEMS_Unlock_allocator();
return EAGAIN;
}
+#if defined(RTEMS_SMP)
+#if __RTEMS_HAVE_SYS_CPUSET_H__
+ the_thread->affinity.setsize = attr->affinitysetsize;
+ *the_thread->affinity.set = *attr->affinityset;
+#endif
+#endif
+
/*
* finish initializing the per API structure
*/
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
- api->Attributes = *the_attr;
+ _POSIX_Threads_Copy_attributes( &api->Attributes, the_attr );
api->detachstate = the_attr->detachstate;
api->schedpolicy = schedpolicy;
api->schedparam = schedparam;
More information about the vc
mailing list