Skip to content

Commit 0359064

Browse files
committed
extmod/uos_dupterm: Use native C stream methods on dupterm object.
This patch changes dupterm to call the native C stream methods on the connected stream objects, instead of calling the Python readinto/write methods. This is much more efficient for native stream objects like UART and webrepl and doesn't require allocating a special dupterm array. This change is a minor breaking change from the user's perspective because dupterm no longer accepts pure user stream objects to duplicate on. But with the recent addition of uio.IOBase it is possible to still create such classes just by inheriting from uio.IOBase, for example: import uio, uos class MyStream(uio.IOBase): def write(self, buf): # existing write implementation def readinto(self, buf): # existing readinto implementation uos.dupterm(MyStream())
1 parent 5042d98 commit 0359064

3 files changed

Lines changed: 16 additions & 28 deletions

File tree

extmod/uos_dupterm.c

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,29 @@ int mp_uos_dupterm_rx_chr(void) {
6060

6161
nlr_buf_t nlr;
6262
if (nlr_push(&nlr) == 0) {
63-
mp_obj_t readinto_m[3];
64-
mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_readinto, readinto_m);
65-
readinto_m[2] = MP_STATE_VM(dupterm_arr_obj);
66-
mp_obj_t res = mp_call_method_n_kw(1, 0, readinto_m);
67-
if (res == mp_const_none) {
68-
nlr_pop();
69-
} else if (res == MP_OBJ_NEW_SMALL_INT(0)) {
63+
byte buf[1];
64+
int errcode;
65+
const mp_stream_p_t *stream_p = mp_get_stream_raise(MP_STATE_VM(dupterm_objs[idx]), MP_STREAM_OP_READ);
66+
mp_uint_t out_sz = stream_p->read(MP_STATE_VM(dupterm_objs[idx]), buf, 1, &errcode);
67+
if (out_sz == 0) {
7068
nlr_pop();
7169
mp_uos_deactivate(idx, "dupterm: EOF received, deactivating\n", MP_OBJ_NULL);
70+
} else if (out_sz == MP_STREAM_ERROR) {
71+
// errcode is valid
72+
if (mp_is_nonblocking_error(errcode)) {
73+
nlr_pop();
74+
} else {
75+
mp_raise_OSError(errcode);
76+
}
7277
} else {
73-
mp_buffer_info_t bufinfo;
74-
mp_get_buffer_raise(MP_STATE_VM(dupterm_arr_obj), &bufinfo, MP_BUFFER_READ);
78+
// read 1 byte
7579
nlr_pop();
76-
if (*(byte*)bufinfo.buf == mp_interrupt_char) {
80+
if (buf[0] == mp_interrupt_char) {
7781
// Signal keyboard interrupt to be raised as soon as the VM resumes
7882
mp_keyboard_interrupt();
7983
return -2;
8084
}
81-
return *(byte*)bufinfo.buf;
85+
return buf[0];
8286
}
8387
} else {
8488
mp_uos_deactivate(idx, "dupterm: Exception in read() method, deactivating: ", nlr.ret_val);
@@ -96,18 +100,7 @@ void mp_uos_dupterm_tx_strn(const char *str, size_t len) {
96100
}
97101
nlr_buf_t nlr;
98102
if (nlr_push(&nlr) == 0) {
99-
mp_obj_t write_m[3];
100-
mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_write, write_m);
101-
102-
mp_obj_array_t *arr = MP_OBJ_TO_PTR(MP_STATE_VM(dupterm_arr_obj));
103-
void *org_items = arr->items;
104-
arr->items = (void*)str;
105-
arr->len = len;
106-
write_m[2] = MP_STATE_VM(dupterm_arr_obj);
107-
mp_call_method_n_kw(1, 0, write_m);
108-
arr = MP_OBJ_TO_PTR(MP_STATE_VM(dupterm_arr_obj));
109-
arr->items = org_items;
110-
arr->len = 1;
103+
mp_stream_write(MP_STATE_VM(dupterm_objs[idx]), str, len, MP_STREAM_RW_WRITE);
111104
nlr_pop();
112105
} else {
113106
mp_uos_deactivate(idx, "dupterm: Exception in write() method, deactivating: ", nlr.ret_val);
@@ -133,9 +126,6 @@ STATIC mp_obj_t mp_uos_dupterm(size_t n_args, const mp_obj_t *args) {
133126
MP_STATE_VM(dupterm_objs[idx]) = MP_OBJ_NULL;
134127
} else {
135128
MP_STATE_VM(dupterm_objs[idx]) = args[0];
136-
if (MP_STATE_VM(dupterm_arr_obj) == MP_OBJ_NULL) {
137-
MP_STATE_VM(dupterm_arr_obj) = mp_obj_new_bytearray(1, "");
138-
}
139129
}
140130

141131
return previous_obj;

py/mpstate.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ typedef struct _mp_state_vm_t {
171171

172172
#if MICROPY_PY_OS_DUPTERM
173173
mp_obj_t dupterm_objs[MICROPY_PY_OS_DUPTERM];
174-
mp_obj_t dupterm_arr_obj;
175174
#endif
176175

177176
#if MICROPY_PY_LWIP_SLIP

py/runtime.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ void mp_init(void) {
108108
for (size_t i = 0; i < MICROPY_PY_OS_DUPTERM; ++i) {
109109
MP_STATE_VM(dupterm_objs[i]) = MP_OBJ_NULL;
110110
}
111-
MP_STATE_VM(dupterm_arr_obj) = MP_OBJ_NULL;
112111
#endif
113112

114113
#if MICROPY_FSUSERMOUNT

0 commit comments

Comments
 (0)