more docs, fixes, examples

master
Ondřej Hruška 4 years ago
parent 735f871ea0
commit f87d822432
Signed by untrusted user: 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.
(barrier-open LABEL)
(barrier-close LABEL)
; Set coroutine scheduler timeslice (in microseconds). Set to zero to disable preemption.
(rt-opt RT_TIMESLICE Rd'usec)
```
## Arithmetic Module

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

@ -230,7 +230,9 @@ impl RunThread {
// Do switch
let old = mem::replace(&mut self.state.cr, cr);
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 {
let time = due.saturating_duration_since(now);
trace!("No thread to switch to, sleep {:?}", time);
@ -248,7 +250,7 @@ impl RunThread {
if n_alive == 0 {
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 {

@ -12,7 +12,7 @@ use nudge::{likely};
use crate::asm::instr::cond::Flag;
use std::fmt::{Debug, Formatter};
use std::fmt;
use std::time::Instant;
use std::time::{Instant, Duration};
pub struct RunState {
pub thread_info: Arc<ThreadInfo>,
@ -95,10 +95,24 @@ impl RunState {
});
if self.cr_deadline.is_none() {
// start context switching
self.cr_deadline = Some(Instant::now() + *self.thread_info.scheduler_interval.read());
self.start_task_switching();
}
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 {

@ -1,16 +1,21 @@
(
; 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 _ safe '0' '9')
(ssleep 2)
(spawn _ unsafe 'a' 'z')
(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
; This can be interrupted any time
(:x)
(yield)
(ld r0 start)
(:l)
(msleep 5)
(ld @cout r0)
(cmp r0 end)
(j.eq :x)

Loading…
Cancel
Save