code wiki / (root) / nx_circulation.nx

nx_circulation.nx source

↩ module page · 86 lines · 2856 B

1// nx_circulation.nx -- reliable byte stream with flow control (TCP class). 2// 3// Biology: cardiovascular circulation regulates blood flow via heart 4// rate + vessel diameter + smooth-muscle tone. Substrate: reliable 5// ordered byte stream with backpressure (window-based flow control). 6 7import "nx_syscalls.nx" 8import "nx_tier.nx" 9 10const NX_CR_V_OK: nx_int = 0 11const NX_CR_V_BLOCKED: nx_int = 1 // would exceed window 12const NX_CR_V_CLOSED: nx_int = 2 13const NX_CR_V_NULL: nx_int = 3 14const NX_CR_V_N: nx_int = 4 15 16struct NxStream { 17 stream_id: nx_int, 18 state: nx_int, 19 bytes_in_flight: nx_size, 20 window_size: nx_size, 21 bytes_acked: nx_size, 22 bytes_sent_total: nx_size, 23 bytes_received_total: nx_size, 24} 25 26const NX_CR_BYTES: nx_int = 48 27const NX_CR_STATE_OPEN: nx_int = 0 28const NX_CR_STATE_HALF_CLOSED: nx_int = 1 29const NX_CR_STATE_CLOSED: nx_int = 2 30 31func nx_cr_v_is_valid(v: nx_int) -> nx_int { 32 if v < 0 { return 0 } 33 if v >= NX_CR_V_N { return 0 } 34 return 1 35} 36 37func nx_cr_stream_new(stream_id: nx_int, window_size: nx_size) -> *NxStream { 38 if window_size <= 0 { return 0 as *NxStream } 39 let raw: *u8 = sys_mmap(NX_CR_BYTES) 40 let s: *NxStream = raw as *NxStream 41 s.stream_id = stream_id 42 s.state = NX_CR_STATE_OPEN 43 s.bytes_in_flight = 0 44 s.window_size = window_size 45 s.bytes_acked = 0 46 s.bytes_sent_total = 0 47 s.bytes_received_total = 0 48 return s 49} 50 51func nx_cr_send(s: *NxStream, bytes: nx_size) -> nx_int { 52 if (s as i64) == 0 { return NX_CR_V_NULL } 53 if s.state == NX_CR_STATE_CLOSED { return NX_CR_V_CLOSED } 54 let new_in_flight: nx_size = s.bytes_in_flight + bytes 55 if new_in_flight > s.window_size { return NX_CR_V_BLOCKED } 56 s.bytes_in_flight = new_in_flight 57 s.bytes_sent_total = s.bytes_sent_total + bytes 58 return NX_CR_V_OK 59} 60 61func nx_cr_ack(s: *NxStream, bytes: nx_size) -> nx_int { 62 if (s as i64) == 0 { return NX_CR_V_NULL } 63 if bytes > s.bytes_in_flight { return NX_CR_V_BLOCKED } // can't ack more than in-flight 64 s.bytes_in_flight = s.bytes_in_flight - bytes 65 s.bytes_acked = s.bytes_acked + bytes 66 return NX_CR_V_OK 67} 68 69func nx_cr_receive(s: *NxStream, bytes: nx_size) -> nx_int { 70 if (s as i64) == 0 { return NX_CR_V_NULL } 71 if s.state == NX_CR_STATE_CLOSED { return NX_CR_V_CLOSED } 72 s.bytes_received_total = s.bytes_received_total + bytes 73 return NX_CR_V_OK 74} 75 76func nx_cr_available_window(s: *NxStream) -> nx_size { 77 if (s as i64) == 0 { return 0 } 78 if s.bytes_in_flight >= s.window_size { return 0 } 79 return s.window_size - s.bytes_in_flight 80} 81 82func nx_cr_close(s: *NxStream) -> nx_int { 83 if (s as i64) == 0 { return NX_CR_V_NULL } 84 s.state = NX_CR_STATE_CLOSED 85 return NX_CR_V_OK 86}