1
1
use crate :: io;
2
+ use crate :: mem:: MaybeUninit ;
2
3
use crate :: os:: xous:: ffi:: { Connection , lend, try_lend, try_scalar} ;
3
4
use crate :: os:: xous:: services:: { LogLend , LogScalar , log_server, try_connect} ;
4
5
@@ -14,23 +15,16 @@ impl Stdout {
14
15
15
16
impl io:: Write for Stdout {
16
17
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
17
- #[ repr( C , align( 4096 ) ) ]
18
- struct LendBuffer ( [ u8 ; 4096 ] ) ;
19
- let mut lend_buffer = LendBuffer ( [ 0u8 ; 4096 ] ) ;
20
- let connection = log_server ( ) ;
21
- for chunk in buf. chunks ( lend_buffer. 0 . len ( ) ) {
22
- for ( dest, src) in lend_buffer. 0 . iter_mut ( ) . zip ( chunk) {
23
- * dest = * src;
24
- }
25
- lend ( connection, LogLend :: StandardOutput . into ( ) , & lend_buffer. 0 , 0 , chunk. len ( ) )
26
- . unwrap ( ) ;
27
- }
28
- Ok ( buf. len ( ) )
18
+ write ( LogLend :: StandardOutput , buf)
29
19
}
30
20
31
21
fn flush ( & mut self ) -> io:: Result < ( ) > {
32
22
Ok ( ( ) )
33
23
}
24
+
25
+ fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
26
+ write_all ( LogLend :: StandardOutput , buf)
27
+ }
34
28
}
35
29
36
30
impl Stderr {
@@ -41,23 +35,51 @@ impl Stderr {
41
35
42
36
impl io:: Write for Stderr {
43
37
fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
44
- #[ repr( C , align( 4096 ) ) ]
45
- struct LendBuffer ( [ u8 ; 4096 ] ) ;
46
- let mut lend_buffer = LendBuffer ( [ 0u8 ; 4096 ] ) ;
47
- let connection = log_server ( ) ;
48
- for chunk in buf. chunks ( lend_buffer. 0 . len ( ) ) {
49
- for ( dest, src) in lend_buffer. 0 . iter_mut ( ) . zip ( chunk) {
50
- * dest = * src;
51
- }
52
- lend ( connection, LogLend :: StandardError . into ( ) , & lend_buffer. 0 , 0 , chunk. len ( ) )
53
- . unwrap ( ) ;
54
- }
55
- Ok ( buf. len ( ) )
38
+ write ( LogLend :: StandardError , buf)
56
39
}
57
40
58
41
fn flush ( & mut self ) -> io:: Result < ( ) > {
59
42
Ok ( ( ) )
60
43
}
44
+
45
+ fn write_all ( & mut self , buf : & [ u8 ] ) -> io:: Result < ( ) > {
46
+ write_all ( LogLend :: StandardError , buf)
47
+ }
48
+ }
49
+
50
+ #[ repr( C , align( 4096 ) ) ]
51
+ struct AlignedBuffer ( [ MaybeUninit < u8 > ; 4096 ] ) ;
52
+
53
+ impl AlignedBuffer {
54
+ #[ inline]
55
+ fn new ( ) -> Self {
56
+ AlignedBuffer ( [ MaybeUninit :: uninit ( ) ; 4096 ] )
57
+ }
58
+
59
+ #[ inline]
60
+ fn fill ( & mut self , buf : & [ u8 ] ) -> & [ u8 ] {
61
+ let len = buf. len ( ) . min ( self . 0 . len ( ) ) ;
62
+ self . 0 [ ..len] . write_copy_of_slice ( & buf[ ..len] ) ;
63
+ // SAFETY: This range was just initialized.
64
+ unsafe { self . 0 [ ..len] . assume_init_ref ( ) }
65
+ }
66
+ }
67
+
68
+ fn write ( opcode : LogLend , buf : & [ u8 ] ) -> io:: Result < usize > {
69
+ let mut aligned_buffer = AlignedBuffer :: new ( ) ;
70
+ let aligned = aligned_buffer. fill ( buf) ;
71
+ lend ( log_server ( ) , opcode. into ( ) , aligned, 0 , aligned. len ( ) ) . unwrap ( ) ;
72
+ Ok ( aligned. len ( ) )
73
+ }
74
+
75
+ fn write_all ( opcode : LogLend , buf : & [ u8 ] ) -> io:: Result < ( ) > {
76
+ let mut aligned_buffer = AlignedBuffer :: new ( ) ;
77
+ let connection = log_server ( ) ;
78
+ for chunk in buf. chunks ( aligned_buffer. 0 . len ( ) ) {
79
+ let aligned = aligned_buffer. fill ( chunk) ;
80
+ lend ( connection, opcode. into ( ) , aligned, 0 , aligned. len ( ) ) . unwrap ( ) ;
81
+ }
82
+ Ok ( ( ) )
61
83
}
62
84
63
85
pub const STDIN_BUF_SIZE : usize = super :: unsupported_stdio:: STDIN_BUF_SIZE ;
@@ -86,13 +108,9 @@ impl io::Write for PanicWriter {
86
108
// the data itself in the buffer. Typically several messages are require to
87
109
// fully transmit the entire panic message.
88
110
if let Some ( gfx) = self . gfx {
89
- #[ repr( C , align( 4096 ) ) ]
90
- struct Request ( [ u8 ; 4096 ] ) ;
91
- let mut request = Request ( [ 0u8 ; 4096 ] ) ;
92
- for ( & s, d) in s. iter ( ) . zip ( request. 0 . iter_mut ( ) ) {
93
- * d = s;
94
- }
95
- try_lend ( gfx, 0 /* AppendPanicText */ , & request. 0 , 0 , s. len ( ) ) . ok ( ) ;
111
+ let mut request = AlignedBuffer :: new ( ) ;
112
+ let request = request. fill ( s) ;
113
+ _ = try_lend ( gfx, 0 /* AppendPanicText */ , request, 0 , request. len ( ) ) ;
96
114
}
97
115
Ok ( s. len ( ) )
98
116
}
0 commit comments