Attached is a set of patches for review that implement classic affinity.
Jennifer Averett
On-Line Applications Research
From e950c2191bc05f9d60afda99f6529360ae03670b Mon Sep 17 00:00:00 2001
From: Jennifer Averett <jennifer.aver...@oarcorp.com>
Date: Thu, 6 Feb 2014 12:42:24 -0600
Subject: [PATCH 02/19] score: Add cpuset support to score.
---
cpukit/score/Makefile.am | 4 ++
cpukit/score/include/rtems/score/cpuset.h | 61 ++++++++++++++++++
cpukit/score/include/rtems/score/cpusetimpl.h | 87 +++++++++++++++++++++++++
cpukit/score/include/rtems/score/thread.h | 18 ++++++
cpukit/score/preinstall.am | 8 +++
cpukit/score/src/cpuset.c | 92 +++++++++++++++++++++++++++
cpukit/score/src/cpusetprintsupport.c | 84 ++++++++++++++++++++++++
cpukit/score/src/threadinitialize.c | 5 ++
8 files changed, 359 insertions(+)
create mode 100644 cpukit/score/include/rtems/score/cpuset.h
create mode 100644 cpukit/score/include/rtems/score/cpusetimpl.h
create mode 100644 cpukit/score/src/cpuset.c
create mode 100644 cpukit/score/src/cpusetprintsupport.c
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 6663d5c..0dc21b2 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -29,6 +29,8 @@ include_rtems_score_HEADERS += include/rtems/score/coremutex.h
include_rtems_score_HEADERS += include/rtems/score/coremuteximpl.h
include_rtems_score_HEADERS += include/rtems/score/coresem.h
include_rtems_score_HEADERS += include/rtems/score/coresemimpl.h
+include_rtems_score_HEADERS += include/rtems/score/cpuset.h
+include_rtems_score_HEADERS += include/rtems/score/cpusetimpl.h
include_rtems_score_HEADERS += include/rtems/score/heap.h
include_rtems_score_HEADERS += include/rtems/score/heapimpl.h
include_rtems_score_HEADERS += include/rtems/score/protectedheap.h
@@ -124,6 +126,8 @@ libscore_a_SOURCES += src/schedulerprioritysmp.c
libscore_a_SOURCES += src/schedulersimplesmp.c
libscore_a_SOURCES += src/schedulersmpstartidle.c
libscore_a_SOURCES += src/smp.c
+libscore_a_SOURCES += src/cpuset.c
+libscore_a_SOURCES += src/cpusetprintsupport.c
endif
## CORE_APIMUTEX_C_FILES
diff --git a/cpukit/score/include/rtems/score/cpuset.h b/cpukit/score/include/rtems/score/cpuset.h
new file mode 100644
index 0000000..a2012a8
--- /dev/null
+++ b/cpukit/score/include/rtems/score/cpuset.h
@@ -0,0 +1,61 @@
+/**
+ * @file rtems/score/cpuset.h
+ *
+ * @brief Information About the cpuset used for affinity
+ *
+ * This include file contains all information about the thread
+ * cpuset Handler. This Handler provides mechanisms which can be used to
+ * control the cpuset.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_CPUSET_H
+#define _RTEMS_SCORE_CPUSET_H
+
+#include <rtems/score/basedefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __RTEMS_HAVE_SYS_CPUSET_H__
+
+/**
+ * @defgroup ScoreCpuset Handler
+ *
+ * @ingroup Score
+ *
+ * This handler encapsulates functionality which is used in the management
+ * of thread's cpuset.
+ */
+/**@{*/
+
+/**
+ * The following defines the control block used to manage the cpuset.
+ */
+typedef struct {
+ /** This is the size of the affinity set */
+ size_t setsize;
+ /** This is the preallocated space to store the affinity set */
+ cpu_set_t preallocated;
+ /** This is a pointer to the affinity set in use */
+ cpu_set_t *set;
+} Cpuset_Control;
+
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/cpusetimpl.h b/cpukit/score/include/rtems/score/cpusetimpl.h
new file mode 100644
index 0000000..8ec5609
--- /dev/null
+++ b/cpukit/score/include/rtems/score/cpusetimpl.h
@@ -0,0 +1,87 @@
+/**
+ * @file rtems/score/cpusetimpl.h
+ *
+ * @brief Implementation prototypes for cpuset
+ *
+ * This file contains the implementation prototypes for
+ * cpuset methods.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_CPUSETIMPL_H
+#define _RTEMS_SCORE_CPUSETIMPL_H
+
+#include <rtems/score/cpuset.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __RTEMS_HAVE_SYS_CPUSET_H__
+
+/**
+ * _Cpuset_Handler_is_valid
+ *
+ * This routine validates a cpuset size corresponds to
+ * the system correct size, that at least one
+ * valid cpu is set and that no invalid cpus are set.
+ */
+int _Cpuset_Handler_is_valid( const cpu_set_t *cpuset, size_t setsize );
+
+/**
+ * rtems_cpuset_show
+ *
+ * This routine will print the value of the given cpuset.
+ */
+void rtems_cpuset_show( const char *description, const cpu_set_t *cpuset);
+
+/**
+ * rtems_cpuset_show_default
+ *
+ * This routine will print the value of the default cpuset.
+ */
+void rtems_cpuset_show_default( const char *description );
+
+#endif
+
+/**
+ * _Cpuset_Handler_default
+ *
+ * This routine returns the default cpuset for
+ * this system.
+ */
+#if __RTEMS_HAVE_SYS_CPUSET_H__ && defined( RTEMS_SMP )
+const Cpuset_Control *_Cpuset_Handler_default(void);
+#else
+#define _Cpuset_Handler_default() do { } while ( 0 )
+#endif
+
+/**
+ * _Cpuset_Handler_initialization
+ *
+ * This routine validates a cpuset sets at least one
+ * valid cpu and that it does not set any invalid
+ * cpus.
+ */
+
+#if __RTEMS_HAVE_SYS_CPUSET_H__ && defined( RTEMS_SMP )
+void _Cpuset_Handler_initialization(void);
+#else
+#define _Cpuset_Handler_initialization() do { } while ( 0 )
+#endif
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* end of include file */
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index bf500fe..828828a 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -31,6 +31,13 @@
#include <rtems/score/threadq.h>
#include <rtems/score/watchdog.h>
+#ifdef RTEMS_SMP
+#if __RTEMS_HAVE_SYS_CPUSET_H__
+#include <sys/cpuset.h>
+#include <rtems/score/cpuset.h>
+#endif
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -406,7 +413,18 @@ struct Thread_Control_struct {
* happen in the meantime.
*/
bool is_executing;
+
+#if __RTEMS_HAVE_SYS_CPUSET_H__
+ /**
+ * @brief This field controls affinity attributes for this thread.
+ *
+ * Affinity attributes indicate which cpus the thread can run on
+ * in an SMP system.
+ */
+ Cpuset_Control affinity;
+#endif
#endif
+
#if __RTEMS_ADA__
/** This field is the GNAT self context pointer. */
void *rtems_ada_self;
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index 4d36ebe..051582c 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -99,6 +99,14 @@ $(PROJECT_INCLUDE)/rtems/score/coresemimpl.h: include/rtems/score/coresemimpl.h
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/coresemimpl.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/coresemimpl.h
+$(PROJECT_INCLUDE)/rtems/score/cpuset.h: include/rtems/score/cpuset.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpuset.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpuset.h
+
+$(PROJECT_INCLUDE)/rtems/score/cpusetimpl.h: include/rtems/score/cpusetimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/cpusetimpl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/cpusetimpl.h
+
$(PROJECT_INCLUDE)/rtems/score/heap.h: include/rtems/score/heap.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/heap.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/heap.h
diff --git a/cpukit/score/src/cpuset.c b/cpukit/score/src/cpuset.c
new file mode 100644
index 0000000..f4c0001
--- /dev/null
+++ b/cpukit/score/src/cpuset.c
@@ -0,0 +1,92 @@
+/**
+ * @file
+ *
+ * @ingroup
+ *
+ * @brief score cpuset Handler.
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef RTEMS_SMP
+#if HAVE_SYS_CPUSET_H
+#include <sys/cpuset.h>
+#include <rtems/score/cpusetimpl.h>
+#include <rtems/score/assert.h>
+#include <rtems/score/percpu.h>
+
+static Cpuset_Control _Default_Cpuset;
+
+/*
+ * _Cpuset_Handler_initialization
+ */
+void _Cpuset_Handler_initialization()
+{
+ int i;
+ int max_cpus = 1;
+
+ /* We do not support a cpu count over CPU_SETSIZE */
+ max_cpus = _SMP_Get_processor_count();
+
+ /* This should never happen */
+ _Assert( max_cpus <= CPU_SETSIZE );
+
+ /* Initialize the affinity to be the set of all available CPU's */
+ _Default_Cpuset.set = &_Default_Cpuset.preallocated;
+ _Default_Cpuset.setsize = sizeof( *_Default_Cpuset.set );
+ CPU_ZERO_S( _Default_Cpuset.setsize, &_Default_Cpuset.preallocated );
+
+ for (i=0; i<max_cpus; i++)
+ CPU_SET_S(i, _Default_Cpuset.setsize, _Default_Cpuset.set );
+}
+
+/**
+ * _Affinity_Handler_is_valid
+ *
+ * This routine validates a cpuset size corresponds to
+ * the system correct size, that at least one
+ * valid cpu is set and that no invalid cpus are set.
+ */
+int _Cpuset_Handler_is_valid( const cpu_set_t *cpuset, size_t setsize )
+{
+ cpu_set_t temp;
+
+ if ( !cpuset )
+ return -1;
+
+ if (setsize != _Default_Cpuset.setsize )
+ return -1;
+
+ /* Validate at least 1 valid cpu is set in cpuset */
+ CPU_AND_S( _Default_Cpuset.setsize, &temp, cpuset, _Default_Cpuset.set );
+
+ if ( CPU_COUNT_S( setsize, &temp ) == 0 )
+ return -1;
+
+ /* Validate that no invalid cpu's are set in cpuset */
+ if ( !CPU_EQUAL_S( setsize, &temp, cpuset ) )
+ return -1;
+
+ return 0;
+}
+
+const Cpuset_Control *_Cpuset_Handler_default()
+{
+ return &_Default_Cpuset;
+}
+
+#endif
+#endif
+
+
diff --git a/cpukit/score/src/cpusetprintsupport.c b/cpukit/score/src/cpusetprintsupport.c
new file mode 100644
index 0000000..2029830
--- /dev/null
+++ b/cpukit/score/src/cpusetprintsupport.c
@@ -0,0 +1,84 @@
+/**
+ * @file
+ *
+ * @brief cpuset support
+ * @ingroup XXX XXX
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <inttypes.h>
+#include <rtems/bspIo.h>
+#include <rtems/score/cpusetimpl.h>
+
+#if HAVE_SYS_CPUSET_H
+
+ void rtems_cpuset_show_with_plugin(
+ void *context,
+ rtems_printk_plugin_t print,
+ const char *description,
+ const cpu_set_t *cpuset
+ );
+
+ /*
+ * rtems_cpuset_show_with_plugin
+ *
+ * This routine shows cpuset cpuset using a
+ * print plugin .
+ */
+ void rtems_cpuset_show_with_plugin(
+ void *context,
+ rtems_printk_plugin_t print,
+ const char *description,
+ const cpu_set_t *cpuset
+ )
+ {
+ int i;
+
+ if ( !print )
+ return;
+
+ (*print)(context ,"%s: ", description);
+ for(i=0; i<_NCPUWORDS; i++)
+ (*print)(context ,"%x", cpuset->__bits[i]);
+ (*print)(context ,"\n");
+ }
+
+ /*
+ * rtems_cpuset_show
+ *
+ * This routine shows a cpuset using the
+ * printk plugin.
+ */
+ void rtems_cpuset_show( const char *description, const cpu_set_t *cpuset)
+ {
+ rtems_cpuset_show_with_plugin( NULL, printk_plugin, description, cpuset );
+ }
+
+ /*
+ * rtems_cpuset_show_default
+ *
+ * This routine shows the default cpuset.
+ */
+ void rtems_cpuset_show_default( const char *description )
+ {
+ const Cpuset_Control *ctl;
+ ctl = _Cpuset_Handler_default();
+ rtems_cpuset_show( description, ctl->set );
+ }
+#endif
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index bc2600a..e18e1bc 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -24,6 +24,7 @@
#include <rtems/score/userextimpl.h>
#include <rtems/score/watchdogimpl.h>
#include <rtems/score/wkspace.h>
+#include <rtems/score/cpusetimpl.h>
#include <rtems/config.h>
bool _Thread_Initialize(
@@ -201,6 +202,10 @@ bool _Thread_Initialize(
/* Initialize the cpu field for the non-SMP schedulers */
the_thread->cpu = _Per_CPU_Get_by_index( 0 );
+#if __RTEMS_HAVE_SYS_CPUSET_H__
+ the_thread->affinity = *_Cpuset_Handler_default();
+ the_thread->affinity.set = &the_thread->affinity.preallocated;
+#endif
#endif
the_thread->current_state = STATES_DORMANT;
--
1.8.1.4
From ebcadbfd40eae57c43d885fd2d893c4840b12a5d Mon Sep 17 00:00:00 2001
From: Jennifer Averett <jennifer.aver...@oarcorp.com>
Date: Mon, 27 Jan 2014 13:55:58 -0600
Subject: [PATCH 03/19] sapi: Moved smp initialization and added cpuset
initilization.
sapi: Initialize score cpuset handler.
---
cpukit/sapi/src/exinit.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c
index d265455..ac8ea33 100644
--- a/cpukit/sapi/src/exinit.c
+++ b/cpukit/sapi/src/exinit.c
@@ -40,6 +40,7 @@
#include <rtems/score/apiext.h>
#include <rtems/score/apimutex.h>
#include <rtems/score/copyrt.h>
+#include <rtems/score/cpusetimpl.h>
#include <rtems/score/heap.h>
#include <rtems/score/interr.h>
#include <rtems/score/isr.h>
@@ -134,6 +135,10 @@ void rtems_initialize_data_structures(void)
_MPCI_Handler_initialization( RTEMS_TIMEOUT );
#endif
+ _SMP_Handler_initialize();
+
+ _Cpuset_Handler_initialization();
+
/* MANAGERS */
_RTEMS_API_Initialize();
@@ -146,8 +151,6 @@ void rtems_initialize_data_structures(void)
_POSIX_API_Initialize();
#endif
- _SMP_Handler_initialize();
-
_System_state_Set( SYSTEM_STATE_BEFORE_MULTITASKING );
/*
--
1.8.1.4
From cd688e7dc9667f2482c6203f1159d98f9cad4e5e Mon Sep 17 00:00:00 2001
From: Jennifer Averett <jennifer.aver...@oarcorp.com>
Date: Mon, 10 Feb 2014 12:30:39 -0600
Subject: [PATCH 04/19] rtems: Add classic get and set affinity methods.
---
cpukit/rtems/Makefile.am | 7 +++
cpukit/rtems/include/rtems/rtems/tasks.h | 37 ++++++++++++++++
cpukit/rtems/src/taskgetaffinity.c | 76 ++++++++++++++++++++++++++++++++
cpukit/rtems/src/tasksetaffinity.c | 73 ++++++++++++++++++++++++++++++
4 files changed, 193 insertions(+)
create mode 100644 cpukit/rtems/src/taskgetaffinity.c
create mode 100644 cpukit/rtems/src/tasksetaffinity.c
diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am
index ea461de..f89a896 100644
--- a/cpukit/rtems/Makefile.am
+++ b/cpukit/rtems/Makefile.am
@@ -269,5 +269,12 @@ librtems_a_SOURCES += src/signalmp.c
librtems_a_SOURCES += src/taskmp.c
endif
+## SMP Files
+if HAS_SMP
+librtems_a_SOURCES += src/tasksetaffinity.c
+librtems_a_SOURCES += src/taskgetaffinity.c
+endif
+
+
include $(srcdir)/preinstall.am
include $(top_srcdir)/automake/local.am
diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h
index 2030632..d54e8e4 100644
--- a/cpukit/rtems/include/rtems/rtems/tasks.h
+++ b/cpukit/rtems/include/rtems/rtems/tasks.h
@@ -491,6 +491,43 @@ rtems_status_code rtems_task_variable_delete(
);
/**
+ * @brief RTEMS Get Task Affinity
+ *
+ * This directive returns the cpuset for the
+ * given task. The cpuset size must be the
+ * same size as the task affinity set size.
+ *
+ * @param[in] id is the thread to extract
+ * @param[in] cpusetsize is the size of the cpuset
+ * @param[out] cpuset is the tasks affinity cpuset
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_task_get_affinity(
+ rtems_id id,
+ size_t cpusetsize,
+ cpu_set_t *cpuset
+);
+
+/**
+ * @brief RTEMS Set Task Affinity
+ *
+ * This directive sets the given tasks
+ * affinity cpuset.
+ *
+ * @param[in] id is the thread to extract
+ * @param[in] cpusetsize is the size of the cpuset
+ * @param[in] cpuset is affinity set to assign to the task
+ *
+ * @retval RTEMS_SUCCESSFUL if successful or error code if unsuccessful
+ */
+rtems_status_code rtems_task_set_affinity(
+ rtems_id id,
+ size_t cpusetsize,
+ cpu_set_t *cpuset
+);
+
+/**
* @brief RTEMS Get Self Task Id
*
* This directive returns the ID of the currently executing task.
diff --git a/cpukit/rtems/src/taskgetaffinity.c b/cpukit/rtems/src/taskgetaffinity.c
new file mode 100644
index 0000000..a9da091
--- /dev/null
+++ b/cpukit/rtems/src/taskgetaffinity.c
@@ -0,0 +1,76 @@
+/**
+ * @file
+ *
+ * @brief RTEMS Task Get Affinity
+ * @ingroup ClassicTasks Tasks
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/cpusetimpl.h>
+
+#if HAVE_SYS_CPUSET_H
+
+/*
+ * rtems_task_get_affinity
+ *
+ * This directive gets the task affinity.
+ *
+ * Input parameters:
+ * id - thread id
+ * cpusetsize - size of cpuset
+ * cpuset - cpuset associated with the thread
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ */
+
+rtems_status_code rtems_task_get_affinity(
+ rtems_id id,
+ size_t cpusetsize,
+ cpu_set_t *cpuset
+)
+{
+ Thread_Control *the_thread;
+ Objects_Locations location;
+ rtems_status_code status = RTEMS_SUCCESSFUL;
+
+ if (!cpuset)
+ return RTEMS_UNSATISFIED;
+
+ the_thread = _Thread_Get( id, &location );
+
+ switch ( location ) {
+
+ case OBJECTS_LOCAL:
+ if (cpusetsize != the_thread->affinity.setsize)
+ status = RTEMS_UNSATISFIED;
+ else
+ CPU_COPY( cpuset, the_thread->affinity.set );
+ _Objects_Put( &the_thread->Object );
+ return status;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ case OBJECTS_REMOTE:
+#endif
+
+ case OBJECTS_ERROR:
+ break;
+ }
+
+ return RTEMS_INVALID_ID;
+}
+#endif
diff --git a/cpukit/rtems/src/tasksetaffinity.c b/cpukit/rtems/src/tasksetaffinity.c
new file mode 100644
index 0000000..26617f4
--- /dev/null
+++ b/cpukit/rtems/src/tasksetaffinity.c
@@ -0,0 +1,73 @@
+/**
+ * @file
+ *
+ * @brief RTEMS Task Set Affinity
+ * @ingroup ClassicTasks Tasks
+ */
+
+/*
+ * COPYRIGHT (c) 1989-2014.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/rtems/tasks.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/cpusetimpl.h>
+
+#if HAVE_SYS_CPUSET_H
+
+/*
+ * rtems_task_set_affinity
+ *
+ * This directive sets the task affinity.
+ *
+ * Input parameters:
+ * id - thread id
+ * cpusetsize - size of cpuset
+ *
+ * Output parameters:
+ * RTEMS_SUCCESSFUL - if successful
+ * cpuset - cpuset associated with the thread
+ */
+
+rtems_status_code rtems_task_set_affinity(
+ rtems_id id,
+ size_t cpusetsize,
+ cpu_set_t *cpuset
+)
+{
+ Thread_Control *the_thread;
+ Objects_Locations location;
+ int error;
+
+ error = _Cpuset_Handler_is_valid( cpuset, cpusetsize );
+ if ( error != 0 )
+ return RTEMS_UNSATISFIED;
+
+ the_thread = _Thread_Get( id, &location );
+ switch ( location ) {
+
+ case OBJECTS_LOCAL:
+ CPU_COPY( the_thread->affinity.set, cpuset );
+ _Objects_Put( &the_thread->Object );
+ return RTEMS_SUCCESSFUL;
+
+#if defined(RTEMS_MULTIPROCESSING)
+ case OBJECTS_REMOTE:
+#endif
+
+ case OBJECTS_ERROR:
+ break;
+ }
+
+ return RTEMS_INVALID_ID;
+}
+#endif
--
1.8.1.4
From 912cecad73bce8c73a3e4d57d306356c193c5556 Mon Sep 17 00:00:00 2001
From: Jennifer Averett <jennifer.aver...@oarcorp.com>
Date: Mon, 10 Feb 2014 12:31:59 -0600
Subject: [PATCH 17/19] smptests: Add smpaffinity01
Test the classic get and set affinity methods.
---
testsuites/smptests/Makefile.am | 1 +
testsuites/smptests/configure.ac | 1 +
testsuites/smptests/smpaffinity01/Makefile.am | 19 ++
testsuites/smptests/smpaffinity01/init.c | 249 +++++++++++++++++++++
.../smptests/smpaffinity01/smpaffinity01.doc | 12 +
.../smptests/smpaffinity01/smpaffinity01.scn | 2 +
6 files changed, 284 insertions(+)
create mode 100644 testsuites/smptests/smpaffinity01/Makefile.am
create mode 100644 testsuites/smptests/smpaffinity01/init.c
create mode 100644 testsuites/smptests/smpaffinity01/smpaffinity01.doc
create mode 100644 testsuites/smptests/smpaffinity01/smpaffinity01.scn
diff --git a/testsuites/smptests/Makefile.am b/testsuites/smptests/Makefile.am
index 023b7e9..19dd1e7 100644
--- a/testsuites/smptests/Makefile.am
+++ b/testsuites/smptests/Makefile.am
@@ -10,6 +10,7 @@ SUBDIRS += smp05
SUBDIRS += smp07
SUBDIRS += smp08
SUBDIRS += smp09
+SUBDIRS += smpaffinity01
SUBDIRS += smpatomic01
SUBDIRS += smplock01
SUBDIRS += smpmigration01
diff --git a/testsuites/smptests/configure.ac b/testsuites/smptests/configure.ac
index 5c68772..29f963e 100644
--- a/testsuites/smptests/configure.ac
+++ b/testsuites/smptests/configure.ac
@@ -64,6 +64,7 @@ smp05/Makefile
smp07/Makefile
smp08/Makefile
smp09/Makefile
+smpaffinity01/Makefile
smpatomic01/Makefile
smplock01/Makefile
smpmigration01/Makefile
diff --git a/testsuites/smptests/smpaffinity01/Makefile.am b/testsuites/smptests/smpaffinity01/Makefile.am
new file mode 100644
index 0000000..d58940a
--- /dev/null
+++ b/testsuites/smptests/smpaffinity01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpaffinity01
+smpaffinity01_SOURCES = init.c
+
+dist_rtems_tests_DATA = smpaffinity01.scn smpaffinity01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(smpaffinity01_OBJECTS)
+LINK_LIBS = $(smpaffinity01_LDLIBS)
+
+smpaffinity01$(EXEEXT): $(smpaffinity01_OBJECTS) $(smpaffinity01_DEPENDENCIES)
+ @rm -f smpaffinity01$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpaffinity01/init.c b/testsuites/smptests/smpaffinity01/init.c
new file mode 100644
index 0000000..39a3965
--- /dev/null
+++ b/testsuites/smptests/smpaffinity01/init.c
@@ -0,0 +1,249 @@
+/*
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NUM_CPUS 4
+
+#include "tmacros.h"
+
+#if HAVE_SYS_CPUSET_H
+
+rtems_id Init_id;
+rtems_id Med_id[NUM_CPUS-1];
+rtems_id Low_id[NUM_CPUS];
+
+/* forward declarations to avoid warnings */
+void Task_1(rtems_task_argument arg);
+void Validate_setaffinity_errors(void);
+void Validate_getaffinity_errors(void);
+void Validate_affinity(void);
+
+void Task_1(rtems_task_argument arg)
+{
+ while(1);
+}
+
+void Validate_setaffinity_errors(void)
+{
+ int sc;
+ cpu_set_t cpuset;
+
+ /* Verify rtems_task_set_affinity checks that all cpu's exist. */
+ /* XXX - This test breaks on a system with over 32 CPU's */
+ CPU_FILL(&cpuset);
+ puts( "Init - rtems_task_set_affinity - Invalid cpu - RTEMS_UNSATISFIED" );
+ sc = rtems_task_set_affinity( Init_id, sizeof(cpu_set_t), &cpuset );
+ rtems_test_assert( sc == RTEMS_UNSATISFIED );
+
+ /* Verify rtems_task_set_affinity checks that at least one cpu is set */
+ CPU_ZERO(&cpuset);
+ puts( "Init - rtems_task_set_affinity - no cpu - RTEMS_UNSATISFIED" );
+ sc = rtems_task_set_affinity( Init_id, sizeof(cpu_set_t), &cpuset );
+ rtems_test_assert( sc == RTEMS_UNSATISFIED );
+
+ /* Verify rtems_task_set_affinity checks that at thread id is valid */
+ CPU_SET(0, &cpuset);
+ puts( "Init - rtems_task_set_affinity - Invalid thread - RTEMS_INVALID_ID" );
+ sc = rtems_task_set_affinity( 999, sizeof(cpu_set_t), &cpuset );
+ rtems_test_assert( sc == RTEMS_INVALID_ID );
+
+ /* Verify rtems_task_set_affinity validates cpusetsize */
+ puts( "Init - rtems_task_set_affinity - Invalid cpusetsize - RTEMS_UNSATISFIED" );
+ sc = rtems_task_set_affinity( Init_id, sizeof(cpu_set_t) * 2, &cpuset );
+ rtems_test_assert( sc == RTEMS_UNSATISFIED );
+
+ /* Verifyrtems_task_set_affinity validates cpuset */
+ puts( "Init - rtems_task_set_affinity - Invalid cpuset - RTEMS_UNSATISFIED" );
+ sc = rtems_task_set_affinity( Init_id, sizeof(cpu_set_t), NULL );
+ rtems_test_assert( sc == RTEMS_UNSATISFIED );
+}
+
+void Validate_getaffinity_errors(void)
+{
+ int sc;
+ cpu_set_t cpuset;
+
+ /* Verify rtems_task_get_affinity checks that at thread id is valid */
+ CPU_SET(0, &cpuset);
+ puts( "Init - rtems_task_get_affinity - Invalid thread - RTEMS_INVALID_ID" );
+ sc = rtems_task_get_affinity( 999, sizeof(cpu_set_t), &cpuset );
+ rtems_test_assert( sc == RTEMS_INVALID_ID );
+
+ /* Verify rtems_task_get_affinity validates cpusetsize */
+ puts(
+ "Init -rtems_task_get_affinity - Invalid cpusetsize - RTEMS_UNSATISFIED"
+ );
+ sc = rtems_task_get_affinity( Init_id, sizeof(cpu_set_t) * 2, &cpuset );
+ rtems_test_assert( sc == RTEMS_UNSATISFIED );
+
+ /* Verify rtems_task_get_affinity validates cpuset */
+ puts("Init - rtems_task_get_affinity - Invalid cpuset - RTEMS_UNSATISFIED");
+ sc = rtems_task_get_affinity( Init_id, sizeof(cpu_set_t), NULL );
+ rtems_test_assert( sc == RTEMS_UNSATISFIED );
+}
+
+void Validate_affinity(void )
+{
+ cpu_set_t cpuset0;
+ cpu_set_t cpuset1;
+ cpu_set_t cpuset2;
+ uint32_t i;
+ int sc;
+ int cpu_count;
+ rtems_task_priority priority;
+ char ch[2];
+
+
+ puts( "Init - Set Init priority to high");
+ sc = rtems_task_set_priority( Init_id, 1, &priority );
+ directive_failed( sc, "Set Init Priority" );
+
+ sc = rtems_task_get_affinity( Init_id, sizeof(cpu_set_t), &cpuset0 );
+ directive_failed( sc, "Get Affinity of Init Task" );
+
+ /* Get the number of processors that we are using. */
+ cpu_count = rtems_smp_get_processor_count();
+
+ /* Fill the remaining cpus with med priority tasks */
+ puts( "Init - Create Medium priority tasks");
+ for (i=0; i<(cpu_count-1); i++){
+ sprintf(ch, "%01" PRId32, i+1 );
+ sc = rtems_task_create(
+ rtems_build_name( 'C', 'P', 'U', ch[0] ),
+ 2,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &Med_id[i]
+ );
+ directive_failed( sc, "task create" );
+
+ sc = rtems_task_start( Med_id[i], Task_1, i+1 );
+ directive_failed( sc, "task start" );
+
+ sc = rtems_task_get_affinity( Med_id[i], sizeof(cpu_set_t), &cpuset2 );
+ directive_failed( sc, "Get Affinity of Medium Priority Task" );
+ rtems_test_assert( CPU_EQUAL(&cpuset0, &cpuset2) );
+ }
+
+ /*
+ * Create low priority thread for each remaining cpu with the affinity
+ * set to only run on one cpu.
+ */
+ puts( "Init - Create Low priority tasks");
+ for (i=0; i<cpu_count; i++){
+ CPU_ZERO(&cpuset1);
+ CPU_SET(i, &cpuset1);
+
+ sprintf(ch, "%01" PRId32, (uint32_t) 0 );
+ sc = rtems_task_create(
+ rtems_build_name( 'X', 'T', 'R', ch[0] ),
+ 10,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &Low_id[i]
+ );
+ directive_failed( sc, "task create" );
+
+ sc = rtems_task_set_affinity( Low_id[i], sizeof(cpu_set_t), &cpuset1 );
+ directive_failed( sc, "Low priority task set affinity" );
+
+ sc = rtems_task_start( Low_id[i], Task_1, i+1 );
+ directive_failed( sc, "task start" );
+ }
+
+
+ /* Verify affinity on low priority tasks */
+ puts("Init - Verify affinity on Low priority tasks");
+ for (i=0; i<cpu_count; i++){
+ CPU_ZERO(&cpuset1);
+ CPU_SET(i, &cpuset1);
+
+ sc = rtems_task_get_affinity( Low_id[i], sizeof(cpu_set_t), &cpuset2 );
+ directive_failed( sc, "Low priority task get affinity" );
+ rtems_test_assert( CPU_EQUAL(&cpuset1, &cpuset2) );
+ }
+
+ /* Change the affinity for each low priority task */
+ puts("Init - Change affinity on Low priority tasks");
+ CPU_COPY(&cpuset1, &cpuset0);
+ for (i=0; i<cpu_count; i++){
+
+ CPU_CLR(i, &cpuset1);
+ sc = rtems_task_set_affinity( Low_id[i], sizeof(cpu_set_t), &cpuset1 );
+
+ /* Verify no cpu's are now set in the cpuset */
+ if (i== (cpu_count-1)) {
+ rtems_test_assert( sc == RTEMS_UNSATISFIED );
+ sc = rtems_task_set_affinity( Low_id[i], sizeof(cpu_set_t), &cpuset0 );
+ }
+
+ directive_failed( sc, "Low priority task set affinity" );
+ }
+
+ puts("Init - Validate affinity on Low priority tasks");
+ CPU_COPY(&cpuset1, &cpuset0);
+ for (i=0; i<cpu_count; i++){
+ CPU_CLR(i, &cpuset1);
+
+ sc = rtems_task_get_affinity( Low_id[i], sizeof(cpu_set_t), &cpuset2 );
+ directive_failed( sc, "Low priority task get affinity" );
+ if (i== (cpu_count-1))
+ rtems_test_assert( CPU_EQUAL(&cpuset0, &cpuset2) );
+ else
+ rtems_test_assert( CPU_EQUAL(&cpuset1, &cpuset2) );
+ }
+}
+
+static void Init(rtems_task_argument arg)
+{
+ int sc;
+
+ puts( "\n\n*** SMP AFFINITY 1 ***" );
+
+ /* Initialize thread id */
+ sc = rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &Init_id );
+ directive_failed( sc, "Identify Init Task" );
+
+ Validate_setaffinity_errors();
+ Validate_getaffinity_errors();
+ Validate_affinity();
+
+ puts( "*** END OF SMP AFFINITY TEST 1 ***" );
+ rtems_test_exit(0);
+}
+
+#else
+static void Init(rtems_task_argument arg)
+{
+ puts( "\n\n*** SMP AFFINITY TEST 1 ***" );
+ puts( " Affinity NOT Supported");
+ puts( "*** END OF SMP AFFINITY TEST 1 ***" );
+ rtems_test_exit(0);
+}
+
+#endif
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_SMP_APPLICATION
+
+#define CONFIGURE_SMP_MAXIMUM_PROCESSORS NUM_CPUS
+
+#define CONFIGURE_MAXIMUM_TASKS (NUM_CPUS*2)
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/smptests/smpaffinity01/smpaffinity01.doc b/testsuites/smptests/smpaffinity01/smpaffinity01.doc
new file mode 100644
index 0000000..98a2a85
--- /dev/null
+++ b/testsuites/smptests/smpaffinity01/smpaffinity01.doc
@@ -0,0 +1,12 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpsignal01
+
+directives:
+
+ - rtems_signal_catch()
+ - rtems_signal_send()
+
+concepts:
+
+ - Ensure that Classic Signals work on SMP.
diff --git a/testsuites/smptests/smpaffinity01/smpaffinity01.scn b/testsuites/smptests/smpaffinity01/smpaffinity01.scn
new file mode 100644
index 0000000..fe394a0
--- /dev/null
+++ b/testsuites/smptests/smpaffinity01/smpaffinity01.scn
@@ -0,0 +1,2 @@
+*** TEST SMPSIGNAL 1 ***
+*** END OF TEST SMPSIGNAL 1 ***
--
1.8.1.4
_______________________________________________
rtems-devel mailing list
rtems-devel@rtems.org
http://www.rtems.org/mailman/listinfo/rtems-devel