1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//! The application code.

use crate::device::cga::{Attribute, Rect, Window};
use crate::interrupts::guard::GUARD;
use crate::threading::APPS;
use crate::MAX_CPUS;

use core::fmt::Write;

/// An app that is started at the beginning and terminates instantly.
pub extern "C" fn init_action() {
    GUARD.run(|_| println!("Hello from the Init App!"));

    GUARD.run(|g| {
        let active = g.scheduler.active().unwrap();
        let t = g.scheduler.thread(active).unwrap();
        println!("self: {t:?}");
    });

    GUARD.run(|g| g.scheduler.exit());
}

pub extern "C" fn app_action() {
    let tid = GUARD.run(|g| g.scheduler.active().unwrap());

    let row = (tid - MAX_CPUS) as u8;

    let style = Attribute::with(((row + 3) & 0b1111).into(), (row & 0b111).into());
    let mut screen = Window::new(Rect::new(0..40, row..row + 1)).with_style(style);

    GUARD.run(|_| screen.clear());

    let mut i = 0_u16;
    loop {
        GUARD.run(|_| {
            screen.set_cursor((0, row));
            write!(screen, "i: {i}").unwrap();
        });
        i = i.wrapping_add(1);

        if row >= 1 {
            GUARD.run(|g| g.bell_ringer.sleep(&mut g.scheduler, 1 << row));
        }

        let border = APPS.div_ceil(2);
        if i == 100 && row as usize >= border {
            GUARD.run(|g| g.scheduler.kill(MAX_CPUS + row as usize - border));
        }
    }
}

pub extern "C" fn keyboard_action() {
    loop {
        GUARD.run(|g| {
            g.keyboard_sema.wait(&mut g.scheduler);
            print!("{}", g.keyboard_buf.pop_front().unwrap());
        });
    }
}