feat(renaser): Fase 11 — el reloj del sistema como capacidad de host
El userspace gana un sentido del tiempo: hasta ahora una app solo sabía cuántas veces la habían llamado, no cuánto tiempo había pasado. - Capacidad `sys_tiempo_mono() -> u64` — la décima función del host: los milisegundos monótonos desde el arranque. `reloj` expone la cuenta del PIT (100 Hz) como `milisegundos()`; `env` la inyecta. Lectura pura, no toca la memoria del módulo, jamás retrocede. - App nueva `pulso` (`apps/pulso/`, wasm32): un compás visual cuya escena es una función PURA de `sys_tiempo_mono` — sin estado entre fotogramas—. Dos instancias laten al unísono nazcan cuando nazcan. - `GENESIS` crece de 5 a 6 apps; `pulso` es la maestra del escritorio. Verificado en QEMU (sendkey): la barra de `pulso` avanza con el tiempo de pared; un segundo `pulso` lanzado con Alt+N ~15 s después aparece sincronizado con el primero — el compás se rige por el reloj absoluto, no por una cuenta de fotogramas. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -847,3 +847,29 @@ una app puede nacer o cerrarse con el reactor ya en marcha.
|
|||||||
re-tesela de 5 a 8 ventanas. Tres `Alt+Q` cierran la app enfocada una a una
|
re-tesela de 5 a 8 ventanas. Tres `Alt+Q` cierran la app enfocada una a una
|
||||||
y el teselado reclama su espacio, de 8 de vuelta a 5. El kernel sigue estable
|
y el teselado reclama su espacio, de 8 de vuelta a 5. El kernel sigue estable
|
||||||
a través de todas las altas y bajas.
|
a través de todas las altas y bajas.
|
||||||
|
|
||||||
|
## Fase 11 — El reloj del sistema como capacidad de host — 2026-05-22
|
||||||
|
|
||||||
|
Hasta la Fase 10 una aplicación sólo sabía CUÁNTAS veces la habían llamado —un
|
||||||
|
`tick` tras otro—, no CUÁNTO tiempo había pasado. La Fase 11 le da al userspace
|
||||||
|
un sentido del tiempo: el reloj monótono del sistema, como capacidad.
|
||||||
|
|
||||||
|
### Añadido
|
||||||
|
- **Capacidad `sys_tiempo_mono() -> u64`** — la décima función del host. Los
|
||||||
|
milisegundos transcurridos desde el arranque. El temporizador (PIT) ya late a
|
||||||
|
100 Hz; `reloj` expone esa cuenta como `milisegundos()` y `env` la inyecta.
|
||||||
|
Es una lectura PURA —no toca la memoria lineal del módulo, no hay puntero que
|
||||||
|
validar— y MONÓTONA: jamás retrocede.
|
||||||
|
- **App `pulso`** (`apps/pulso/`, `wasm32`). Un compás visual: una cabeza
|
||||||
|
brillante que recorre una pista y vuelve, con un período de 6 s. Su escena es
|
||||||
|
una FUNCIÓN PURA de `sys_tiempo_mono` —no guarda estado entre fotogramas—.
|
||||||
|
De ahí su prueba: dos instancias de `pulso`, nazca una al arrancar y otra
|
||||||
|
mucho después con un `Alt+N`, laten exactamente al unísono.
|
||||||
|
- `pulso` se suma al userspace de génesis: `GENESIS` pasa de 5 a 6 apps, con
|
||||||
|
`pulso` como la primera —la ventana maestra del escritorio—.
|
||||||
|
|
||||||
|
### Verificado
|
||||||
|
- QEMU (`sendkey`): la barra de `pulso` avanza con el tiempo de pared entre dos
|
||||||
|
capturas. Un `Alt+N` da a luz un segundo `pulso` ~15 s después del arranque;
|
||||||
|
flotado junto al primero, su barra está en la MISMA fase — la prueba de que
|
||||||
|
el compás se rige por el reloj absoluto, no por una cuenta de fotogramas.
|
||||||
|
|||||||
+4
-3
@@ -28,7 +28,7 @@ Reconstruir una app WASM del userspace tras tocarla. Los `.wasm` viven en
|
|||||||
modulo `hello_wasm` se copia como `app.wasm`, el resto conserva su nombre:
|
modulo `hello_wasm` se copia como `app.wasm`, el resto conserva su nombre:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd apps/<app> # hello_wasm, discola, glotona, cronista, memoriosa
|
cd apps/<app> # hello_wasm, discola, glotona, cronista, memoriosa, pulso
|
||||||
cargo build --target wasm32-unknown-unknown --release
|
cargo build --target wasm32-unknown-unknown --release
|
||||||
cp target/wasm32-unknown-unknown/release/<app>.wasm ../../kernel/assets/<app>.wasm
|
cp target/wasm32-unknown-unknown/release/<app>.wasm ../../kernel/assets/<app>.wasm
|
||||||
# (hello_wasm es la excepcion: su destino es kernel/assets/app.wasm)
|
# (hello_wasm es la excepcion: su destino es kernel/assets/app.wasm)
|
||||||
@@ -78,8 +78,9 @@ objetos—, la Fase 8 COMPLETA —el compositor teselante e interactivo: teselad
|
|||||||
con `mirada-layout` (8a), ciclado de layout (8b), foco y enrutamiento selectivo
|
con `mirada-layout` (8a), ciclado de layout (8b), foco y enrutamiento selectivo
|
||||||
del teclado (8c), promoción y reordenación de ventanas (8d)—, la Fase 9
|
del teclado (8c), promoción y reordenación de ventanas (8d)—, la Fase 9
|
||||||
COMPLETA —orden-Z y ventanas flotantes: composición con solapamiento (`Alt+F`)—
|
COMPLETA —orden-Z y ventanas flotantes: composición con solapamiento (`Alt+F`)—
|
||||||
y la Fase 10 COMPLETA —alta y baja de aplicaciones en vivo (`Alt+N` / `Alt+Q`)—.
|
la Fase 10 COMPLETA —alta y baja de aplicaciones en vivo (`Alt+N` / `Alt+Q`)— y
|
||||||
Todo verificado en QEMU. Ver `ROADMAP.md`.
|
la Fase 11 COMPLETA —el reloj del sistema como capacidad de host
|
||||||
|
(`sys_tiempo_mono`) + la app `pulso`—. Todo verificado en QEMU. Ver `ROADMAP.md`.
|
||||||
|
|
||||||
## Flujo de trabajo
|
## Flujo de trabajo
|
||||||
|
|
||||||
|
|||||||
@@ -434,6 +434,26 @@ y no volvía a tocar la lista. Ahora tiene una bandeja donde van dejándose los
|
|||||||
recién llegados, y en cada ronda la mira y les da su sitio. La casa ya no se
|
recién llegados, y en cada ronda la mira y les da su sitio. La casa ya no se
|
||||||
escribe entera de una vez: se va escribiendo, día a día, mientras se vive.
|
escribe entera de una vez: se va escribiendo, día a día, mientras se vive.
|
||||||
|
|
||||||
|
## El sentido del tiempo — un reloj para los inquilinos
|
||||||
|
|
||||||
|
Los inquilinos de la casa sabían hacer su trabajo, turnarse, recordar entre
|
||||||
|
sesiones. Pero había algo que no sabían: qué hora era. Vivían en un presente
|
||||||
|
sin medida —cada uno contaba las veces que lo habían despertado, y nada más—.
|
||||||
|
Dos inquilinos que empezaran la misma tarea en momentos distintos no tenían
|
||||||
|
forma de ir a la par.
|
||||||
|
|
||||||
|
Hoy la casa les regaló un reloj. No uno para cada cuarto: uno solo, en el
|
||||||
|
recibidor, que todos pueden mirar. Marca, sin más, cuánto hace que la casa
|
||||||
|
despertó. Quien quiera saber la hora, la mira; quien no, sigue a lo suyo.
|
||||||
|
|
||||||
|
Y para estrenarlo llegó un inquilino nuevo, «pulso», que no hace otra cosa que
|
||||||
|
mirar ese reloj y dibujar su paso: una luz que recorre un riel, una y otra vez,
|
||||||
|
con un compás de seis segundos. Lo hermoso es lo que ocurre al invitar a un
|
||||||
|
segundo «pulso» mucho después: no empieza su recorrido desde el principio —se
|
||||||
|
incorpora justo donde va el primero, al instante, como dos bailarines que oyen
|
||||||
|
la misma música—. Porque ninguno lleva su propia cuenta: ambos miran el mismo
|
||||||
|
reloj del recibidor.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*El diario continúa. La próxima página la escribirá la próxima jornada.*
|
*El diario continúa. La próxima página la escribirá la próxima jornada.*
|
||||||
|
|||||||
+16
-2
@@ -181,8 +181,22 @@ Verificada en QEMU (`sendkey`).
|
|||||||
- El censo de ventanas sólo crece —los índices son la identidad, jamás se
|
- El censo de ventanas sólo crece —los índices son la identidad, jamás se
|
||||||
reciclan—; una ventana cerrada queda como ranura inerte, fuera del teselado.
|
reciclan—; una ventana cerrada queda como ranura inerte, fuera del teselado.
|
||||||
|
|
||||||
Líneas abiertas posteriores: más capacidades del host (temporización, audio);
|
## Fase 11 — el reloj del sistema como capacidad de host (completada)
|
||||||
reciclado de las ranuras de ventana cerradas.
|
|
||||||
|
Hasta la Fase 10 una aplicación sólo sabía cuántas veces la habían llamado, no
|
||||||
|
cuánto tiempo había pasado. La Fase 11 le da al userspace un sentido del
|
||||||
|
tiempo. Verificada en QEMU (`sendkey`).
|
||||||
|
|
||||||
|
- Capacidad `sys_tiempo_mono`: los milisegundos monótonos desde el arranque —la
|
||||||
|
décima función del host—. El temporizador (PIT) ya late a 100 Hz; `reloj`
|
||||||
|
expone esa cuenta y `env` la inyecta. Lectura pura, jamás retrocede.
|
||||||
|
- App nueva `pulso`: un compás visual cuya escena es una función PURA del reloj
|
||||||
|
del host. Dos instancias, nazcan cuando nazcan, laten al unísono — la prueba
|
||||||
|
de que el tiempo es absoluto, no una cuenta de fotogramas.
|
||||||
|
- El userspace de génesis crece de 5 a 6 apps.
|
||||||
|
|
||||||
|
Líneas abiertas posteriores: audio como capacidad de host; reciclado de las
|
||||||
|
ranuras de ventana cerradas.
|
||||||
|
|
||||||
## Principios que persisten entre fases
|
## Principios que persisten entre fases
|
||||||
|
|
||||||
|
|||||||
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulso"
|
||||||
|
version = "0.1.0"
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# renaser :: apps/pulso — Fase 11 :: el compas visual del reloj del host
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Un modulo WebAssembly puro que no guarda estado alguno: su escena es una
|
||||||
|
# funcion pura del reloj monotono del sistema (`sys_tiempo_mono`). Por eso dos
|
||||||
|
# instancias de `pulso`, nazcan cuando nazcan, laten al unisono. Tiene su
|
||||||
|
# propio `[workspace]`: queda fuera del espacio de trabajo del kernel.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "pulso"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
description = "renaser :: app WASM — un compas visual gobernado por el reloj del host"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
|
||||||
|
# `cdylib` produce un modulo `.wasm` que exporta funciones — el formato que
|
||||||
|
# wasmi instancia. La aplicacion solo habla con el kernel por funciones del host.
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
|
opt-level = "s"
|
||||||
|
lto = true
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// renaser :: apps/pulso — Fase 11 :: el compas visual del reloj del host
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Hasta la Fase 10 una aplicacion solo sabia CUANTAS veces la habian llamado
|
||||||
|
// —un `tick` tras otro—, no CUANTO tiempo habia pasado. La Fase 11 le da al
|
||||||
|
// userspace un reloj: la capacidad `sys_tiempo_mono`, los milisegundos
|
||||||
|
// monotonos desde el arranque.
|
||||||
|
//
|
||||||
|
// `pulso` es su testigo. Dibuja un compas —una cabeza brillante que recorre
|
||||||
|
// una pista y vuelve— cuya posicion es una FUNCION PURA del reloj del host.
|
||||||
|
// No guarda estado entre fotogramas: no le hace falta. Y de ahi su prueba:
|
||||||
|
// dos instancias de `pulso`, nazca una al arrancar y otra mucho despues con
|
||||||
|
// un `Alt+N`, laten EXACTAMENTE al unisono — porque ambas leen el mismo
|
||||||
|
// reloj, no un contador propio de fotogramas.
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
// --- Las capacidades que el kernel `renaser` inyecta a esta aplicacion. ---
|
||||||
|
#[link(wasm_import_module = "renaser")]
|
||||||
|
extern "C" {
|
||||||
|
/// Compone un bufer de pixeles (de ESTA memoria lineal) en la region que el
|
||||||
|
/// kernel asigno a esta aplicacion.
|
||||||
|
fn sys_render_frame(ptr: u32, len: u32);
|
||||||
|
/// El reloj monotono del sistema: milisegundos desde el arranque.
|
||||||
|
fn sys_tiempo_mono() -> u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sin sistema operativo bajo nosotros, un panico solo puede detenerse en seco.
|
||||||
|
#[panic_handler]
|
||||||
|
fn al_fallar(_: &core::panic::PanicInfo) -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Geometria de la escena. El ancho y el alto DEBEN coincidir con la region
|
||||||
|
// que el kernel asigna a esta app. ---
|
||||||
|
const ANCHO: usize = 360;
|
||||||
|
const ALTO: usize = 120;
|
||||||
|
|
||||||
|
/// El periodo del compas, en milisegundos: la cabeza recorre la pista entera y
|
||||||
|
/// vuelve a empezar cada `PERIODO`.
|
||||||
|
const PERIODO: u64 = 6000;
|
||||||
|
|
||||||
|
/// Azul nocturno: el fondo del lienzo.
|
||||||
|
const FONDO: u32 = 0x0A_18_30;
|
||||||
|
/// La pista por donde corre el compas — un surco tenue.
|
||||||
|
const PISTA: u32 = 0x1E_2A_44;
|
||||||
|
/// La estela ya recorrida en este ciclo.
|
||||||
|
const ESTELA: u32 = 0x2E_50_C8;
|
||||||
|
/// La cabeza del compas — el indigo brillante del foco del compositor.
|
||||||
|
const CABEZA: u32 = 0x8B_5C_F6;
|
||||||
|
|
||||||
|
/// Margen lateral de la pista, en pixeles.
|
||||||
|
const MARGEN: usize = 24;
|
||||||
|
/// Filas que ocupa la pista — un surco horizontal centrado en el lienzo.
|
||||||
|
const PISTA_Y0: usize = 46;
|
||||||
|
const PISTA_Y1: usize = 74;
|
||||||
|
/// Anchura de la cabeza del compas, en pixeles.
|
||||||
|
const CABEZA_ANCHO: usize = 7;
|
||||||
|
|
||||||
|
/// El lienzo de la aplicacion, en SU propia memoria lineal. El kernel jamas lo
|
||||||
|
/// ve directamente: solo recibe el (ptr, len) que cada fotograma le entrega.
|
||||||
|
static mut LIENZO: [u32; ANCHO * ALTO] = [0; ANCHO * ALTO];
|
||||||
|
|
||||||
|
/// Preparacion: el kernel la invoca UNA sola vez, al cargar el modulo. Pinta el
|
||||||
|
/// primer fotograma — el compas en el instante de nacer.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn init() {
|
||||||
|
pintar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Un fotograma de trabajo: vuelve a pintar el compas en el instante actual y
|
||||||
|
/// RETORNA, cediendo la CPU al kernel y a las apps vecinas.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn tick() {
|
||||||
|
pintar();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pinta el compas en el instante ACTUAL. No guarda estado alguno: la escena es
|
||||||
|
/// una funcion pura del reloj del host. Por eso dos instancias de `pulso`,
|
||||||
|
/// nazcan cuando nazcan, laten EXACTAMENTE al unisono.
|
||||||
|
fn pintar() {
|
||||||
|
// SEGURIDAD: durante `init` y `tick` esta es la unica via de acceso a
|
||||||
|
// LIENZO, y el kernel jamas reentra el modulo mientras una de ellas corre.
|
||||||
|
let lienzo: &mut [u32] = unsafe { &mut *core::ptr::addr_of_mut!(LIENZO) };
|
||||||
|
|
||||||
|
// La fase del compas: 0 al inicio del periodo, casi 1 al final. Se deriva
|
||||||
|
// SOLO del reloj del host — ni un contador propio, ni un origen guardado.
|
||||||
|
// SEGURIDAD: `sys_tiempo_mono` es una capacidad del host; no toca memoria.
|
||||||
|
let tiempo = unsafe { sys_tiempo_mono() };
|
||||||
|
let fase = tiempo % PERIODO;
|
||||||
|
|
||||||
|
// El ancho util de la pista y hasta donde ha llegado la cabeza.
|
||||||
|
let util = ANCHO - 2 * MARGEN;
|
||||||
|
let avance = (fase as usize * util) / PERIODO as usize;
|
||||||
|
|
||||||
|
// Fondo limpio.
|
||||||
|
for pixel in lienzo.iter_mut() {
|
||||||
|
*pixel = FONDO;
|
||||||
|
}
|
||||||
|
// La pista entera, tenue.
|
||||||
|
banda(lienzo, MARGEN, MARGEN + util, PISTA);
|
||||||
|
// La estela ya recorrida en este ciclo.
|
||||||
|
banda(lienzo, MARGEN, MARGEN + avance, ESTELA);
|
||||||
|
// La cabeza del compas: una barra brillante al frente de la estela.
|
||||||
|
let cabeza0 = MARGEN + avance;
|
||||||
|
banda(lienzo, cabeza0, cabeza0 + CABEZA_ANCHO, CABEZA);
|
||||||
|
|
||||||
|
volcar(lienzo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rellena la pista —las filas [`PISTA_Y0`, `PISTA_Y1`)— entre las columnas
|
||||||
|
/// [x0, x1) con un color, recortado con firmeza al ancho del lienzo.
|
||||||
|
fn banda(lienzo: &mut [u32], x0: usize, x1: usize, color: u32) {
|
||||||
|
let x0 = x0.min(ANCHO);
|
||||||
|
let x1 = x1.min(ANCHO);
|
||||||
|
let mut fila = PISTA_Y0;
|
||||||
|
while fila < PISTA_Y1 {
|
||||||
|
let base = fila * ANCHO;
|
||||||
|
let mut col = x0;
|
||||||
|
while col < x1 {
|
||||||
|
lienzo[base + col] = color;
|
||||||
|
col += 1;
|
||||||
|
}
|
||||||
|
fila += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Entrega el lienzo completo al kernel. El (ptr, len) apunta SIEMPRE dentro de
|
||||||
|
/// nuestra memoria lineal, y su tamaño es, exactamente, el de la region.
|
||||||
|
fn volcar(lienzo: &[u32]) {
|
||||||
|
// SEGURIDAD: `sys_render_frame` es una capacidad del host; el (ptr, len)
|
||||||
|
// describe nuestra propia memoria lineal y el host lo verifica sin piedad.
|
||||||
|
unsafe {
|
||||||
|
sys_render_frame(lienzo.as_ptr() as u32, (ANCHO * ALTO * 4) as u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -107,11 +107,13 @@ struct AppGenesis {
|
|||||||
region: (u32, u32, u32, u32),
|
region: (u32, u32, u32, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// El userspace de genesis — las cinco aplicaciones que pueblan un disco recien
|
/// El userspace de genesis — las seis aplicaciones que pueblan un disco recien
|
||||||
/// forjado. Un saludo (`hola`), la `memoriosa` interactiva que recuerda entre
|
/// forjado. El compas visual `pulso` (Fase 11), un saludo (`hola`), la
|
||||||
/// sesiones (Fase 7c), y tres demos de los guardarrailes del kernel: `discola`
|
/// `memoriosa` interactiva que recuerda entre sesiones (Fase 7c), y tres demos
|
||||||
/// (combustible), `glotona` (memoria) y `cronista` (la cronica de los arranques).
|
/// de los guardarrailes del kernel: `discola` (combustible), `glotona`
|
||||||
const GENESIS: [AppGenesis; 5] = [
|
/// (memoria) y `cronista` (la cronica de los arranques).
|
||||||
|
const GENESIS: [AppGenesis; 6] = [
|
||||||
|
AppGenesis { nombre: "pulso", archivo: "pulso.wasm", region: (100, 120, 360, 120) },
|
||||||
AppGenesis { nombre: "hola", archivo: "app.wasm", region: (100, 120, 480, 560) },
|
AppGenesis { nombre: "hola", archivo: "app.wasm", region: (100, 120, 480, 560) },
|
||||||
AppGenesis { nombre: "memoriosa", archivo: "memoriosa.wasm", region: (700, 120, 360, 80) },
|
AppGenesis { nombre: "memoriosa", archivo: "memoriosa.wasm", region: (700, 120, 360, 80) },
|
||||||
AppGenesis { nombre: "discola", archivo: "discola.wasm", region: (60, 700, 360, 80) },
|
AppGenesis { nombre: "discola", archivo: "discola.wasm", region: (60, 700, 360, 80) },
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
@@ -54,6 +54,13 @@ fn pulsos() -> u64 {
|
|||||||
CONTADOR_PULSOS.load(Ordering::Acquire)
|
CONTADOR_PULSOS.load(Ordering::Acquire)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Milisegundos transcurridos desde el arranque (Fase 11). El temporizador late
|
||||||
|
/// a 100 Hz —un pulso cada 10 ms—; esta es la lectura del reloj MONOTONO que el
|
||||||
|
/// host ofrece al userspace como `sys_tiempo_mono`. Jamas retrocede.
|
||||||
|
pub fn milisegundos() -> u64 {
|
||||||
|
pulsos().saturating_mul(10)
|
||||||
|
}
|
||||||
|
|
||||||
/// Inscribe un waker en el censo de espera del proximo fotograma.
|
/// Inscribe un waker en el censo de espera del proximo fotograma.
|
||||||
fn inscribir(waker: Waker) {
|
fn inscribir(waker: Waker) {
|
||||||
if let Some(censo) = EN_ESPERA.get() {
|
if let Some(censo) = EN_ESPERA.get() {
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
// * sys_object_raiz — leer la raiz del grafo;
|
// * sys_object_raiz — leer la raiz del grafo;
|
||||||
// * sys_object_fijar_raiz — coronar un objeto como raiz;
|
// * sys_object_fijar_raiz — coronar un objeto como raiz;
|
||||||
// * sys_estado_cargar — leer el estado persistido de la app (Fase 7c);
|
// * sys_estado_cargar — leer el estado persistido de la app (Fase 7c);
|
||||||
// * sys_estado_guardar — anclar el estado persistido de la app (Fase 7c).
|
// * sys_estado_guardar — anclar el estado persistido de la app (Fase 7c);
|
||||||
|
// * sys_tiempo_mono — leer el reloj monotono del sistema (Fase 11).
|
||||||
//
|
//
|
||||||
// GUARDARRAIL: el kernel valida MATEMATICAMENTE todo puntero que el modulo le
|
// GUARDARRAIL: el kernel valida MATEMATICAMENTE todo puntero que el modulo le
|
||||||
// entrega contra los limites reales de su memoria lineal. No se confia en que
|
// entrega contra los limites reales de su memoria lineal. No se confia en que
|
||||||
@@ -442,5 +443,19 @@ pub(crate) fn enlazar_capacidades(
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// --- CAPACIDAD 10 :: sys_tiempo_mono() -> u64 ---
|
||||||
|
// El reloj MONOTONO del sistema: milisegundos transcurridos desde el
|
||||||
|
// arranque. Le da al userspace un sentido del tiempo independiente del
|
||||||
|
// ritmo de los fotogramas — una app sabe CUANTO ha pasado, no solo CUANTAS
|
||||||
|
// veces la han llamado—. Jamas retrocede. No toca la memoria del modulo:
|
||||||
|
// es una lectura pura, sin puntero que validar.
|
||||||
|
enlazador.func_wrap(
|
||||||
|
"renaser",
|
||||||
|
"sys_tiempo_mono",
|
||||||
|
|_caller: Caller<'_, ContextoCapacidades>| -> u64 {
|
||||||
|
crate::async_system::reloj::milisegundos()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user