4
4
5
5
#include "console.h"
6
6
7
- typedef struct putstr_data {
8
- char * buf ;
9
- int len ;
10
- bool called ;
11
- struct putstr_data * next ;
12
- } putstr_data_t ;
13
-
14
- static putstr_data_t * putstr_head = NULL ;
15
- static putstr_data_t * putstr_tail = NULL ;
16
-
17
- static void putstr_upcall (int _x __attribute__ ((unused )),
18
- int _y __attribute__ ((unused )),
19
- int _z __attribute__ ((unused )),
20
- void * ud __attribute__ ((unused ))) {
21
- putstr_data_t * data = putstr_head ;
22
- data -> called = true;
23
- putstr_head = data -> next ;
24
-
25
- if (putstr_head == NULL ) {
26
- putstr_tail = NULL ;
27
- } else {
28
- int ret ;
29
- ret = putnstr_async (putstr_head -> buf , putstr_head -> len , putstr_upcall , NULL );
30
- if (ret < 0 ) {
31
- // XXX There's no path to report errors currently, so just drop it
32
- putstr_upcall (0 , 0 , 0 , NULL );
33
- }
34
- }
35
- }
36
-
37
7
int putnstr (const char * str , size_t len ) {
38
8
int ret = RETURNCODE_SUCCESS ;
39
9
40
- putstr_data_t * data = (putstr_data_t * )malloc (sizeof (putstr_data_t ));
41
- if (data == NULL ) return RETURNCODE_ENOMEM ;
42
-
43
- data -> len = len ;
44
- data -> called = false;
45
- data -> buf = (char * )malloc (len * sizeof (char ));
46
- if (data -> buf == NULL ) {
47
- ret = RETURNCODE_ENOMEM ;
48
- goto putnstr_fail_buf_alloc ;
49
- }
50
- strncpy (data -> buf , str , len );
51
- data -> next = NULL ;
52
-
53
- if (putstr_tail == NULL ) {
54
- // Invariant, if tail is NULL, head is also NULL
55
- ret = putnstr_async (data -> buf , data -> len , putstr_upcall , NULL );
56
- if (ret < 0 ) goto putnstr_fail_async ;
57
- putstr_head = data ;
58
- putstr_tail = data ;
59
- } else {
60
- putstr_tail -> next = data ;
61
- putstr_tail = data ;
62
- }
63
-
64
- yield_for (& data -> called );
65
-
66
- putnstr_fail_async :
67
- free (data -> buf );
68
- putnstr_fail_buf_alloc :
69
- free (data );
70
-
71
- return ret ;
72
- }
73
-
74
- int putnstr_async (const char * str , size_t len , subscribe_upcall cb , void * userdata ) {
75
- #pragma GCC diagnostic push
76
- #pragma GCC diagnostic pop
77
-
78
10
allow_ro_return_t ro = allow_readonly (DRIVER_NUM_CONSOLE , 1 , str , len );
79
11
if (!ro .success ) {
80
12
return tock_status_to_returncode (ro .status );
81
13
}
82
14
83
- subscribe_return_t sub = subscribe (DRIVER_NUM_CONSOLE , 1 , cb , userdata );
84
- if (!sub .success ) {
85
- return tock_status_to_returncode (sub .status );
86
- }
87
-
88
15
syscall_return_t com = command (DRIVER_NUM_CONSOLE , 1 , len , 0 );
89
- return tock_command_return_novalue_to_returncode (com );
90
- }
91
-
92
- int getnstr_async (char * buf , size_t len , subscribe_upcall cb , void * userdata ) {
93
- allow_rw_return_t rw = allow_readwrite (DRIVER_NUM_CONSOLE , 1 , buf , len );
94
- if (!rw .success ) {
95
- return tock_status_to_returncode (rw .status );
96
- }
97
-
98
- subscribe_return_t sub = subscribe (DRIVER_NUM_CONSOLE , 2 , cb , userdata );
99
- if (!sub .success ) {
100
- return tock_status_to_returncode (sub .status );
16
+ ret = tock_command_return_novalue_to_returncode (com );
17
+ if (ret < 0 ) {
18
+ return ret ;
101
19
}
102
20
103
- syscall_return_t com = command (DRIVER_NUM_CONSOLE , 2 , len , 0 );
104
- return tock_command_return_novalue_to_returncode (com );
21
+ return yield_for_subscribable_upcall_returnr0_sync (DRIVER_NUM_CONSOLE , 2 );
105
22
}
106
23
107
- typedef struct getnstr_data {
108
- bool called ;
109
- int result ;
110
- } getnstr_data_t ;
111
-
112
- static getnstr_data_t getnstr_data = { true, 0 };
113
24
114
- static void getnstr_upcall (int result ,
115
- int _y __attribute__ ((unused )),
116
- int _z __attribute__ ((unused )),
117
- void * ud __attribute__ ((unused ))) {
118
- getnstr_data .result = result ;
119
- getnstr_data .called = true;
120
- }
121
-
122
- int getnstr (char * str , size_t len ) {
25
+ int getnstr (char * buf , size_t len ) {
123
26
int ret ;
124
27
125
- if (! getnstr_data . called ) {
126
- // A call is already in progress
127
- return RETURNCODE_EALREADY ;
28
+ allow_rw_return_t rw = allow_readwrite ( DRIVER_NUM_CONSOLE , 1 , buf , len );
29
+ if (! rw . success ) {
30
+ return tock_status_to_returncode ( rw . status ) ;
128
31
}
129
- getnstr_data .called = false;
130
32
131
- ret = getnstr_async (str , len , getnstr_upcall , NULL );
33
+ syscall_return_t com = command (DRIVER_NUM_CONSOLE , 2 , len , 0 );
34
+ ret = tock_command_return_novalue_to_returncode (com );
132
35
if (ret < 0 ) {
133
36
return ret ;
134
37
}
135
38
136
- yield_for (& getnstr_data .called );
137
-
138
- return getnstr_data .result ;
39
+ return yield_for_subscribable_upcall_returnr0_sync (DRIVER_NUM_CONSOLE , 2 );
139
40
}
140
41
141
42
int getch (void ) {
@@ -145,8 +46,3 @@ int getch(void) {
145
46
r = getnstr (buf , 1 );
146
47
return (r == RETURNCODE_SUCCESS ) ? buf [0 ] : RETURNCODE_FAIL ;
147
48
}
148
-
149
- int getnstr_abort (void ) {
150
- syscall_return_t com = command (DRIVER_NUM_CONSOLE , 3 , 0 , 0 );
151
- return tock_command_return_novalue_to_returncode (com );
152
- }
0 commit comments