more docs, fixes, examples

master
Ondřej Hruška 4 years ago
parent 735f871ea0
commit f87d822432
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 3
      README.md
  2. 2
      crsn/src/builtin/parse.rs
  3. 6
      crsn/src/runtime/run_thread.rs
  4. 18
      crsn/src/runtime/run_thread/state.rs
  5. 11
      examples/coroutines3-crit.csn

@ -545,6 +545,9 @@ Jumping to a label is always safer than a manual skip.
; The label can be a numeric or string label, its sole purpose is tying the two together. They must be unique in the program. ; The label can be a numeric or string label, its sole purpose is tying the two together. They must be unique in the program.
(barrier-open LABEL) (barrier-open LABEL)
(barrier-close LABEL) (barrier-close LABEL)
; Set coroutine scheduler timeslice (in microseconds). Set to zero to disable preemption.
(rt-opt RT_TIMESLICE Rd'usec)
``` ```
## Arithmetic Module ## Arithmetic Module

@ -613,7 +613,7 @@ mod test {
global_regs: [0; REG_COUNT], global_regs: [0; REG_COUNT],
ext_data: Default::default(), ext_data: Default::default(),
cr_deadline: None, cr_deadline: None,
critical_section: false, critical_section: 0,
}, },
const_eval_ti: ti.clone(), const_eval_ti: ti.clone(),
parsing_expr: false, parsing_expr: false,

@ -230,7 +230,9 @@ impl RunThread {
// Do switch // Do switch
let old = mem::replace(&mut self.state.cr, cr); let old = mem::replace(&mut self.state.cr, cr);
self.state.parked.push_back(old); self.state.parked.push_back(old);
self.state.cr_deadline = Some(now + *self.info.scheduler_interval.read());
self.state.start_task_switching();
} else if let Some(due) = closest_due { } else if let Some(due) = closest_due {
let time = due.saturating_duration_since(now); let time = due.saturating_duration_since(now);
trace!("No thread to switch to, sleep {:?}", time); trace!("No thread to switch to, sleep {:?}", time);
@ -248,7 +250,7 @@ impl RunThread {
if n_alive == 0 { if n_alive == 0 {
trace!("Stop task switching, no parked threads are alive"); trace!("Stop task switching, no parked threads are alive");
self.state.cr_deadline = None; self.state.stop_task_switching(); // This should improve performance in single-threaded mode
} }
match self.state.cr.cr_state { match self.state.cr.cr_state {

@ -12,7 +12,7 @@ use nudge::{likely};
use crate::asm::instr::cond::Flag; use crate::asm::instr::cond::Flag;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::fmt; use std::fmt;
use std::time::Instant; use std::time::{Instant, Duration};
pub struct RunState { pub struct RunState {
pub thread_info: Arc<ThreadInfo>, pub thread_info: Arc<ThreadInfo>,
@ -95,10 +95,24 @@ impl RunState {
}); });
if self.cr_deadline.is_none() { if self.cr_deadline.is_none() {
// start context switching // start context switching
self.cr_deadline = Some(Instant::now() + *self.thread_info.scheduler_interval.read()); self.start_task_switching();
} }
handle handle
} }
pub(crate) fn start_task_switching(&mut self) {
let ival = *self.thread_info.scheduler_interval.read();
if ival > Duration::default() {
self.cr_deadline = Some(Instant::now() + ival);
} else {
// Disabled
self.cr_deadline = None;
}
}
pub(crate) fn stop_task_switching(&mut self) {
self.cr_deadline = None;
}
} }
impl Debug for RunState { impl Debug for RunState {

@ -1,16 +1,21 @@
( (
; This example shows the use of critical sections. ; This example shows the use of critical sections.
; Set short timeslice (50us) to make the effect more pronounced
(rt-opt RT_TIMESLICE 50)
(spawn _ unsafe 'A' 'Z') (spawn _ unsafe 'A' 'Z')
(spawn _ safe '0' '9') (spawn _ unsafe 'a' 'z')
(ssleep 2) (spawn _ safe '0' '9') ; Notice that the sequence 0-9 is always printed in its entirety - because it is in a critical section
(msleep 200)
(halt)
(proc unsafe start end (proc unsafe start end
; This can be interrupted any time ; This can be interrupted any time
(:x) (:x)
(yield)
(ld r0 start) (ld r0 start)
(:l) (:l)
(msleep 5)
(ld @cout r0) (ld @cout r0)
(cmp r0 end) (cmp r0 end)
(j.eq :x) (j.eq :x)

Loading…
Cancel
Save