#line 244 "/home/ubuntu/felix/src/packages/fibres.fdoc"
open class Schannel
{
_gc_pointer type _schannel = "::flx::rtl::schannel_t*";
ctor _schannel: 1 =
"new(*ptf-> gcp,::flx::rtl::schannel_ptr_map,false) ::flx::rtl::schannel_t()"
requires property "needs_gc"
;
gen mk_null_channel : 1 -> _schannel = "(::flx::rtl::schannel*)NULL";
fun isNULL: _schannel -> bool = "!$1";
inline proc read_address (chan:_schannel, loc: &address) {
svc$ svc_sread$ chan, loc;
}
inline proc write_address (chan:_schannel, var v:address) {
svc$ svc_swrite$ chan, &v;
}
_gc_pointer type schannel[t] = "::flx::rtl::schannel_t*";
_gc_pointer type ischannel[t] = "::flx::rtl::schannel_t*";
_gc_pointer type oschannel[t] = "::flx::rtl::schannel_t*";
gen mk_schannel[t]():schannel[t] =>
C_hack::cast[schannel[t]] #_schannel
;
ctor[T] address: oschannel[T] = "$1";
ctor[T] address: ischannel[T] = "$1";
ctor[t] oschannel[t](x:schannel[t]) => C_hack::cast[oschannel[t]] x;
ctor[t] ischannel[t](x:schannel[t]) => C_hack::cast[ischannel[t]] x;
gen mk_ioschannel_pair[t](var ch:schannel[t]) =>
ischannel[t] ch, oschannel[t] ch
;
gen mk_ioschannel_pair[t]() =>
mk_ioschannel_pair[t]$ mk_schannel[t] ()
;
inline proc read_pointer[T] (chan:ischannel[&T], p: &&T) {
read_address$ C_hack::cast[_schannel] chan, C_hack::cast[&address] p;
}
inline proc write_pointer[T] (chan:oschannel[&T], var p:&T) {
write_address$ C_hack::cast[_schannel] chan, p.address;
}
proc read[T] (chan:schannel[T], loc: &&T) {
svc$ svc_sread$ C_hack::cast[_schannel] chan, C_hack::reinterpret[&root::address] (loc);
}
proc read[T] (chan:schannel[T], p: &T) {
var loc: &T;
read (chan, &loc);
p <- *loc;
}
inline gen read[T] (chan:schannel[T]) = {
var loc: &T;
read (chan, &loc);
return *loc;
}
proc read[T] (chan:ischannel[T], loc: &&T) { read (C_hack::cast[schannel[T]] chan, loc); }
proc read[T] (chan:ischannel[T], p: &T) { read (C_hack::cast[schannel[T]] chan, p); }
inline gen read[T] (chan:ischannel[T]) => read$ C_hack::cast[schannel[T]] chan;
inline gen ready[T] :ischannel[T] -> bool = "$1->top!=nullptr && !(uintptr_t)$1->top &1u)";
inline gen ready[T] : schannel[T] -> bool = "$1->top!=nullptr && (uintptr_t)$1->top &1u)";
inline gen maybe_read[T] (chan:ischannel[T]) =>
if chan.ready then Some chan.read else None[T]
;
inline gen maybe_read[T] (chan:schannel[T]) =>
if chan.ready then Some chan.read else None[T]
;
proc write[T] (chan:schannel[T], v:T) {
var ps = C_hack::cast[root::address]$ new v;
svc$ svc_swrite$ C_hack::cast[_schannel] chan, &ps;
}
proc write[T] (chan:oschannel[T], v:T) {
write (C_hack::cast[schannel[T]] chan, v);
}
proc broadcast[T] (chan:schannel[T], v:T) {
var ps = C_hack::cast[root::address]$ new v;
svc$ svc_multi_swrite$ C_hack::cast[_schannel] chan, &ps;
}
proc broadcast[T] (chan:oschannel[T], v:T) {
broadcast (C_hack::cast[schannel[T]] chan, v);
}
gen iterator[T] (i:ischannel[T]) () : opt[T] = {
next:>
var y = None[T];
frun { var x = read i; y = Some x; };
match y do
| Some _ => yield y; goto next;
| None => return y;
done
}
inline gen subcall[r,w] (chout:%>w, chin:%<r) (arg:w):r =
{
write (chout,arg);
return read chin;
}
inline fun apply[r,w] (ch:(%>w * %<r), arg:w):r =>
subcall ch arg
;
}
#line 456 "/home/ubuntu/felix/src/packages/fibres.fdoc"
open class DuplexSchannels
{
_gc_pointer type duplex_schannel[r,w] = "::flx::rtl::schannel_t*";
inline gen read[r,w] (chan:duplex_schannel[r,w]) : r =>
read (C_hack::cast[ischannel[r]] chan)
;
inline proc write[r,w] (chan:duplex_schannel[r,w], v:w) =>
write (C_hack::cast[oschannel[w]] chan, v)
;
ctor[r,w] duplex_schannel[r,w] () =>
C_hack::cast[duplex_schannel[r,w]] #_schannel
;
gen mk_duplex_schannel_pair[r,w] () =>
let c = #_schannel in
C_hack::cast[duplex_schannel[w,r]] c,
C_hack::cast[duplex_schannel[r,w]] c
;
inline gen subcall[r,w] (ch:duplex_schannel[r,w]) (arg:w):r =
{
write (ch,arg);
return read ch;
}
inline fun apply[r,w] (ch:duplex_schannel[r,w], arg:w):r =>
subcall ch arg
;
inline gen subcall[r,w]
(fib: duplex_schannel[w,r] -> 1 -> 0)
(arg: w)
: r =
{
var wr,rw = mk_duplex_schannel_pair[r,w]();
spawn_fthread$ fib wr;
write (rw,arg);
return read rw;
}
inline gen apply[r,w] (
fib: duplex_schannel[w,r] -> 1 -> 0,
arg: w)
: r =>
subcall fib arg
;
}