this adds a "kicker" thread that gets updated with a target time
to kick the UX by the FIDO2 USB handler. When the target time is
met, an "update" command is issued to the UX.
This hopefully creates an efficient mechanism for triggering a
UX redraw that also has an acceptable delay.
The ticktimer wasn't properly adjusting the upper bits, meaning delays
of more than 42 days did not function properly. This was discovered as
part of the libstd tests.
Signed-off-by: Sean Cross <sean@xobs.io>
Precursor has a custom TIMER0 module that is different from other LiteX
timers. Adapt the Renode model to match the hardware.
Signed-off-by: Sean Cross <sean@xobs.io>
There were a few corner cases when it came to thread selection. Namely,
the same thread had a higher chance of repeatedly being executed.
Clean up these corner cases, and as a result get libstd tests to pass.
Signed-off-by: Sean Cross <sean@xobs.io>
Add notes on how to properly hand memory to userspace. This does not yet
work, but is committed here as a work-in-progress.
Signed-off-by: Sean Cross <sean@xobs.io>
The default mem size got shrunk down to 4 MB earlier, but there is a
lingering issue that prevents specifying virtual addresses. As a result,
pddb and others don't work.
Temporarily revert this change.
Signed-off-by: Sean Cross <sean@xobs.io>
The process search now uses iterators properly. It's still not ideal
because it needs to investigate every process, but it's better than it
was.
Signed-off-by: Sean Cross <sean@xobs.io>
Previously we used externally-linked assembly in order to make syscalls.
Now that `asm!()` is stable, use this macro.
This will help to optimize IPC between programs and the kernel.
Additionally, it resolves an unsoundness issue where we were filling in
values on the stack and hoping that Rust didn't reorder the structs.
Signed-off-by: Sean Cross <sean@xobs.io>
The previous condvar implementation was unsound, and didn't do the right
thing. Overhaul condvars so that they now pass the libstd tests.
As part of this, function calls were added to free the mutex and condvar
objects that may have been allocated.
Signed-off-by: Sean Cross <sean@xobs.io>
Use a multiply-based algorithm to count the number of leading zeroes.
This results in a function that's just 20 instructions long.
Signed-off-by: Sean Cross <sean@xobs.io>
THe act of finding a runnable thread is so common, yet the kernel
contains three ways of doing this.
Use a unified function to select the next available thread.
Signed-off-by: Sean Cross <sean@xobs.io>
Previously the `current_thread` was set to 0, which is invalid. Set the
`current_thread` so that it defaults to the initial thread ID.
Signed-off-by: Sean Cross <sean@xobs.io>
This memory region is much smaller than the previous value of 256 MB,
but it will limit the amount of memory used by superpages in
long-running processes.
Previously, we would march through memory as messages were passed back
and forth and a process' memory space would quickly be eaten up by 1024
pages.
Signed-off-by: Sean Cross <sean@xobs.io>
When waiting on a thread, it may be the case that the thread we're
joining has exited already. In this case, the correct approach is to
resume execution rather than switching to the parent process.
This fixes an issue where `SWITCHTO_CALLER` is None when joining a
short-lived thread.
Signed-off-by: Sean Cross <sean@xobs.io>
When attempting to return an invalid item, return `DoubleFree`. This is
because such cases are most likely due to instances where a message was
responded to twice.
Signed-off-by: Sean Cross <sean@xobs.io>
Add calls to free Mutexes and Condvars. These will go in a destructor,
and will remove any trace of these mutexes within the ticktimer server.
Signed-off-by: Sean Cross <sean@xobs.io>
Rewrite the RecalculateSleep opcode handler so that it will only be
processed if sent by our own process.
As part of this rewrite, use the new `let else` pattern.
Signed-off-by: Sean Cross <sean@xobs.io>
1. track evictions as separate from cleanliness. not clean means
the data is dirty and needs writing back. eviction simply means
the data needs be re-retrieved from disk.
2. actually fill the data when we do a sync -- previously
we only copied the old data into the new page but then forgot
to allocate the data and assign it to the cache (oops)
3. sync the small pools after doing a remove inside the update()
command to make sure we've met invariants for future calls
to cache fills
so many corner cases, i'm going around in circles....
previously, we were invalidating at the first instance of
encountering the key; instead we should only invalidate once
we've processed it in our range of interest.