We can just implement this as a macro and not needlessly
run afoul of MISRC-C rule 17.1
Fixes: #10012
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This is an integral part of userspace and cannot be used
on its own. Fold into the main userspace configuration.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
User mode needs to be able to read this value in
compiler generated function prologues/epilogues.
Special handling in init.c for arches that use
_data_copy. This happens before _Cstart() gets
called. We need to make sure that the compiler
stack canary checks in _data_copy itself do not
fail.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
We need a generic name for the partition containing
essential C library globals. We're going to need to
add the stack canary guard to this area so user mode
can read it.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
Instead of having to enable ramfunc support manually, just make it
transparently available to users, keeping the MPU region disabled if not
used to not waste a MPU region. This however wastes 24 bytes of code
area when the MPU is disabled and 48 bytes when it is enabled, and
probably a dozen of CPU cycles during boot. I believe it is something
acceptable.
Note that when XIP is used, code is already in RAM, so the __ramfunc
keyword does nothing, but does not generate an error.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
The linker file defines the __ramfunc_ram_size symbols to get the size
of the __ramfunc_ram section. Use that instead of computing the value at
runtime from the start and end symbols. This saves 16 bytes of code with
CONFIG_RAM_FUNCTION=y.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Using __ramfunc to places a function in RAM instead of Flash.
Code that for example reprograms flash at runtime can't execute
from flash, in that case must placing code into RAM.
This commit create a new section named '.ramfunc' in link scripts,
all functions has __ramfunc keyword saved in thats sections and
will load from flash to sram after the system booted.
Fixes: #10253
Signed-off-by: qianfan Zhao <qianfanguijin@163.com>
This commit simplifies OS <-> Application interface controlling power
management. In the previous approach application-based PM required
overriding sys_suspend() and sys_resume() functions. As these functions
actually implemented power state change, in such case application
basically had to provide own implementation of all PM-related stuff,
which was not portable and hard to maintain.
This commit changes this scheme: The sys_suspend() and sys_resume()
are now system functions while the application could either use
built-in power management policies or provide its own. All details
of power mode switching are now handled by the OS.
Also, this commit cleans up the Kconfig options related to system-level
power management grouping them under common CONFIG_SYS_PM_ prefix.
Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no>
There are issues using lowercase min and max macros when compiling a C++
application with a third-party toolchain such as GNU ARM Embedded when
using some STL headers i.e. <chrono>.
This is because there are actual C++ functions called min and max
defined in some of the STL headers and these macros interfere with them.
By changing the macros to UPPERCASE, which is consistent with almost all
other pre-processor macros this naming conflict is avoided.
All files that use these macros have been updated.
Signed-off-by: Carlos Stuart <carlosstuart1970@gmail.com>
Work queues are implemented in terms of k_queue objects which provide
their own synchronization. In particular insertion is potentially
blocking and always acts as a reschedule point, which means that it
must not be called with spinlocks held.
Release the lock first, and do a little cleanup of the resulting
k_delayed_work_submit_to_queue() logic.
Fixes#13411
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Upon hard/soft irq or exception entry/exit, handle transitions
off or onto the trampoline stack, which is the only stack that
can be used on the kernel side when the shadow page table
is active. We swap page tables when on this stack.
Adjustments to page tables are now as follows:
- Any adjustments for stack memory access now are always done
to the user page tables
- Any adjustments for memory domains are now always done to
the user page tables
- With KPTI, resetting a page now clears the present bit
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
Minor style (syntax) fix in the help text of symbol
config EXECUTION_BENCHMARKING.
Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit changes the names of SYS_POWER_DEEP_SLEEP* Kconfig
options in order to match SYS_POWER_LOW_POWER_STATE* naming
scheme.
Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no>
The SYS_POWER_LOW_POWER_STATE_SUPPORTED and SYS_POWER_LOW_POWER_STATE
suggests one low power state but these options control multiple
low power state. This commit uses plural in the names to indicate
that.
Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no>
This API doesn't use the normal thread priority comparison itself, so
doesn't get the magic that thread_base.prio provides. If called when
another thread should be run, this would preempt the current thread
always, even if the scheduler lock was taken.
That was benign until recent spinlockifiation exposed it: a mutex in
the philosophers test run in preempt_only mode would swap away while
holding a spinlock (which used to work with irq locks) and fail later
with a "recursive" spinlock assert.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This port is a little different. Most subsystem synchronization uses
simple critical sections that can be replaced with global or
per-object spinlocks. But the userspace code was heavily exploiting
the fact that irq_lock was recursive and could be taken at any time.
So outer functions were doing locking and then calling into inner
helpers that would take their own lock (because they were called from
other contexts that did not lock).
Rather than try to rework this right now, this just creates a set of
spinlocks corresponding to the recursive states in which they are
taken, to preserve the existing semantics exactly.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Simple global lock around the timer API. Actually a lot of this usage
was using needless vestigial locking around existing scheduler and
timeout APIs that are now internally synchronized.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
One spinlock per pipe object. Also removed some vestigial locking
around _ready_thread(). That call is internally synchronized now.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The k_sleep() locking was actually to protect the _current state from
preemption before the context switch, so document that and replace
with a spinlock. Should probably unify this with the rather cleaner
logic in pend_curr(), but right now "sleeping" and "pended" are
needlessly distinct states.
And we can remove the locking entirely from k_wakeup(). There's no
reason for any of that to need to be synchronized. Even if we're
racing with other thread modifiations, the state on exit will be a
runnable thread without a timeout, or whatever timeout/pend state the
other side was requesting (i.e. it's a bug, but not one solved by
synhronization).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Use a subsystem lock, not a per-object lock. Really we want to lock
at mutex granularity where possible, but (1) that has non-trivial
memory overhead vs. e.g. directly spinning on the mutex state and (2)
the locking in a few places was originally designed to protect access
to the mutex *owner* priority, which is not 1:1 with a single mutex.
Basically the priority-inheriting mutex code will need some rework
before it works as a fine-grained locking abstraction in SMP.
Note that this fixes an invisible bug: with the older code,
k_mutex_unlock() would actually call irq_unlock() twice along the path
where there was a new owner, which is benign on existing architectures
(so long as the key argument is unchanged) but was never guaranteed to
work. With a spinlock, unlocking an unlocked/unowned lock is a
detectable assertion condition.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Straightforward port. Each struct k_queue object gets a spinlock to
control obvious data ownership.
Note that this port actually discovered a preexisting bug: the -ENOMEM
case in queue_insert() was failing to release the lock. But because
the tests that hit that path didn't rely on other threads being
scheduled, they ran to successful completion even with interrupts
disabled. The spinlock API detects that as a recursive lock when
asserts are enabled.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The two APIs protected by this lock are themselves internally
synchronized. Replace the irq_lock with a spinlock anyway, because
what I think it's doing is trying to prevent a race where something
else like an ISR or something it wakes up mucks with the thread before
this completes. Seems fragile on SMP as it stands, but this preserves
behavior on uniprocessor architectures.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Straightforward spinlock around the global thread state. Two changes
to the locking strategy were needed:
1. There was a needless recursive lock taken in schedule_new_thread().
This is only ever invoked in circumstances where the lock was already
held, or where there is no need for internal synchronization.
2. The recursive irq_lock() around the loop that spawns the initial
static threads (which happens at the start of main thread execution)
was removed. Most of the job (i.e. making sure the threads don't run
before the loop is finished) was already duplicated by the sched_lock
it was already taking, and the attempt to promise that all the
timeouts happen on the same tick is already true by construction at
system startup on uniprocessor systems, and not possible to guarantee
at all under SMP (where other CPUs can take that timer interrupt). We
don't document or test for this feature, so don't try to be fancy.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Really the locking in this file is vestigial. It only exists because
the scheduler's _unpend_all() call to wake up everyone waiting on a
wait_q is unsynchronized, because it was written to assume
irq_lock-style-locking. It would be cleaner to put that locking into
the wait_q itself and/or use the scheduler's subsystem lock. But it's
not clear there's any performance benefit, so let's stick with the
more easily verifiable change first.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Poll gets a single subsystem lock for now. The existing locking in
Ben's code is subtle, being used both for latency control and for
critical section protection. So getting each k_poll_event to use a
separate lock will require care and a little logic change. Do the
simple version for now, which still works to decouple it from the
global lock.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These functions, for good design reason, take a locking key to
atomically release along with the context swtich. But there's still a
common pattern in code to do a switch unconditionally by passing
irq_lock() directly. On SMP that's a little hurtful as it spams the
global lock. Provide an _unlocked() variant for
_Swap/_reschedule/_pend_curr for simplicity and efficiency.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Switch semaphores to use a subsystem spinlock instead of the system
irqlock.
Note that this is only "half way there". Semaphores will no longer
contend with other irqlock users on SMP systems, but all semaphores
are still sharing the same lock. Really we want semaphores to be
independently synchronized, but adding 4 bytes to every one (there are
a LOT of these things) for a separate spinlock is too much to pay.
Rather, a proper SMP-aware implementation would spin on the count
variable directly. But let's not rock that boat quite yet.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Just like with _Swap(), we need two variants of these utilities which
can atomically release a lock and context switch. The naming shifts
(for byte count reasons) to _reschedule/_pend_curr, and both have an
_irqlock variant which takes the traditional locking.
Just refactoring. No logic changes.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Mostly useless patch. All architectures have their own code for
atomic operations and don't use this fallback. Still, it's a trivial
locking setup and we might as well.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Each work_q object gets a separate spinlock to synchronize access
instead of the global lock. Note that there was a recursive lock
condition in k_delayed_work_cancel(), so that's been split out into an
internal unlocked version and the API entry point that wraps it with a
lock.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The validation checking recently added to spinlocks is useful, but
requires kernel-internals like _current and _current_cpu in a header
context that tends to be needed before those are declared (or where we
don't want them declared), and is causing big header dependency
headaches.
Move it to C code, it's just a validation tool, not a performance
thing.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
We want a _Swap() variant that can atomically release/restore a
spinlock state in addition to the legacy irqlock. The function as it
was is now named "_Swap_irqlock()", while _Swap() now refers to a
spinlock and takes two arguments. The former will be going away once
existing users (not that many! Swap() is an internal API, and the
long port away from legacy irqlocking is going to be happening mostly
in drivers) are ported to spinlocks.
Obviously on uniprocessor setups, these produce identical code. But
SMP requires that the correct API be used to maintain the global lock.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These two spots were duplicating logic that is already done inside
_reschedule(), which is the cleaner, less dangerous API. Use it where
possible when outside the scheduler internals.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Since we know do DTS before Kconfig we should try and remove dts from
creating Kconfig namespaced symbols and leave that to Kconfig. So
rename CONFIG_CCM_<FOO> to DT_CCM_<FOO>.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
The power management framework used two different abstractions
to describe power states. The SYS_PM_* given coarse information
what kind of power state (low power or deep sleep) was used,
while the SYS_POWER_STATE_* abstraction provided information
about particular power mode.
This commit removes the SYS_PM_* abstraction as the same
information is already carried in SYS_POWER_STATE_*.
Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no>
This was never a long-term solution, more of a gross hack
to get test cases working until we could figure out a good
end-to-end solution for memory domains that generated
appropriate linker sections. Now that we have this with
the app shared memory feature, and have converted all tests
to remove it, delete this feature.
To date all userspace APIs have been tagged as 'experimental'
which sidesteps deprecation policies.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
* Newlib now defines a special z_newlib_partition containing
all globals relevant to newlib. Most of these are in libc.a
with a heap tracking variable in newlib's hooks.
* Both C libraries now expose a k_mem_partition containing the
bounds of the malloc heap arena. Threads that want to use
libc malloc() will need to add this to their memory domain.
* z_newlib_get_heap_bounds has been removed, in favor of the
memory partition for the heap arena
* ztest now includes the C library partitions in its memory
domain.
* The mem_alloc test now runs in user mode to prove that this
all works for both C libraries.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
Dynamic kernel objects enforce that the permission state
of an object is also a reference count; using a kernel
object without permission regardless of caller privilege
level is a programming bug.
However, this is not the case for static objects. In
particular, supervisor threads are allowed to use any
object they like without worrying about permissions, and
the logic here was causing cleanup functions to be called
over and over again on kernel objects that were actually
in use.
The automatic cleanup mechanism was intended for
dynamic objects anyway, so just skip it entirely for
static objects.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This patch puts checks in place to ensure that callers to the k_mem_slab
APIs provide word aligned block sizes. If this is not done, this can
result in unaligned accesses and subsequent crashes.
Signed-off-by: Andy Gross <andy.gross@linaro.org>
This commit extends the implementation of sane_partition(..) in
kernel/mem_domain.c so that it generates an ASSERT if partitions
inside a mem_domain overlap. This extension is only implemented
for the case when the MPU requires non-overlapping regions.
Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This adds a simple implementation of SMP CPU affinity to Zephyr. The
API is simple and doesn't try to invent abstractions like "cpu sets".
Each thread has an enable/disable flag associated with each CPU in the
system, and the bits can be turned on and off (for threads that are
not currently runnable, of course) using an easy three-function API.
Because the implementation picked requires enumerating runnable
threads in priority order looking for one that match the current CPU,
this is not a good fit for the SCALABLE or MULTIQ scheduler backends,
so it currently can be enabled only for SCHED_DUMB (which is the
default anyway). Fancier algorithms do exist, but even the best of
them scale as O(N_CPUS), so aren't quite constant time and often
require significant memory overhead to keep separate lists for
different cpus/sets.
The intended use here is for apps that want to "pin" threads to
specific CPUs for latency control, or conversely to prevent certain
threads from taking time on specific CPUs to leave them free for fast
response.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
When under SMP, _current is a macro that indirects to a CPU-specific
address, and that trick won't work until kernel_arch_init() has
returned.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Idle threads must (for obvious reasons!) always be preemptible from
the perspective of the scheduler. But when preemptive scheduling is
disabled, they are given a priority of -1, which is the lowest
COOPERATIVE priority. So the scheduler preemption logic needed an
extra test for this case and couldn't just rely on the existing
priority comparison. This was a measurable performance loss, as this
is a hot path on existing benchmarks.
Limit that test to circumstances (!CONFIG_PREEMPT_ENABLED) where it's
actually needed.
Longer term it would be better to just force the existence of one
"preemptible" thread priority always, but right now the number of
priorities and the state of the PREEMPT_ENABLED kconfig flag are
linked, and the existing interrupt return code (with no preemption,
you know with certainty which thread you are returning to and can skip
some work) on some platforms fails when I try this.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
For historical reasons, some architectures had a valid _current thread
pointer at initialization time and others didn't. So the scheduler
logic had a test that checks _current vs. NULL every time it needed to
check premption, when this was only a workaround for initialization
state.
Fix things so that there is a dummy thread always (and clean up the
code to do a struct assignment instead of a memset of bare memory),
and we can remove that test from the scheduler hot path.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
GCC 6.2.0 is making frustratingly poor inlining decisions with some of
these routines, resulting in an awful lot of runtime calls for code
that is only ever expanded once or twice within the file.
Treat with targetted ALWAYS_INLINE's to force the issue. The
scheduler code is a hot path.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The sys_dlist_insert_*() functions had a behavior where a NULL
argument for the insertion position to sys_dlist_insert_after/before()
was interpreted as "the end of the list". We never used that
convention (except in one spot internal to dlist.h which was not
itself used anywhere), and of course already have an API for appending
and prepending to a list.
In practice this was a performance disaster. The NULL check is
virtually never provable statically by the compiler, so that test and
branch is present always. And worse, the check and call to another
function was pushing this beyond the complexity limit for gcc to
inline a function (at -Os optimization anyway), forcing us to use
function calls for what should be a ~8 instruction sequence. The
upshot is that dlist insertions were 2-3x slower than they needed to
be.
Deprecate these older APIs and introduce a new sys_dlist_insert() call
which can be much better optimized.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The fix in commit e664c78b82 ("kernel/timeout: Fix recursive
spinlock in z_set_timeout_expiry()") missed a spot that had also been
introduced with recent locking work. The new
_get_next_timeout_expiry() implementation takes its own lock, which is
recursive when called from z_clock_announce(). Fix by calling the
wrapped implementation instead.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Whether a timeout is linked into the timeout queue can be determined
from the corresponding sys_dnode_t linked state. This removes the need
to use a special flag value in dticks to determine that the timeout is
inactive.
Update _abort_timeout to return an error code, rather than the flag
value, when the timeout to be aborted was not active.
Remove the _INACTIVE flag value, and replace its external uses with an
internal API function that checks whether a timeout is inactive.
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
k_poll events are registered in a linked list when their signal
condition has been met. The code to clear event registration did not
account for events that were not registered, resulting in double-removes
that produced core dumps on native-posix sanitycheck.
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
CONTAINER_OF() on a NULL pointer returns some offset around NULL and not
another NULL pointer. We have to check for that ourselves.
This only worked because the dnode happened to be at the start of the
struct.
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
The help text has been stating that CONFIG_STACK_CANARIES will
silently be ignored when the compiler does not support them. But this
is not the desired behaviour of CONFIG_STACK_CANARIES[1].
This patch corrects the help text to state that an error will occur if
this feature is enabled, but not supported.
[1] "I would much rather see the build break if someone tries to
enable the stack canaries, and the compiler doesn't support
it. Because what happens now is that if someone enables this option,
and there is no support, the build will succeed but there are no
actual stack canaries in place, and unless the user is paying close
attention to the cmake test output they will have no idea."
--
https://github.com/zephyrproject-rtos/zephyr/issues/5019
Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
There is an effort underway to make most of the Zephyr build script's
reentrant. Meaning, the build scripts can be executed multiple times
during the same CMake invocation.
Reentrancy enables several use-cases, the motivating one is the
ability to build several Zephyr executables, or images, for instance a
bootloader and an application.
For build scripts to be reentrant they cannot be directly referencing
global variables, like target names, but must instead reference
variables, which can vary from entry to entry.
Therefore, in this patch, we replace global targets with variables.
Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
The z_set_timeout_expiry() function was added in part to simply the
locking strategy, but it missed a case where a function it was calling
was re-locking the same spinlock. It "works"[1] in uniprocessor
environments, but can be a deadlock in SMP.
Fix this by moving the meat of the function to an unlocked utility,
use that locally, and turn the entry point into one that does locking.
Actually this only gets called from idle now, which is a use case that
will go away when TICKLESS_IDLE is removed as a separate feature (once
you know all timeouts are set tickless, you don't need to set it from
the idle entry at all).
Discovered via lucky inspection.
[1] It doesn't work. It releases the lock prematurely at the end of
the inner block. But in practice this wasn't discovered.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This patch provides support for generating Code coverage reports.
The prj.conf needs to enable CONFIG_COVERAGE. Once enabled, the
code coverage data dump now comes via UART.
This data dump on the UART is triggered once the main
thread exits.
Next step is to save this data dump on file. Then run
scripts/gen_gcov_files.py with the serial console log as argument.
The last step would be be to run the gcovr. Use the following cmd
gcovr -r . --html -o gcov_report/coverage.html --html-details
Currently supported architectures are ARM and x86.
Signed-off-by: Adithya Baglody <adithya.nagaraj.baglody@intel.com>
Timeslicing works by removing the _current thread from the run queue
and re-adding it at the end of its priority. On systems with a
_Swap() that can be preempted by a timer interrupt, that means it's
possible for the timeslice to try to slice out a thread that had
already pended itself!
This behavior used to be benign (or at least undetectable) as the
duplicated list operations were idempotent. But now the dlist code is
stricter about correctness and has exposed the bug -- it will blow up
if you try to remove an already-removed list node.
Fix (on affected platforms) by stashing the _current pointer in
_pend_current_thread() that is checked and cleared in the timer
interrupt. If we discover we're trying to interrupt a thread that's
already interrupted itself, we can safely exit z_time_slice() as a
noop. The timeslicing bookeeping was already done for us underneath
the pend code.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This is a refactoring of the fix in commit 6c95dafd82 to limit its
application to affected platforms now that the root cause is
understood.
Note that the bug that fix was addressing was rare and seen only on
after multi-hour sessions on Michael Scott's test rig. So if
something regresses, this is where to look!
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
On ARM, _Swap() isn't atomic and a hardware interrupt can land after
the (irq_locked) caller has entered _Swap() but before the context
switch actually happens. This will require some platform-specific
workarounds in a few places in the scheduler.
This commit is just the Kconfig and selection on ARM.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The call to _arch_switch is a giant screaming sign inviting optimizer
bugs. The code that appears before is what happened long ago when we
were switched out, but the version that EXECUTED just now is actually
in a different thread. So the assignment to _current before the
switch actually assigned OUR thread (the "new_thread" of the old
context!) to _current.
But obviously the optimizer looks at that code and assumes that the
_current which got assigned to the thread we were switching to long
ago is still correct, and used it when retrieving the swap return
value.
Obviously the real bug here is that the _arch_switch() in question
lacked a memory clobber (and it's getting one).
But we can remove two lines, remove code from inside the interrupt
lock and make the implementation more robust by moving the read to
after the irq_unlock() (which generally also has a memory clobber).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These files were using z_thread_malloc() without including
kernel_internal.h. On existing architectures that works due to
transitive includes, but x86_64 has a thinner include layer and
doesn't do it for us. Include the files required for the APIs we use.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Commit 76b3518ce6 ("kernel: Make statements evaluate boolean
expressions") changed the type of is_polling in the struct _poller
from int to bool. In the conversion a "0" has been changed into "true"
instead of "false". Fix that.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This API was using variable number of arguments. Which is not
allowed according to misra c guidelines(Rule 17.1). Hence making
this API into a macro and using the util macro FOR_EACH_FIXED_ARG
to get the same functionality.
There is one deviation from the old function. The last argument
shouldn't be NULL.
Signed-off-by: Adithya Baglody <adithya.nagaraj.baglody@intel.com>
The logic in z_set_timeout_expiry() missed the case where the ticks
argument could be zero (or lower), which can happen naturally due to
timing/interrupt slop. In those circumstances, it would still try to
reset a timer that was "about to expire at the next tick", which would
run afoul of the drivers' internal decisions about how soon a timer
interrupt could be set, and then get pushed out to the next tick.
Explicitly detect this as an "imminent" predicate to make the logic
clearer.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The recent change that added a locked z_set_timeout_expiry() API
obsoleted the subtle note about synchronization above
reset_time_slice(). None of that matters any more, the API is
synchronized internally in a conventional way.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The use of dticks == INACTIVE to tell whether or not a timeout was
already in the list was insufficient. There is a time period between
the moment a timeout is removed from the list and the end of its
handler where it is not in the list, yet its list node pointers still
point into it. Doing things like aborting a thread while that is true
(which can be asynchronous too!) would corrupt the list even though
all the operations on it were "atomic".
Set the timeout node pointers to nulls atomically when removed, and
check for double-remove conditions (which, again, might be perfectly
OK).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This loop was structured badly, as a while(true) with multiple "exit
if" cases in the body. It was bad enough that I genuinely fooled
myself into rewriting it, having convinced myself there was a bug in
it when there wasn't.
So keep the rewritten loop which expresses the iteration in a more
invariant way (i.e. "while we have an element to expire" and not "test
if we have to exit the loop"). Shorter and easier. Also makes the
locking clearer as we can simply release the lock around the callback
in a natural/obvious way.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Don't present USE_SWITCH and SMP to user applications that are
configuring for platforms that do not support SMP or USE_SWITCH.
Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
SMP requires the new-style '_arch_switch' to be enabled. To prevent
users from creating invalid configurations where SMP is enabled while
_arch_switch is not, we add a dependency from SMP to USE_SWITCH.
Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
RETPOLINE has been enabled by default on most platforms, but it is
only supported on X86.
Features should only be enabled if they are supported and active on
the given platform. To rectify this we have RETPOLINE depend on X86,
the only platform on which it is implemented.
Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
In general driver system calls are implemented at a subsystem
layer. However, some drivers may have capabilities specific to
the hardware not covered by the subsystem API. Such drivers may
want to define their own system calls.
This macro makes it simple to validate in the driver-specific
system call handlers that not only does the untrusted device
pointer correspond to the expected subsystem, initialization
state, and caller permissions, but also that the device object
is an instance of a specific driver (and not just any driver in
that subsystem).
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
The main function is just a weak function that should be override by the
applications if they need. Just adding a nop instructions to explicitly
says that this function does nothing.
MISRA-C rule 2.2
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
If initialization fails, zero the API struct so that
device_get_binding() can't fetch it, and do not mark
the driver object as initialized to user mode.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This patch splits the text section into 2 parts. The first section
will have some info regarding vector tables and debug info. The
second section will have the complete text section.
This is needed to force the required functions and data variables
the correct locations.
This is due to the behavior of the linker. The linker will only link
once and hence this text section had to be split to make room
for the generated linker script.
Added a new Kconfig CODE_DATA_RELOCATION which when enabled will
invoke the script, which does the required relocation.
Added hooks inside init.c for bss zeroing and data copy operations.
Needed when we have to copy data from ROM to required memory type.
Signed-off-by: Adithya Baglody <adithya.nagaraj.baglody@intel.com>
MISRA-C says all declarations of an object or function must use the
same name and qualifiers.
MISRA-C rule 8.3
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
In C90 was introduced function prototype, that allows argument types
to be checked against parameter types, though it is not necessary
specify names for the parameters. MISRA-C requires names for function
prototype parameters, it claims that names can provide useful
information regarding the function interface.
MISRA-C rule 8.2
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The order of evaluation of function calls in the arguments of a
function. This is undefined (32)/ unspecified(15-18) in C99.
MISRA-C rule 13.2 does not allow that a value of an expression and its
side effects happens in not deterministic order to avoid these
undefined behaviors.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
According with MISRA-C and unconditional break statement must
terminate every switch-clause.
MISRA-C rule 16.1 and 16.3
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
MISRA-C requires the right-hand operand of && or || operator does not
contain persistent effect.
MISRA-C rule 13.5
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
When a memory partition is removed, it is not required
to clear the start and attr fields, since a free partition
is only indicated by a zero size field. This commit removes
the un-necessary clearing of start and attr fields.
Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
It is necessary to delay setting lock_count = 0 because an unlocking thread
maybe swapped out when it calls adjust_owner_prio(). If the thread that starts
running sees lock_count = 0 it will successfully acquire the mutex even though
it is not fully unlocked yet.
Fixes#11798.
Signed-off-by: Nicolás Bértolo <nicolasbertolo@gmail.com>
The comment explaining why _IntLibInit was being invoked was left in
place after the invocation itself was removed. Remove it too.
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
The function that checks if an object is valid is essentially a boolean
function. Just changing its return type to reflect it.
MISRA-C rule 14.4
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This allows for workqueues to be started in user mode.
No additional kernel objects or system calls are defined
other than starting the workqueue in user mode; for
permission purposes the embedded queue and thread objects
are sufficient.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
k_work and k_work_q are not kernel objects, nor will they
be. k_work_q contains some kernel objects which are tracked
independently.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
There were many platforms where this function was doing nothing. Just
merging its functionality with _PrepC function.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
System must not set the clock expiry via backdoor as it may
effect in unbound time drift of all scheduled timeouts.
Fixes: #11502
Signed-off-by: Pawel Dunaj <pawel.dunaj@nordicsemi.no>
System Power Management is only supported in Tickless Idle mode.
This patch modifies Kconfig dependencies to ensure System Power
Management option selects Tickless Idle one.
Fixes: #11046
Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
The call to z_clock_set_timeout() was being made outside the timeout
lock, which can race against other contexts setting sooner-expiring
timeouts.
Also add a long comment to one spot (timeslicing) where this call is
made outside the timeout spinlock (inside the scheduler lock) and why
this is OK.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Add implementation for k_msgq_peek() which is similar to k_msgq_get()
except the message is not deleted from the queue.
Signed-off-by: Sathish Kuttan <sathish.k.kuttan@intel.com>
If we just had the kernel's implementation, we could
just move this to lib/, but possible arch-specific
implementations dictate that we just make this a
syscall.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
We aren't going to allow any user mode access to the
k_mem_slab APIs, but in some cases (specifically in the
case of the I2S subsystem) we need to allow user mode
to assign a memory slab to a particular driver.
This will let us verfiy (in supervisor mode) that a provided
k_mem_slab pointer is really a k_mem_slab, and know its
initialization state, and have permissions assigned to it.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit optimizes the process of checking that the
added partitions in a mem_domain are sane. It places the
sane_partition checking inside the loop of adding the
partitions in the mem_domain, so that the checkings are
not performed twice, and no partition is checked against
itself.
Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
This commit fixes the calculations of the partition ending
addresses in two places in the code, according to:
<last> = <start> + <size> - 1. We also rename 'end' to 'last'
to stress that we calculate the last address in the partition.
Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
User mode may need to use this API to get a handle on
devices by name, expose as a system call. We impose
a maximum name length as the system call handler needs
to make a copy of the string passed in from user mode.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
If this function is itself interrupted by a timeslice event, the
slicing state can be corrupted. Just re-use the scheduler lock
instead of using a new spinlock; this is a low-latency function that
won't deadlock. Found by inspection.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Add a TICKLESS_CAPABLE kconfig variable which is used by the kernel to
select tickless mode's default automatically on drivers that support
it (rather than having to set the default per-board). Select it from
the ARM SysTick and Intel HPET drivers.
Also remove the old qemu_cortex_m3 default settings which this
replaces.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Some places are using the same tag identifier with different types.
This is a MISRA-C violation and makes the code less readable.
MISRA-C rule 5.7
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
k_poll_signal was being used by both, struct and function. Besides
this being extremely error prone it is also a MISRA-C violation.
Changing the function to contain a verb, since it performs an action
and the struct will be a noun. This pattern must be formalized and
followed and across the project.
MISRA-C rules 5.7 and 5.9
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
There was an struct and a variable called _kernel. This is error prone
and a MISRA-C violation. It is changing the struct to have a unique
identifier.
MISRA-C rule 5.8
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
According with MISRA-C an object should be defined in a block scope if
it is used in a single function.
MISRA-C rule 8.9
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This is not violating any MISRA-C rule, though, it seems to be
triggering a false (rule 9.1) positive in some static analysis
tools. Nevertheless, it is more readable declare all variables in the
same scope together.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
There is a struct and a macro called _ready_q, this is error
prone. Just removing it.
MISRA-C rule 5.4
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The tracing variable in alert.c was declared by default. This
should have been declared only when CONFIG_OBJECT_TRACING is set.
Signed-off-by: Adithya Baglody <adithya.nagaraj.baglody@intel.com>
This patch fixes few issues in queue.c. This patch also changes
the return type of k_queue_alloc_append and k_queue_alloc_prepend
from int to s32_t.
Signed-off-by: Adithya Baglody <adithya.nagaraj.baglody@intel.com>
This commit introduces k_sleep() return value, which provides
information about actual sleep time. If the returned value is
not-zero, the thread slept shorter than requested, which is
only possible if the thread has been woken up by k_wakeup() call.
Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no>
Fixing a few minor typo fixes in kernel/mem_domain.c
and the respective documentation section.
Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
Fix a compile warning if we build using int types defined to match the
compiler. We get the following warnings:
kernel/msg_q.c: In function ‘_impl_k_msgq_alloc_init’:
kernel/msg_q.c:75:9: warning: passing argument 3 of ‘__builtin_umul_overflow’ from incompatible pointer type [-Wincompatible-pointer-types]
(u32_t *)&total_size)) {
^
kernel/msg_q.c:75:9: note: expected ‘unsigned int *’ but argument is of type ‘u32_t * {aka long unsigned int *}’
__builtin_umul_overflow expects to be passed unsigned int for all its
arguments, so cast to that instead of u32_t.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Previously, a generic "workqueue" name was used, but there're few
workqueues in a typical Zephyr setup, and it wasn't possible to
distinguish them.
Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
In _pend_current_thread the argument key is always a unsigned
interger type and this function forces it to become a signed
interger. This is a dangerous behavior and cant be trusted to
work as expected.
Signed-off-by: Adithya Baglody <adithya.nagaraj.baglody@intel.com>
Duh: "remove()" is a POSIX symbol, and on at least some platforms
stdio.h can be included here out of platform headers causing a name
collision.
Fixes#10669's direct issue, though the broader issue of how to choose
names for statics remains controversial.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This API shouldn't take a int type but instead it should take
u32_t. This argument has to be similar to irq_lock() and
irq_unlock().
Signed-off-by: Adithya Baglody <adithya.nagaraj.baglody@intel.com>
In tickless mode, not all elapsed ticks may have been announced yet,
so future z_time_slice() calls will include "extra" ticks that we have
to account for when setting up the slice count.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Our funny convention holds that passing ticks==1 to _add_timeout()
means "at the next tick". But that means that 1, 0, and all negative
numbers are expected to behave the same. In ticked mode, that's fine
because it will, after all, expire at the next tick.
But in tickless, the next announcement may be for several ticks, and
that zero will appear to expire "before" the next tick in the
consumption loop.
Make sure all "next tick" expirations look the same.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
When fetching the next timeout to expire, the value is relative to the
last announced tick, so you subtract the timer-provided elapsed time
to get the true delta from "now". When adding a new timeout, you
*have* a value relative to now, so you compute the delta vs. the last
announced tick by adding the elapsed() time. Duh.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This was wrong in subtle ways. In tickless mode it's possible to get
an announcement for multiple ticks at a time and have multiple
callbacks to execute that were technically scheduled at different
times. We want to fix the current tick at the value represented by
the currently-executing callback's EXPIRATION (even if we missed it!),
so that any new timeouts it sets (c.f. a k_timer period) happen at the
right point, in phase with the expected series. In single-tick mode
the code ends up the same always, so the bug wasn't visible.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The previous comment correctly and carefully explained why the 64 bit
value in curr_tick doesn't require locking when reading only the low
32 bits.
It completely missed the fact that the calculation of elapsed time and
the read of curr_tick ABSOLUTELY DO require locking, because the
former is expressed in terms of the latter. This was always bug, even
in the old code, but never witnessed because we ran so little software
in tickless mode.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
It's possible to interrupt a thread that has already scheduled a
timeout. Really this is a race against the usage of
_add_thread_timeout() and needs some design work to provide proper
locking (which is a distinct requirement from the scheduler lock and
timeout lock!), as the users of that API are spread around the kernel.
But existing usage always schedules the timeouts first, so this is
safe.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The timeout APIs are properly synchronized now. This irq_lock() (and
the comment explaining it) isn't needed anymore.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
These options are rapidly becoming a default configuration, which is
complicated by having them be hidden inside of a SYS_POWER_MANAGEMENT
variable that has to be enabled first. Put them at the top level of
the kernel config.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
I was pretty careful, but these snuck in. Most of them are due to
overbroad string replacements in comments. The pull request is very
large, and I'm too lazy to find exactly where to back-merge all of
these.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Now that the API has been fixed up, replace the existing timeout queue
with a much smaller version. The basic algorithm is unchanged:
timeouts are stored in a sorted dlist with each node nolding a delta
time from the previous node in the list; the announce call just walks
this list pulling off the heads as needed. Advantages:
* Properly spinlocked and SMP-aware. The earlier timer implementation
relied on only CPU 0 doing timeout work, and on an irq_lock() being
taken before entry (something that was violated in a few spots).
Now any CPU can wake up for an event (or all of them) and everything
works correctly.
* The *_thread_timeout() API is now expressible as a clean wrapping
(just one liners) around the lower-level interface based on function
pointer callbacks. As a result the timeout objects no longer need
to store backpointers to the thread and wait_q and have shrunk by
33%.
* MUCH smaller, to the tune of hundreds of lines of code removed.
* Future proof, in that all operations on the queue are now fronted by
just two entry points (_add_timeout() and z_clock_announce()) which
can easily be augmented with fancier data structures.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
_timeout_remaining_get() was a function on a struct _timeout, doing
iteration on the timeout list, but it was defined in timer.c (the
higher level abstraction).
Move it to where it belongs. Also have it return ticks instead of ms
to conform to scheme in the rest of the timeout API. And rename it to
a more standard zephyr name.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The current z_clock_uptime() call (recently renamed from
_get_elapsed_program_time) requires the driver to track a full 64 bit
uptime value in ticks, which is entirely separate from the one the
kernel is already keeping.
Don't do that. Just ask the drivers to track uptime since the last
call to z_clock_announce(), since that is going to map better to
built-in hardware capability.
Obviously existing drivers already have this feature, so they're
actually getting slightly larger in order to implement the new API in
terms of the old one. But future drivers will thank us.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Add the callback parameter to add_timeout(), and remove the thread
argument. Now the "low level" timeout API can be expressed without
reference to threads.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Now that this is known to be an unused value, remove it from the API.
Note that this caught a few spots where we were passing values (a
non-NULL wait_q with a NULL thread handle) that were always being
ignored before.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The existing timeout API wants to store a wait_q on which the thread
is waiting, but it only uses that value in one spot (and there only as
a boolean flag indicating "this thread is waiting on a wait_q).
As it happens threads can already store their own backpointers to a
wait_q (needed for the SCALABLE scheduler backend), so we should use
that instead.
This patch doesn't actually perform that unification yet. It
reorgnizes things such that the pended_on field is always set at the
point of timeout interaction, and adds a bunch of asserts to make 100%
sure the logic is correct. The next patch will modify the API.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The timeout_q.h scheme, where it declared real functions, but the
stubs for when there was no clock were in wait_q.h was senselessly
weird. Put them in the same file.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Instead of checking every time we hit the low-level context switch
path to see if the new thread has a "partner" with which it needs to
share time, just run the slice timer always and reset it from the
scheduler at the points where it has already decided a switch needs to
happen. In TICKLESS_KERNEL situations, we pay the cost of extra timer
interrupts at ~10Hz or whatever, which is low (note also that this
kind of regular wakeup architecture is required on SMP anyway so the
scheduler can "notice" threads scheduled by other CPUs). Advantages:
1. Much simpler logic. Significantly smaller code. No variance or
dependence on tickless modes or timer driver (beyond setting a
simple timeout).
2. No arch-specific assembly integration with _Swap() needed
3. Better performance on many workloads, as the accounting now happens
at most once per timer interrupt (~5 Hz) and true rescheduling and
not on every unrelated context switch and interrupt return.
4. It's SMP-safe. The previous scheme kept the slice ticks as a
global variable, which was an unnoticed bug.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This got broken. Add some #ifery to handle the case. Not clean, will
clean up in a future pass once the API is final.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This feature was a useless noop based on mistaken API understanding.
The idea seems to have been that k_busy_wait() included guards to
ensure "clock_always_on" was true duing the loop, presumably because
the original author was afraid that "turning the clock off" would
affect the operation of k_cycle_get_32().
Then later someone came around and "optimized" this for Quark SE,
where the cycle counter is the RTC and unrelated to the timer driver
used by the clock_always_on feature. (Except even there it presumably
should have been done at the SoC level and not just in the C1000
devboard -- note that Arduino 101 never would have gotten this).
But it was all a mistake: "clock_always_on" has nothing to do with
en/disabling the system cycle timer (which never happens when the
system is active, that's a feature of idle), it's a control over the
delivery of timer interrupts. And needless to say we don't care about
timer interrupts when we're spinning on a cycle counter.
Yank the whole mess.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The current API has an rather unfortuate collision between two APIs:
z_clock_announce(), which is called out of the timer interrupt to
inform the kernel of time passage (and which is responsible for
invoking timer callbacks), and z_tick_set(), which is ALSO used by the
timer drivers for... confusing and inconsistent purposes.
This is sort of a mess. The tick_set API needs to go away, but before
that I'm adding some assertions to at least make sure the existing
drivers are using them consistently.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
There was no good reason to have these rather large functions in a
header. Put them into sys_clock.c for now, pending rework to the
system.
Now the API is clearly visible in a small header.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
If the idle code was detecting that it needed to sleep for less than
CONFIG_SYS_TICKLESS_IDLE_THRESH, then it would never call
z_clock_set_timeout() at all, which means that the system would never
wake up unless it already had a timeout scheduled! Apparently we
lacked a test case to detect this condition.
Honestly this seems like a crazy feature to me. There's no benefit in
delivering needless tick announcements. If the system has the
capacity to enter deeper sleep for long timeouts, that's already
exposed via the PM APIs, the timer subsystem needn't be involved.
But... we actually have a test (tickless_concept) that looks at this,
so support it for now and consider deprecation later.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This code (just refactored as part of the timer API work) turns out to
be needless. It's trying to detect the case where we're being asked
to idle for zero time, but that's not possible with a properly
functioning timer driver: the call to z_clock_announce() must happen
out of an interrupt, and this is the idle thread, which must sit below
any possible interrupt priority. The call to z_clock_uptime() must
not ever return "too late" until after the timer interrupt has fired,
at which point we'll be inspecting the next timeout (which itself is
guaranteed to be in the future for the same reason).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The tickless driver had a bunch of "hairy" APIs which forced the timer
drivers to do needless low-level accounting for the benefit of the
kernel, all of which then proceeded to implement them via cut and
paste. Specifically the "program_time" calls forced the driver to
expose to the kernel exactly when the next interrupt was due and how
much time had elapsed, in a parallel API to the existing "what time is
it" and "announce a tick" interrupts that carry the same information.
Remove these from the kernel, replacing them with synthesized logic
written in terms of the simpler APIs.
In some cases there will be a performance impact due to the use of the
64 bit uptime call, but that will go away soon.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
Rename timer driver API functions to be consistent. ADD DOCS TO THE
HEADER so implementations understand what the requirements are.
Remove some unused functions that don't need declarations here.
Also removes the per-platform #if's around the power control callback
in favor of a weak-linked noop function in the driver initialization
(adds a few bytes of code to default platforms -- we'll live, I
think).
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The existing API had two almost identical functions: _set_time() and
_timer_idle_enter(). Both simply instruct the timer driver to set the
next timer interrupt expiration appropriately so that the call to
z_clock_announce() will be made at the requested number of ticks. On
most/all hardware, these should be implementable identically.
Unfortunately because they are specified differently, existing drivers
have implemented them in parallel.
Specify a new, unified, z_clock_set_timeout(). Document it clearly
for implementors. And provide a shim layer for legacy drivers that
will continue to use the old functions.
Note that this patch fixes an existing bug found by inspection: the
old call to _set_time() out of z_clock_announce() failed to test for
the "wait forever" case in the situation where clock_always_on is
true, meaning that a system that reached this point and then never set
another timeout would freeze its uptime clock incorrectly.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
There were three separate "announce ticks" entry points exposed for
use by drivers. Unify them to just a single z_clock_announce()
function, making the "final" tick announcement the business of the
driver only, not the kernel.
Note the oddness with "_sys_idle_elapsed_ticks": this was a global
variable exposed by the kernel. But it was never actually used by the
kernel. It was updated and inspected only within the timer drivers,
and only so that it could be passed back to the kernel as the default
(actually hidden) argument to the announce function. Break this false
dependency by putting this variable into each timer driver
individually.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The system tick count is a 64 bit quantity that gets updated from
interrupt context, meaning that it's dangerously non-atomic and has to
be locked. The core kernel clock code did this right.
But the value was also exposed to the rest of the universe as a global
variable, and virtually nothing else was doing this correctly. Even
in the timer ISRs themselves, the interrupts may be themselves
preempted (most of our architectures support nested interrupts) by
code that wants to set timeouts and inspect system uptime.
Define a z_tick_{get,set}() API, eliminate the old variable, and make
sure everyone uses the right mechanism.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This flag is an indication to the timer driver that the OS doesn't
care about rollover conditions of the tick count while idling, so the
system doesn't need to wake up once per counter flip[1]. Obviously in
that circumstance values returned from k_uptime_get_32() are going to
be wrong, so the implementation had an assert to check for misuse.
But no one understood that from the docs, so the only place these APIs
were used in practice were as "guards" around code that needed to call
k_uptime_get_32(), even though that's 100% wrong per docs!
Clarify the docs. Remove the incorrect guards. Change the flag to
initialize to true so that uptime isn't broken-by-default in tickless
mode. Also move the implemenations of the functions out of the
header, as there's no good reason for these to need to be inlined.
[1] Which can be significant. A 100MHz ARM using the 24 bit SysTick
counter rolls over at about 6 Hz, and if it had to come out of
idle at that rate it would be a significant power issue that would
swamp the gains from tickless. Obviously systems with slow
counters like nRF or 64 bit ones like RISC-V or x86's TSC aren't
as affected.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This was another "global variable" API. Give it function syntax too.
Also add a warning, because on nRF devices (at least) the cycle clock
runs in kHz and is too slow to give a precise answer here.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This was only used in a few places just to indirect the already
perfectly valid SYS_CLOCK_TICKS_PER_SEC value. There's no reason for
these to ever have been kconfig units, and in fact the distinction
appears to have introduced a hidden/untested bug in the power
subsystem (the two variables were used interchangably, but they were
defined in reciprocal units!).
Just use "ticks" as our time unit pervasively, and clarify the docs to
explain that.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The existing API defined sys_clock_{hw_cycles,ticks}_per_sec as simple
"variables" to be shared, except that they were only real storage in
certain modes (the HPET driver, basically) and everywhere else they
were a build constant.
Properly, these should be an API defined by the timer driver (who
controls those rates) and consumed by the clock subsystem. So give
them function syntax as a stepping stone to get there.
Note that this also removes the deprecated variable
_sys_clock_us_per_tick rather than give it the same treatment.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The builtin function __builtin_umul_overflow returns a boolean and
should not checked as an integer.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Removing an unnecessary check in k_mem_pool_alloc. The condition is
already being checked in the if.
MISRA-C rule 14.3
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
A final else statement must be provided when an if statement is
followed by one or more else if.
MISRA-C rule 15.7
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
When delta_ticks_from_prev is not 0, the variable ticks will necessarily
be lesser or equal 0, so the if checking that is no necessary.
MISRA-C rule 15.7
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
According C99 the first 31 characters of an identifier must be unique.
Shortening the namespace of the generated objects to achieve it.
C99 - 5.2.4.1
MISRA-C rule 5.1
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Under GNU C, sizeof(void) = 1. This commit merely makes it explicit u8.
Pointer arithmetics over void types is:
* A GNU C extension
* Not supported by Clang
* Illegal across all ISO C standards
See also: https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
Signed-off-by: Mark Ruvald Pedersen <mped@oticon.com>
Change APIs that essentially return a boolean expression - 0 for
false and 1 for true - to return a bool.
MISRA-C rule 14.4
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Added k_thread_name_set() and enable thread name setting when declaring
static threads. This is enabled only when THREAD_MONITOR is used. System
threads get a name by default.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit improves the help text of INIT_STACKS
Kconfig option, so it indicates that the stack
initialization applies also to the interrupt stack.
Fixes#7196.
Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
The Kconfig option CONFIG_BUILD_TIMESTAMP became unused when
BUILD_VERSION was introduced, but it's option and parts of it's
implementation was not completely cleaned from the repository.
Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
Add ifdef guard to the z_reset_timeslice() to fix compilation
errors when CONFIG_TIMESLICING is disabled.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Several style and typo fixes in inline comments of arm kernel
files and thread.c.
Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
_pend_current_thread can return any arbitrary value set by
_set_thred_return_value(), it happens that most cases set 0. This
function can not rely on this behavior otherwise it may return an
invalid value and/or not set data's value.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Make while statement using pointers explicitly check whether
the value is NULL or not.
The C standard does not say that the null pointer is the same
as the pointer to memory address 0 and because of this is a good
practice always compare with the macro NULL.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
MISRA C requires that every controlling expression of and if or while
statement have a boolean type.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Make if statement using pointers explicitly check whether the value is
NULL or not.
The C standard does not say that the null pointer is the same as the
pointer to memory address 0 and because of this is a good practice
always compare with the macro NULL.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>