Skip to main content

kernel_api/
lib.rs

1//! Popcorn2 kernel public API.
2//! 
3//! Provides a mix of utility types and functions to replace the lack of `std`, as well as a stable API to kernel internals.
4
5#![feature(debug_closure_helpers)]
6#![feature(ptr_metadata)]
7#![feature(min_specialization)]
8#![feature(step_trait)]
9#![feature(doc_cfg)]
10#![feature(arbitrary_self_types_pointers)]
11#![feature(cfg_target_has_atomic)]
12#![feature(const_trait_impl)]
13#![feature(const_convert)]
14#![feature(const_ops)]
15#![feature(const_option_ops)]
16#![feature(integer_widen_truncate)]
17#![feature(formatting_options)]
18#![cfg_attr(doc, feature(rustdoc_missing_doc_code_examples))]
19
20#![cfg_attr(target_has_atomic_load_store = "128", feature(integer_atomics))]
21
22#![cfg_attr(feature = "full", feature(type_changing_struct_update))]
23#![cfg_attr(feature = "full", feature(unsize))]
24#![cfg_attr(feature = "full", feature(dispatch_from_dyn))]
25#![cfg_attr(feature = "full", feature(coerce_unsized))]
26#![cfg_attr(feature = "full", feature(pointer_is_aligned_to))]
27#![cfg_attr(feature = "full", feature(slice_ptr_get))]
28#![cfg_attr(feature = "full", feature(maybe_uninit_fill))]
29#![cfg_attr(feature = "full", feature(sanitize))]
30#![cfg_attr(feature = "full", feature(negative_impls))]
31#![cfg_attr(feature = "full", feature(decl_macro))]
32#![cfg_attr(feature = "full", feature(const_default))]
33
34#![allow(type_alias_bounds)]
35
36#![cfg_attr(not(feature = "use_std"), no_std)]
37
38#[cfg(feature = "full")] extern crate alloc;
39
40pub mod memory;
41
42#[cfg(feature = "full")]
43pub mod sync;
44
45#[cfg(feature = "full")]
46mod bridge;
47
48pub mod ptr;
49
50#[cfg(feature = "full")]
51pub mod time;
52
53#[cfg(feature = "full")]
54pub mod detect;
55
56#[cfg(feature = "full")]
57pub mod address_space;
58
59pub mod mapping;
60
61#[cfg(feature = "full")]
62pub mod allocator;
63
64#[cfg(feature = "full")]
65pub mod threading;
66
67#[cfg(feature = "full")]
68pub mod syscall;
69
70#[cfg(feature = "full")]
71pub mod channel;
72
73#[cfg(feature = "full")]
74pub mod modules;
75
76pub mod num;
77
78#[cfg(feature = "full")]
79mod sealed {
80    pub trait Sealed {}
81}
82
83/// Prints and returns the value of a given expression for quick and dirty debugging.
84///
85/// # Examples
86///
87/// ```
88/// # fn complex_operation() -> i8 { 5 }
89/// // prints `complex_operation() = ...` and assigns the result to `x`
90/// let x = dbg!(complex_operation());
91/// ```
92#[macro_export]
93macro_rules! dbg {
94    ($val:expr $(,)?) => {
95        // Use of `match` here is intentional because it affects the lifetimes
96        // of temporaries - https://stackoverflow.com/a/48732525/1063961
97        match $val {
98            tmp => {
99                ::log::debug!("{} = {:#x?}",
100                    ::core::stringify!($val), &tmp);
101                tmp
102            }
103        }
104    };
105    ($($val:expr),+ $(,)?) => {
106        ($($crate::dbg!($val)),+,)
107    };
108}
109
110/// Creates a struct newtype from an enum definition.
111///
112/// The enum is represented as a tuple struct with a single field of type `base_integer`.
113/// Each variant is converted to an associated constant of the same name, with value equal
114/// to `$type($value)`.
115///
116/// This allows for representing enums that do not have a fixed set of variants, as creating
117/// an enum in Rust with an out of range discriminant is undefined behaviour.
118///
119/// # Examples
120///
121/// ```
122/// use kernel_api::newtype_enum;
123///
124/// newtype_enum! {
125///     /// The type of food requested.
126///     pub enum FoodType: pub u8 => {
127///         /// Red and round.
128///         TOMATO = 0,
129///         /// Green and cylindrical.
130///         CUCUMBER = 1,
131///     }
132/// }
133///
134/// assert_eq!(FoodType::TOMATO, FoodType(0));
135/// assert_eq!(FoodType::CUCUMBER, FoodType(1));
136/// let carrot = FoodType(2);
137/// ```
138#[macro_export]
139macro_rules! newtype_enum {
140    (
141        $(#[$type_attrs:meta])*
142        $visibility:vis enum $type:ident : $base_vis:vis $base_integer:ty => $(#[$impl_attrs:meta])* {
143            $(
144                $(#[$variant_attrs:meta])*
145                $variant:ident = $value:expr,
146            )*
147        }
148    ) => {
149        $(#[$type_attrs])*
150        #[repr(transparent)]
151        #[derive(Clone, Copy, Eq, PartialEq)]
152        $visibility struct $type($base_vis $base_integer);
153
154        $(#[$impl_attrs])*
155        #[allow(unused)]
156        impl $type {
157            $(
158                $(#[$variant_attrs])*
159                pub const $variant: $type = $type($value);
160            )*
161        }
162
163        #[allow(unused)]
164        impl core::fmt::Debug for $type {
165            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
166                match *self {
167                    // Display variants by their name, like Rust enums do
168                    $(
169                        $type::$variant => write!(f, stringify!($variant)),
170                    )*
171
172                    // Display unknown variants in tuple struct format
173                    $type(unknown) => {
174                        write!(f, "{}({})", stringify!($type), unknown)
175                    }
176                }
177            }
178        }
179    }
180}
181