Skip to content

Commit 91ddb9d

Browse files
committed
Fix #1548, Adding SMP API to OSAL
1 parent c7f57b7 commit 91ddb9d

26 files changed

Lines changed: 1008 additions & 3 deletions

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ set(OSAL_SRCLIST
354354
src/os/shared/src/osapi-mutex.c
355355
src/os/shared/src/osapi-network.c
356356
src/os/shared/src/osapi-printf.c
357+
src/os/shared/src/osapi-task-affinity.c
357358
src/os/shared/src/osapi-queue.c
358359
src/os/shared/src/osapi-rwlock.c
359360
src/os/shared/src/osapi-select.c

default_config.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ set(OSAL_CONFIG_QUEUE_MAX_DEPTH 50
395395
CACHE STRING "Maximum depth of message queue"
396396
)
397397

398+
# The maximum number of CPUs supported.
399+
set(OSAL_CONFIG_MAX_CPUS 1
400+
CACHE STRING "Maximum number of CPUs supported"
401+
)
402+
398403
# Flags added to all tasks on creation
399404
#
400405
# Some OS's use floating point under the hood, this supports

osconfig.h.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,13 @@
232232
*/
233233
#define OS_QUEUE_MAX_DEPTH @OSAL_CONFIG_QUEUE_MAX_DEPTH@
234234

235+
/**
236+
* \brief The maximum number of CPUs to support
237+
*
238+
* Based on the OSAL_CONFIG_MAX_CPUS configuration option
239+
*/
240+
#define OS_MAX_CPUS @OSAL_CONFIG_MAX_CPUS@
241+
235242
/**
236243
* \brief The name of the temporary file used to store shell commands
237244
*

src/os/inc/osapi-task-affinity.h

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/************************************************************************
2+
* NASA Docket No. GSC-19,200-1, and identified as "cFS Draco"
3+
*
4+
* Copyright (c) 2023 United States Government as represented by the
5+
* Administrator of the National Aeronautics and Space Administration.
6+
* All Rights Reserved.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
9+
* not use this file except in compliance with the License. You may obtain
10+
* a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
************************************************************************/
18+
19+
/**
20+
* \file
21+
*
22+
* Declarations and prototypes for file objects
23+
*/
24+
25+
#ifndef OSAPI_TASK_AFFINITY_H
26+
#define OSAPI_TASK_AFFINITY_H
27+
28+
#include "common_types.h"
29+
#include "osconfig.h"
30+
31+
/**
32+
* @brief An abstract structure capable of holding a cpuset
33+
* Because standard integer types max out at 64 bits
34+
* OSAL uses an array of 8-bit bytes to store the mask so it can scale
35+
* to support any number of cores. Currently the max is 64 but this can
36+
* be used for more in the future.
37+
* if the number of bits doesn't divide perfectly by 8,
38+
* add one extra byte to the end to hold the remainders
39+
*/
40+
typedef struct
41+
{
42+
uint8 affinity_mask[(OS_MAX_CPUS + 7) / 8];
43+
} OS_cpuset_t;
44+
45+
/**
46+
* @name OSAL CPU Set Manipulation Macros
47+
* @{
48+
*/
49+
50+
/** @brief Initializes the CPU set to empty (clears all CPUs) */
51+
#define OS_CPUSET_ZERO(cpusetptr) memset((cpusetptr)->affinity_mask, 0, sizeof((cpusetptr)->affinity_mask))
52+
53+
/** @brief Adds a specific CPU to the CPU set */
54+
#define OS_CPUSET_SET(cpu, cpusetptr) \
55+
do \
56+
{ \
57+
if ((cpu) < OS_MAX_CPUS) \
58+
{ \
59+
(cpusetptr)->affinity_mask[(cpu) / 8] |= (1U << ((cpu) % 8)); \
60+
} \
61+
} while (0)
62+
63+
/** @brief Removes a specific CPU from the CPU set */
64+
#define OS_CPUSET_CLR(cpu, cpusetptr) \
65+
do \
66+
{ \
67+
if ((cpu) < OS_MAX_CPUS) \
68+
{ \
69+
(cpusetptr)->affinity_mask[(cpu) / 8] &= ~(1U << ((cpu) % 8)); \
70+
} \
71+
} while (0)
72+
73+
/** @brief Checks if a specific CPU is in the CPU set (Evaluates to true/false) */
74+
#define OS_CPUSET_ISSET(cpu, cpusetptr) \
75+
(((cpu) < OS_MAX_CPUS) ? (((cpusetptr)->affinity_mask[(cpu) / 8] & (1U << ((cpu) % 8))) != 0) : 0)
76+
77+
/** @} */
78+
/*
79+
* ----------------------------------------------------------------------
80+
* The OS_TaskAffinityGetCoresConfigured() is an api call to obtain information from OS
81+
* for the number of configured cores
82+
*
83+
* Returns the number of configured cores
84+
* ----------------------------------------------------------------------
85+
*/
86+
uint32 OS_TaskAffinityGetCoresConfigured(void);
87+
88+
/*
89+
* ----------------------------------------------------------------------
90+
* The OS_TaskAffinityCoresConfigured() is an api call to return global information
91+
* from OSAL set at init for the number of configured cores.
92+
*
93+
* Returns the number of configured cores
94+
* ----------------------------------------------------------------------
95+
*/
96+
uint32 OS_TaskAffinityCoresConfigured(void);
97+
98+
/*
99+
* ----------------------------------------------------------------------
100+
* The OS_TaskAffinitySetAffinity() is an api call to set affinity to a task
101+
*
102+
* Sets an affinity from cpuset to task with provided task_id
103+
* ----------------------------------------------------------------------
104+
*/
105+
int32 OS_TaskAffinitySetAffinity(osal_id_t task_id, const OS_cpuset_t cpuset);
106+
107+
/*
108+
* ----------------------------------------------------------------------
109+
* The OS_TaskAffinityGetAffinity() is an api call to get affinity to a task
110+
*
111+
* Writes affinity to cpuset from task with provided task_id
112+
* ----------------------------------------------------------------------
113+
*/
114+
int32 OS_TaskAffinityGetAffinity(osal_id_t task_id, OS_cpuset_t *cpuset);
115+
116+
#endif /* OSAPI_TASK_AFFINITY_H */

src/os/inc/osapi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ extern "C"
8484
#include "osapi-shell.h"
8585
#include "osapi-sockets.h"
8686
#include "osapi-task.h"
87+
#include "osapi-task-affinity.h"
8788
#include "osapi-timebase.h"
8889
#include "osapi-timer.h"
8990

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/************************************************************************
2+
* NASA Docket No. GSC-19,200-1, and identified as "cFS Draco"
3+
*
4+
* Copyright (c) 2023 United States Government as represented by the
5+
* Administrator of the National Aeronautics and Space Administration.
6+
* All Rights Reserved.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
9+
* not use this file except in compliance with the License. You may obtain
10+
* a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
************************************************************************/
18+
19+
/**
20+
* \file
21+
*
22+
* This file Contains all of the api calls for manipulating files
23+
* in a file system / C library that implements the POSIX-style file API
24+
*/
25+
26+
/****************************************************************************************
27+
INCLUDE FILES
28+
***************************************************************************************/
29+
30+
/*
31+
* Inclusions Defined by OSAL layer.
32+
*
33+
*/
34+
35+
#include "os-impl-taskaffinity.h"
36+
#include "os-impl-tasks.h"
37+
#include "os-shared-idmap.h"
38+
#include "osapi-task-affinity.h"
39+
40+
/*
41+
** System Include Files
42+
*/
43+
#include <stdio.h>
44+
#include <string.h>
45+
#include <errno.h>
46+
#include <time.h>
47+
#include <stdlib.h>
48+
49+
/****************************************************************************************
50+
DEFINES
51+
***************************************************************************************/
52+
53+
/****************************************************************************************
54+
Named File API
55+
***************************************************************************************/
56+
/*
57+
* ----------------------------------------------------------------------
58+
* The OS_TaskAffinityGetCoresConfigured() is an api call to obtain information from OS
59+
* for the number of configured cores
60+
*
61+
* Returns the number of configured cores
62+
* ----------------------------------------------------------------------
63+
*/
64+
uint32 OS_TaskAffinityGetCoresConfigured_Impl(void)
65+
{
66+
return OS_TaskAffinity_Proc_Conf();
67+
}
68+
69+
/*
70+
* ----------------------------------------------------------------------
71+
* The OS_TaskAffinitySetAffinity() is an api call to set affinity to a task
72+
*
73+
* Sets an affinity from cpuset to task with provided task_id
74+
* ----------------------------------------------------------------------
75+
*/
76+
int32 OS_TaskAffinitySetAffinity_Impl(const OS_object_token_t *token, const OS_cpuset_t cpuset)
77+
{
78+
cpu_set_t lcl_cpuset;
79+
OS_impl_task_internal_record_t *impl;
80+
int32 return_value;
81+
uint32 i;
82+
83+
impl = OS_OBJECT_TABLE_GET(OS_impl_task_table, *token);
84+
85+
CPU_ZERO(&lcl_cpuset);
86+
87+
/* Populate POSIX cpuset from OSAL CPU Set using the macro */
88+
for (i = 0; (i < OS_MAX_CPUS) && (i < OS_TaskAffinityGetCoresConfigured()); i++)
89+
{
90+
/* Check if the bit is set in the OSAL structure */
91+
if (OS_CPUSET_ISSET(i, &cpuset))
92+
{
93+
/* If it is, set the corresponding bit in the POSIX structure */
94+
CPU_SET(i, &lcl_cpuset);
95+
}
96+
}
97+
98+
return_value = pthread_setaffinity_np(impl->id, sizeof(lcl_cpuset), &lcl_cpuset);
99+
100+
if (return_value == 0)
101+
{
102+
return OS_SUCCESS;
103+
}
104+
else
105+
{
106+
return OS_ERROR;
107+
}
108+
}
109+
110+
/*
111+
* ----------------------------------------------------------------------
112+
* The OS_TaskAffinityGetAffinity() is an api call to get affinity to a task
113+
*
114+
* Writes affinity to cpuset from task with provided task_id
115+
* ----------------------------------------------------------------------
116+
*/
117+
int32 OS_TaskAffinityGetAffinity_Impl(const OS_object_token_t *token, OS_cpuset_t *cpuset)
118+
{
119+
cpu_set_t local_cpuset;
120+
OS_impl_task_internal_record_t *impl;
121+
int32 return_value;
122+
uint32 i;
123+
124+
impl = OS_OBJECT_TABLE_GET(OS_impl_task_table, *token);
125+
126+
CPU_ZERO(&local_cpuset);
127+
return_value = pthread_getaffinity_np(impl->id, sizeof(local_cpuset), &local_cpuset);
128+
129+
if (return_value == 0)
130+
{
131+
/* Clear the OSAL affinity mask using the macro */
132+
OS_CPUSET_ZERO(cpuset);
133+
134+
/* Populate the OSAL affinity mask from the POSIX mask */
135+
for (i = 0; (i < OS_MAX_CPUS) && (i < OS_TaskAffinityGetCoresConfigured()); i++)
136+
{
137+
/* If the bit is set in the POSIX structure */
138+
if (CPU_ISSET(i, &local_cpuset))
139+
{
140+
/* set the corresponding bit in the OSAL structure */
141+
OS_CPUSET_SET(i, cpuset);
142+
}
143+
}
144+
145+
return OS_SUCCESS;
146+
}
147+
148+
return OS_ERROR;
149+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/************************************************************************
2+
* NASA Docket No. GSC-19,200-1, and identified as "cFS Draco"
3+
*
4+
* Copyright (c) 2023 United States Government as represented by the
5+
* Administrator of the National Aeronautics and Space Administration.
6+
* All Rights Reserved.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
9+
* not use this file except in compliance with the License. You may obtain
10+
* a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
************************************************************************/
18+
19+
/**
20+
* \file
21+
*
22+
* This file Contains all of the api calls for manipulating files
23+
* in a file system / C library that implements the POSIX-style file API
24+
*/
25+
26+
/****************************************************************************************
27+
INCLUDE FILES
28+
***************************************************************************************/
29+
30+
/*
31+
* Inclusions Defined by OSAL layer.
32+
*
33+
*/
34+
35+
#include "os-shared-idmap.h"
36+
#include "osapi-task-affinity.h"
37+
38+
/*
39+
** System Include Files
40+
*/
41+
#include <stdio.h>
42+
#include <string.h>
43+
#include <errno.h>
44+
#include <time.h>
45+
#include <stdlib.h>
46+
47+
/****************************************************************************************
48+
DEFINES
49+
***************************************************************************************/
50+
51+
/****************************************************************************************
52+
Named File API
53+
***************************************************************************************/
54+
/*
55+
* ----------------------------------------------------------------------
56+
* The OS_TaskAffinityGetCoresConfigured() is an api call to obtain information from OS
57+
* for the number of configured cores
58+
*
59+
* Returns the number of configured cores
60+
* ----------------------------------------------------------------------
61+
*/
62+
uint32 OS_TaskAffinityGetCoresConfigured_Impl(void)
63+
{
64+
return 1;
65+
}
66+
67+
/*
68+
* ----------------------------------------------------------------------
69+
* The OS_TaskAffinitySetAffinity() is an api call to set affinity to a task
70+
*
71+
* Sets an affinity from cpuset to task with provided task_id
72+
* ----------------------------------------------------------------------
73+
*/
74+
int32 OS_TaskAffinitySetAffinity_Impl(const OS_object_token_t *token, const OS_cpuset_t cpuset)
75+
{
76+
return OS_ERR_NOT_IMPLEMENTED;
77+
}
78+
79+
/*
80+
* ----------------------------------------------------------------------
81+
* The OS_TaskAffinityGetAffinity() is an api call to get affinity to a task
82+
*
83+
* Writes affinity to cpuset from task with provided task_id
84+
* ----------------------------------------------------------------------
85+
*/
86+
int32 OS_TaskAffinityGetAffinity_Impl(const OS_object_token_t *token, OS_cpuset_t *cpuset)
87+
{
88+
return OS_ERR_NOT_IMPLEMENTED;
89+
}

0 commit comments

Comments
 (0)