add rt_abort, call rt_panic from rust panic handler on target_os = "none"

This commit is contained in:
Chris Copeland 2024-06-03 01:59:27 -07:00
parent c57a265e0b
commit e365b58343
Signed by: chrisnc
GPG Key ID: 14550DA72485DF30
24 changed files with 140 additions and 65 deletions

View File

@ -1,3 +1,4 @@
#include <rt/abort.h>
#include <rt/context.h>
#include <rt/cycle.h>
#include <rt/idle.h>
@ -22,7 +23,8 @@ __attribute__((noreturn)) void rt_task_entry(void);
#include "m/m.c"
#endif
static struct context *context_init(uintptr_t fn, void *stack, size_t stack_size)
static struct context *context_init(uintptr_t fn, void *stack,
size_t stack_size)
{
void *const sp = (char *)stack + stack_size;
struct context *ctx = sp;
@ -67,6 +69,14 @@ __attribute__((noreturn, weak)) void rt_idle(void)
}
}
__attribute__((noreturn, weak)) void rt_abort(void)
{
for (;;)
{
__asm__("udf" :::);
}
}
__attribute__((noreturn, weak)) void rt_trap(void)
{
for (;;)

View File

@ -1,3 +1,4 @@
#include <rt/abort.h>
#include <rt/context.h>
#include <rt/idle.h>
#include <rt/log.h>
@ -127,7 +128,15 @@ __attribute__((noreturn, weak)) void rt_idle(void)
}
}
__attribute__((noreturn)) void rt_trap(void)
__attribute__((noreturn, weak)) void rt_abort(void)
{
for (;;)
{
__asm__(" itrap0");
}
}
__attribute__((noreturn, weak)) void rt_trap(void)
{
for (;;)
{

View File

@ -1,3 +1,4 @@
#include <rt/abort.h>
#include <rt/arch/init.h>
#include <rt/arch/irq.h>
#include <rt/arch/syscall.h>
@ -86,6 +87,11 @@ void rt_logf(const char *format, ...)
}
#endif
__attribute__((noreturn)) void rt_abort(void)
{
abort();
}
__attribute__((noreturn)) void rt_panic(const char *msg)
{
block_async_signals(NULL);

View File

@ -10,7 +10,7 @@ static rt::cond cond;
static unsigned x = 0;
static bool flag = false;
#define ITERATIONS 10000
#define ITERATIONS 1000
static void signaler(void)
{

View File

@ -9,7 +9,7 @@ static RT_COND(cond);
static unsigned x = 0;
static bool flag = false;
#define ITERATIONS 10000
#define ITERATIONS 1000
static void signaler(void)
{

11
include/rt/abort.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
__attribute__((noreturn)) void rt_abort(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,7 @@
#pragma once
#include <rt/atomic.h>
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -1,13 +1,11 @@
use std::{env, path::PathBuf};
static SOURCES: &[&str] = &[
"assert.c",
"barrier.c",
"cond.c",
"list.c",
"mutex.c",
"notify.c",
"panic.c",
"queue.c",
"rt.c",
"rwlock.c",

View File

@ -8,7 +8,7 @@ rt::condvar!(COND);
static FLAG: AtomicBool = AtomicBool::new(false);
const ITERATIONS: i32 = 10000;
const ITERATIONS: i32 = 1000;
fn signaler() {
rt::task::drop_privilege();
@ -38,4 +38,4 @@ fn timeout() {
rt::task!(signaler, rt::task::STACK_MIN, 2);
rt::task!(incrementer, rt::task::STACK_MIN, 1);
rt::task!(incrementer, rt::task::STACK_MIN, 1);
rt::task!(timeout, rt::task::STACK_MIN, 0);
rt::task!(timeout, rt::task::STACK_MIN * 3, 0);

View File

@ -66,9 +66,9 @@ fn donator() {
sequence(9);
}
const STACK_SIZE: usize = rt::task::STACK_MIN * 2;
const STACK_SIZE: usize = rt::task::STACK_MIN * 4;
rt::task!(locker0, STACK_SIZE, 3);
rt::task!(locker1, STACK_SIZE, 2);
rt::task!(spinner, rt::task::STACK_MIN, 1);
rt::task!(spinner, STACK_SIZE, 1);
rt::task!(donator, STACK_SIZE, 0);

View File

@ -26,6 +26,8 @@ fn timeout() {
rt::trap();
}
rt::task!(f(1), 2 * rt::task::STACK_MIN, 1);
rt::task!(f(2), 2 * rt::task::STACK_MIN, 1);
const STACK_SIZE: usize = rt::task::STACK_MIN * 2;
rt::task!(f(1), STACK_SIZE, 1);
rt::task!(f(2), STACK_SIZE, 1);
rt::task!(timeout, rt::task::STACK_MIN, 0);

View File

@ -59,7 +59,9 @@ fn timeout() {
panic!("timed out");
}
rt::task!(increment_lock, rt::task::STACK_MIN, 1);
rt::task!(increment_trylock, rt::task::STACK_MIN, 1);
rt::task!(increment_timedlock, rt::task::STACK_MIN, 1);
rt::task!(timeout, rt::task::STACK_MIN, 0);
const STACK_SIZE: usize = rt::task::STACK_MIN * 4;
rt::task!(increment_lock, STACK_SIZE, 1);
rt::task!(increment_trylock, STACK_SIZE, 1);
rt::task!(increment_timedlock, STACK_SIZE, 1);
rt::task!(timeout, STACK_SIZE, 0);

View File

@ -29,5 +29,7 @@ fn waiter() {
rt::trap();
}
const STACK_SIZE: usize = rt::task::STACK_MIN * 4;
rt::task!(notifier, rt::task::STACK_MIN, 0);
rt::task!(waiter, rt::task::STACK_MIN, 0);
rt::task!(waiter, STACK_SIZE, 0);

View File

@ -32,4 +32,4 @@ fn oncer_trap() {
}
rt::task!(oncer, rt::task::STACK_MIN, 0);
rt::task!(oncer_trap, rt::task::STACK_MIN, 0);
rt::task!(oncer_trap, rt::task::STACK_MIN * 4, 0);

View File

@ -43,7 +43,7 @@ fn timeout() {
rt::trap();
}
const STACK_SIZE: usize = rt::task::STACK_MIN * 2;
const STACK_SIZE: usize = rt::task::STACK_MIN * 4;
rt::task!(pusher(0), STACK_SIZE, 1);
rt::task!(pusher(TASK_INC), STACK_SIZE, 1);

View File

@ -33,7 +33,9 @@ fn timeout() {
rt::trap();
}
rt::task!(reader, rt::task::STACK_MIN, 1);
rt::task!(reader, rt::task::STACK_MIN, 1);
const STACK_SIZE: usize = rt::task::STACK_MIN * 4;
rt::task!(reader, STACK_SIZE, 1);
rt::task!(reader, STACK_SIZE, 1);
rt::task!(writer, rt::task::STACK_MIN, 1);
rt::task!(timeout, rt::task::STACK_MIN, 0);

View File

@ -26,4 +26,4 @@ fn waiter() {
}
rt::task!(poster, rt::task::STACK_MIN, 0);
rt::task!(waiter, rt::task::STACK_MIN, 0);
rt::task!(waiter, rt::task::STACK_MIN * 4, 0);

View File

@ -23,5 +23,7 @@ fn sleep_periodic(period: rt::tick::Utick) {
}
}
rt::task!(sleep_periodic(5), rt::task::STACK_MIN, 0);
rt::task!(sleep_periodic(10), rt::task::STACK_MIN, 1);
const STACK_SIZE: usize = rt::task::STACK_MIN * 4;
rt::task!(sleep_periodic(5), STACK_SIZE, 0);
rt::task!(sleep_periodic(10), STACK_SIZE, 1);

View File

@ -13,11 +13,6 @@ pub fn trap() -> ! {
unsafe { bindings::rt_trap() }
}
#[inline]
pub fn panic(m: &str) -> ! {
unsafe { bindings::rt_panic(m.as_ptr().cast()) }
}
/* The paste macro must be re-exported so rt's macros can use it without
* other crates directly using paste. */
#[doc(hidden)]
@ -34,14 +29,4 @@ fn test_init() {
}
#[cfg(target_os = "none")]
use core::panic::PanicInfo;
#[cfg(target_os = "none")]
#[panic_handler]
fn panic_handler(panic_info: &PanicInfo) -> ! {
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
panic(s)
} else {
panic("panic")
}
}
mod panic;

51
rust/src/panic.rs Normal file
View File

@ -0,0 +1,51 @@
use core::{fmt::Write, panic::PanicInfo};
#[inline]
fn panic(m: &str) -> ! {
unsafe { crate::bindings::rt_panic(m.as_ptr().cast()) }
}
struct PanicBuf<const N: usize> {
cursor: usize,
buf: [u8; N],
}
impl<const N: usize> PanicBuf<N> {
const fn new() -> PanicBuf<N> {
PanicBuf {
cursor: 0,
buf: [0; N],
}
}
const fn as_str(&self) -> &str {
unsafe { core::str::from_utf8_unchecked(&self.buf) }
}
}
impl<const N: usize> core::fmt::Write for PanicBuf<N> {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
for &b in s.as_bytes() {
if let Some(e) = self.buf.get_mut(self.cursor) {
*e = b;
self.cursor += 1;
} else {
break;
}
}
Ok(())
}
}
#[panic_handler]
fn panic_handler(panic_info: &PanicInfo) -> ! {
use crate::panic::PanicBuf;
if let Some(s) = panic_info.payload().downcast_ref::<&str>() {
panic(s)
} else {
let mut panic_buf: PanicBuf<128> = PanicBuf::new();
let _ = core::write!(panic_buf, "{}", panic_info);
panic(panic_buf.as_str())
}
}

View File

@ -3,14 +3,12 @@ Import("env")
librt = env.StaticLibrary(
target="rt",
source=[
"assert.c",
"barrier.c",
"cond.c",
"list.c",
"mutex.c",
"notify.c",
"once.c",
"panic.c",
"queue.c",
"rt.c",
"rwlock.c",

View File

@ -1,11 +0,0 @@
#include <rt/assert.h>
#include <rt/panic.h>
__attribute__((weak)) void rt_assert(bool condition, const char *msg)
{
if (!condition)
{
rt_panic(msg);
}
}

View File

@ -1,12 +0,0 @@
#include <rt/panic.h>
#include <rt/atomic.h>
#include <rt/trap.h>
static rt_atomic(const char *) rt_panic_msg;
__attribute__((weak, noreturn)) void rt_panic(const char *msg)
{
rt_atomic_store(&rt_panic_msg, msg, RT_ATOMIC_SEQ_CST);
rt_trap();
}

View File

@ -1,3 +1,4 @@
#include <rt/abort.h>
#include <rt/atomic.h>
#include <rt/container.h>
#include <rt/context.h>
@ -7,6 +8,7 @@
#include <rt/log.h>
#include <rt/mpu.h>
#include <rt/mutex.h>
#include <rt/panic.h>
#include <rt/sem.h>
#include <rt/start.h>
#include <rt/syscall.h>
@ -671,3 +673,19 @@ void *rt_syscall_run_pending(void)
rt_task_cycle_resume();
return new_ctx;
}
static rt_atomic(const char *) rt_panic_msg;
__attribute__((weak, noreturn)) void rt_panic(const char *msg)
{
rt_atomic_store(&rt_panic_msg, msg, RT_ATOMIC_SEQ_CST);
rt_abort();
}
__attribute__((weak)) void rt_assert(bool condition, const char *msg)
{
if (!condition)
{
rt_panic(msg);
}
}