kernel: add per-thread errno support

Saves an errno per-thread, retrieved via _get_errno(), instead of
changing the value of a global variable during context switches to avoid
a hit to the context switch performance.

Per-arch asm implementations are provided for maximum performance.

Enabled by default, but can be disabled via the CONFIG_ERRNO option.

Change-Id: I81d57a2e318c94c68eee913ae0d4ca3a3609c7a4
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
Benjamin Walsh 2015-12-04 15:12:03 -05:00 committed by Anas Nashif
commit 3181df6db4
11 changed files with 143 additions and 1 deletions

View file

@ -13,3 +13,4 @@ obj-y += prep_c.o \
vector_table.o vector_table.o
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
obj-$(CONFIG_ERRNO) += errno.o

39
arch/arc/core/errno.S Normal file
View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2015 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @file
*
* @brief Per-thread errno accessor function
*
* Allow accessing the errno for the current thread without involving the
* context switching.
*/
#define _ASMLANGUAGE
#include <nano_private.h>
#include <offsets.h>
GTEXT(_nanokernel)
GTEXT(_get_errno)
SECTION_FUNC(TEXT, _get_errno)
mov_s r0, _nanokernel
ld_s r0, [r0, __tNANO_current_OFFSET]
add_s r0, r0, __tTCS_errno_var_OFFSET
j_s.nd [blink]
nop_s

View file

@ -180,6 +180,9 @@ struct tcs {
#ifdef CONFIG_NANO_TIMEOUTS #ifdef CONFIG_NANO_TIMEOUTS
struct _nano_timeout nano_timeout; struct _nano_timeout nano_timeout;
#endif #endif
#ifdef CONFIG_ERRNO
int errno_var;
#endif
}; };
struct s_NANO { struct s_NANO {

View file

@ -6,3 +6,5 @@ asflags-y = $(ccflags-y)
obj-y = vector_table.o reset.o \ obj-y = vector_table.o reset.o \
prep_c.o scs.o scb.o nmi.o \ prep_c.o scs.o scb.o nmi.o \
sw_isr_table.o sw_isr_table.o
obj-$(CONFIG_ERRNO) += errno.o

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2015 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @file
*
* @brief Per-thread errno accessor function
*
* Allow accessing the errno for the current thread without involving the
* context switching.
*/
#define _ASMLANGUAGE
#include <nano_private.h>
#include <offsets.h> /* nanokernel structure offset definitions */
_ASM_FILE_PROLOGUE
GTEXT(_nanokernel)
GTEXT(_get_errno)
SECTION_FUNC(TEXT, _get_errno)
ldr r0, =_nanokernel
ldr r0, [r0, #__tNANO_current_OFFSET]
adds.n r0, #__tTCS_errno_var_OFFSET
bx lr

View file

@ -125,6 +125,9 @@ struct tcs {
#ifdef CONFIG_NANO_TIMEOUTS #ifdef CONFIG_NANO_TIMEOUTS
struct _nano_timeout nano_timeout; struct _nano_timeout nano_timeout;
#endif #endif
#ifdef CONFIG_ERRNO
int errno_var;
#endif
}; };
struct s_NANO { struct s_NANO {

View file

@ -22,4 +22,4 @@ obj-y += gdt.o fatal.o cpuhalt.o \
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
obj-$(CONFIG_FP_SHARING) += float.o obj-$(CONFIG_FP_SHARING) += float.o
obj-$(CONFIG_MICROKERNEL) += strtask.o obj-$(CONFIG_MICROKERNEL) += strtask.o
obj-$(CONFIG_ERRNO) += errno.o

38
arch/x86/core/errno.S Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2015 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @file
*
* @brief Per-thread errno accessor function
*
* Allow accessing the errno for the current thread without involving the
* context switching.
*/
#define _ASMLANGUAGE
#include <nano_private.h>
#include <arch/x86/asm.h>
#include <offsets.h>
GTEXT(_nanokernel)
GTEXT(_get_errno)
SECTION_FUNC(TEXT, _get_errno)
movl _nanokernel + __tNANO_current_OFFSET, %eax
addl $__tTCS_errno_var_OFFSET, %eax
ret

View file

@ -663,6 +663,10 @@ struct tcs {
struct _nano_timeout nano_timeout; struct _nano_timeout nano_timeout;
#endif #endif
#ifdef CONFIG_ERRNO
int errno_var;
#endif
/* /*
* The location of all floating point related structures/fields MUST be * The location of all floating point related structures/fields MUST be
* located at the end of struct tcs. This way only the * located at the end of struct tcs. This way only the

View file

@ -82,4 +82,13 @@ config NANO_TIMERS
help help
Allow fibers and tasks to wait on nanokernel timers, which can be Allow fibers and tasks to wait on nanokernel timers, which can be
accessed using the nano_timer_xxx() APIs. accessed using the nano_timer_xxx() APIs.
config ERRNO
bool
prompt "Enable errno support"
default y
help
Enable per-thread errno in the kernel. Application and library code must
include errno.h provided by the C library (libc) to use the errno symbol.
The C library must access the per-thread errno via the _get_errno() symbol.
endmenu endmenu

View file

@ -56,6 +56,9 @@ GEN_OFFSET_SYM(tTCS, preempReg); /* start of prempt register set */
GEN_OFFSET_SYM(tTCS, next_thread); GEN_OFFSET_SYM(tTCS, next_thread);
#endif #endif
#ifdef CONFIG_ERRNO
GEN_OFFSET_SYM(tTCS, errno_var);
#endif
/* size of the entire struct tcs structure */ /* size of the entire struct tcs structure */