Commit Graph

40 Commits

Author SHA1 Message Date
Damien George
b6b39bff47 py/gc: Make gc_lock_depth have a count per thread.
This commit makes gc_lock_depth have one counter per thread, instead of one
global counter.  This makes threads properly independent with respect to
the GC, in particular threads can now independently lock the GC for
themselves without locking it for other threads.  It also means a given
thread can run a hard IRQ without temporarily locking the GC for all other
threads and potentially making them have MemoryError exceptions at random
locations (this really only occurs on MCUs with multiple cores and no GIL,
eg on the rp2 port).

The commit also removes protection of the GC lock/unlock functions, which
is no longer needed when the counter is per thread (and this also fixes the
cas where a hard IRQ calling gc_lock() may stall waiting for the mutex).

It also puts the check for `gc_lock_depth > 0` outside the GC mutex in
gc_alloc, gc_realloc and gc_free, to potentially prevent a hard IRQ from
waiting on a mutex if it does attempt to allocate heap memory (and putting
the check outside the GC mutex is now safe now that there is a
gc_lock_depth per thread).

Signed-off-by: Damien George <damien@micropython.org>
2021-05-10 13:07:16 +10:00
stijn
fca2730ea0 lib/utils/pyexec: Remove obsolete LCD initialization.
This was added a long time ago in 75abee206d
when USB host support was added to the stm (now stm32) port, and when this
pyexec code was actually part of the stm port.  It's unlikely to work as
intended anymore.  If it is needed in the future then generic hook macros
can be added in pyexec.
2021-01-30 13:41:36 +11:00
Damien George
bb24c69b90 lib/utils/pyexec: Add stdin-reader on raw REPL with flow control.
Background: the friendly/normal REPL is intended for human use whereas the
raw REPL is for computer use/automation.  Raw REPL is used for things like
pyboard.py script_to_run.py.  The normal REPL has built-in flow control
because it echos back the characters.  That's not so with raw REPL and flow
control is just implemented by rate limiting the amount of data that goes
in.  Currently it's fixed at 256 byte chunks every 10ms.  This is sometimes
too fast for slow MCUs or systems with small stdin buffers.  It's also too
slow for a lot of higher-end MCUs, ie it could be a lot faster.

This commit adds a new raw REPL mode which includes flow control: the
device will echo back a character after a certain number of bytes are sent
to the host, and the host can use this to regulate the data going out to
the device.  The amount of characters is controlled by the device and sent
to the host before communication starts.  This flow control allows getting
the maximum speed out of a serial link, regardless of the link or the
device at the other end.

Also, this new raw REPL mode parses and compiles the incoming data as it
comes in.  It does this by creating a "stdin reader" object which is then
passed to the lexer.  The lexer requests bytes from this "stdin reader"
which retrieves bytes from the host, and does flow control.  What this
means is that no memory is used to store the script (in the existing raw
REPL mode the device needs a big buffer to read in the script before it can
pass it on to the lexer/parser/compiler).  The only memory needed on the
device is enough to parse and compile.

Finally, it would be possible to extend this new raw REPL to allow bytecode
(.mpy files) to be sent as well as text mode scripts (but that's not done
in this commit).

Some results follow. The test was to send a large 33k script that contains
mostly comments and then prints out the heap, run via pyboard.py large.py.

On PYBD-SF6, prior to this PR:

$ ./pyboard.py large.py
stack: 524 out of 23552
GC: total: 392192, used: 34464, free: 357728
 No. of 1-blocks: 12, 2-blocks: 2, max blk sz: 2075, max free sz: 22345
GC memory layout; from 2001a3f0:
00000: h=hhhh=======================================hhBShShh==h=======h
00400: =====hh=B........h==h===========================================
00800: ================================================================
00c00: ================================================================
01000: ================================================================
01400: ================================================================
01800: ================================================================
01c00: ================================================================
02000: ================================================================
02400: ================================================================
02800: ================================================================
02c00: ================================================================
03000: ================================================================
03400: ================================================================
03800: ================================================================
03c00: ================================================================
04000: ================================================================
04400: ================================================================
04800: ================================================================
04c00: ================================================================
05000: ================================================================
05400: ================================================================
05800: ================================================================
05c00: ================================================================
06000: ================================================================
06400: ================================================================
06800: ================================================================
06c00: ================================================================
07000: ================================================================
07400: ================================================================
07800: ================================================================
07c00: ================================================================
08000: ================================================================
08400: ===============================================.....h==.........
       (349 lines all free)

(the big blob of used memory is the large script).

Same but with this PR:

$ ./pyboard.py large.py
stack: 524 out of 23552
GC: total: 392192, used: 1296, free: 390896
 No. of 1-blocks: 12, 2-blocks: 3, max blk sz: 40, max free sz: 24420
GC memory layout; from 2001a3f0:
00000: h=hhhh=======================================hhBShShh==h=======h
00400: =====hh=h=B......h==.....h==....................................
       (381 lines all free)

The only thing in RAM is the compiled script (and some other unrelated
items).

Time to download before this PR: 1438ms, data rate: 230,799 bits/sec.

Time to download with this PR: 119ms, data rate: 2,788,991 bits/sec.

So it's more than 10 times faster, and uses significantly less RAM.

Results are similar on other boards. On an stm32 board that connects via
UART only at 115200 baud, the data rate goes from 80kbit/sec to
113kbit/sec, so gets close to saturating the UART link without loss of
data.

The new raw REPL mode also supports a single ctrl-C to break out of this
flow-control mode, so that a ctrl-C can always get back to a known state.
It's also backwards compatible with the original raw REPL mode, which is
still supported with the same sequence of commands.  The new raw REPL
mode is activated by ctrl-E, which gives an error on devices that do not
support the new mode.

Signed-off-by: Damien George <damien@micropython.org>
2020-11-30 11:37:44 +11:00
Damien George
7789cd5f16 lib/utils/pyexec: Add MICROPY_BOARD hooks before/after executing code.
Signed-off-by: Damien George <damien@micropython.org>
2020-11-11 21:47:13 +11:00
Damien George
b2030e1661 lib/utils/pyexec: Add missing MP_ERROR_TEXT when compiler disabled. 2020-06-02 15:43:44 +10:00
stijn
84fa3312cf all: Format code to add space after C++-style comment start.
Note: the uncrustify configuration is explicitly set to 'add' instead of
'force' in order not to alter the comments which use extra spaces after //
as a means of indenting text for clarity.
2020-04-23 11:24:25 +10:00
Damien George
69661f3343 all: Reformat C and Python source code with tools/codeformat.py.
This is run with uncrustify 0.70.1, and black 19.10b0.
2020-02-28 10:33:03 +11:00
Damien George
5a91cd9ff3 lib/utils/pyexec: Handle pending exceptions after disabling kbd intrs.
Pending exceptions would otherwise be handled later on where there may not
be an NLR handler in place.

A similar fix is also made to the unix port's REPL handler.

Fixes issues #4921 and #5488.
2020-02-07 16:08:26 +11:00
Yonatan Goldschmidt
61d2b40ad5 lib/utils/pyexec: Introduce MICROPY_REPL_INFO, wrap debug prints in it.
For the 3 ports that already make use of this feature (stm32, nrf and
teensy) this doesn't make any difference, it just allows to disable it from
now on.

For other ports that use pyexec, this decreases code size because the debug
printing code is dead (it can't be enabled) but the compiler can't deduce
that, so code is still emitted.
2019-12-28 00:05:39 +11:00
Damien George
af20c2ead3 py: Add global default_emit_opt variable to make emit kind persistent.
mp_compile no longer takes an emit_opt argument, rather this setting is now
provided by the global default_emit_opt variable.

Now, when -X emit=native is passed as a command-line option, the emitter
will be set for all compiled modules (included imports), not just the
top-level script.

In the future there could be a way to also set this variable from a script.

Fixes issue #4267.
2019-08-28 12:47:58 +10:00
Andrew Leech
859596ce25 lib/utils: Make pyexec_file_if_exists run frozen scripts if they exist.
So that boot.py and/or main.py can be frozen (either as STR or MPY) in the
same way that other scripts are frozen.  Frozen scripts have preference to
scripts in the VFS.
2019-05-01 11:27:51 +10:00
Damien George
06a532c227 lib/utils/pyexec: Add pyexec_file_if_exists() helper function.
It will only execute the script if it can be stat'd and is a file.
2019-04-26 15:21:09 +10:00
Mike Causer
812969d615 all: Change PYB message prefix to MPY.
Replaces "PYB: soft reboot" with "MPY: soft reboot", etc.

Having a consistent prefix across ports reduces the difference between
ports, which is a general goal.  And this change won't break pyboard.py
because that tool only looks for "soft reboot".
2019-02-12 15:18:33 +11:00
Damien George
1fa8f977f5 lib/utils/pyexec: Implement paste mode with event driven REPL. 2019-01-28 23:00:19 +11:00
Damien George
f5d46a88aa lib/utils/pyexec: Forcefully unlock the heap if locked and REPL active.
Otherwise there is really nothing that can be done, it can't be unlocked by
the user because there is no way to allocate memory to execute the unlock.

See issue #4205 and #4209.
2018-10-13 16:21:08 +11:00
Damien George
b2b06450e3 lib/utils: Fix to support compiling with object representation D. 2018-07-08 23:13:37 +10:00
Damien George
d9b9fbc41a lib/utils/pyexec: Update to work with new MICROPY_HW_ENABLE_USB option. 2018-02-13 18:56:12 +11:00
Damien George
a3dc1b1957 all: Remove inclusion of internal py header files.
Header files that are considered internal to the py core and should not
normally be included directly are:
    py/nlr.h - internal nlr configuration and declarations
    py/bc0.h - contains bytecode macro definitions
    py/runtime0.h - contains basic runtime enums

Instead, the top-level header files to include are one of:
    py/obj.h - includes runtime0.h and defines everything to use the
        mp_obj_t type
    py/runtime.h - includes mpstate.h and hence nlr.h, obj.h, runtime0.h,
        and defines everything to use the general runtime support functions

Additional, specific headers (eg py/objlist.h) can be included if needed.
2017-10-04 12:37:50 +11:00
Alexander Steffen
55f33240f3 all: Use the name MicroPython consistently in comments
There were several different spellings of MicroPython present in comments,
when there should be only one.
2017-07-31 18:35:40 +10:00
Tom Collins
288ea06e7c lib/utils/pyexec: Update event-driven REPL to match non-event REPL.
Don't print dupe ">>> " prompt when starting event-driven REPL.  Clear
incomplete line in transition from raw to friendly REPL.
2017-05-05 22:15:47 +10:00
Damien George
3f7aa330fd lib/utils/pyexec: Fix bug with pyexec_file not setting flag for source. 2017-03-14 21:53:46 +11:00
Damien George
56b238393b lib/utils/pyexec: Refactor to put lexer constructors all in one place.
The lexer can now raise an exception on construction so it must go within
an nlr handler block.
2017-03-14 11:52:05 +11:00
Damien George
3b2fd4df31 lib/utils/pyexec: Allow to compile when the uPy compiler is disabled. 2017-02-27 15:02:32 +11:00
Damien George
211244d1f3 lib/utils/pyexec: Only print help prompt if HELP feature is enabled. 2017-01-22 12:33:19 +11:00
Paul Sokolovsky
3cdccb9b14 zephyr: Fix mp_hal_set_interrupt_char() declaration to be compatible.
With other ports. Other ports declare it in mphalport.h, it can be
inline or macro.
2016-10-26 17:53:28 +03:00
Paul Sokolovsky
6832cbd69d lib/utils/pyexec: Fix compilation warning of type vs format mismatch.
This happens with some compilers on some architectures, which don't define
size_t as unsigned int. MicroPython's printf() dooesn't support obscure
format specifiers for size_t, so the obvious choice is to explicitly cast
to unsigned, to match %u used in printf().
2016-10-26 13:45:03 +03:00
Vincenzo Frascino
c38ea32810 lib/utils/pyexec: Add mp_hal_set_interrupt_char() prototype.
This patch removes a compilation warning in pyexec.

Signed-off-by: Vincenzo Frascino <vincenzo.frascino@linaro.org>
2016-10-26 13:42:27 +03:00
Damien George
ad3724e0bc lib/utils/pyexec: Allow behaviour of SystemExit to be configurable.
Setting the pyexec_system_exit variable to PYEXEC_FORCED_EXT allows
SystemExit exceptions to terminate the pyexec functions.
2016-10-17 13:14:59 +11:00
Damien George
824f5c5a32 py/vstr: Combine vstr_new_size with vstr_new since they are rarely used.
Now there is just one function to allocate a new vstr, namely vstr_new
(in addition to vstr_init etc).  The caller of this function should know
what initial size to allocate for the buffer, or at least have some policy
or config option, instead of leaving it to a default (as it was before).
2016-10-14 16:46:34 +11:00
Paul Sokolovsky
4021b1e1b8 lib/utils/pyexec: Don't treat SystemExit as "forced exit".
"Forced exit" is treated as soft-reboot (Ctrl+D). But expected effect of
calling sys.exit() is termination of the current script, not any further
and more serious actions like mentioned soft reboot.
2016-10-12 18:00:32 +03:00
Paul Sokolovsky
bae62d9abe lib/utils/pyexec: qstr_pool_info() requires size_t* parameters. 2016-08-30 00:58:42 +03:00
Paul Sokolovsky
04c27e5eaa lib/utils/pyexec: Use full path to readline.h header, per latest conventions. 2016-07-21 00:14:10 +03:00
Colin Hogben
8aa3cbf153 lib/utils/pyexec: Condition-out GC calls from pyexec.
A port which uses lib/utils/pyexec.c but which does not enable garbage
collection should not need to implement the gc_collect function.

This patch also moves the gc_collect call to after printing the qstr
info.  Since qstrs cannot be collected it should not make any difference
to the printed statistics.
2016-04-19 09:22:40 +01:00
Damien George
0a2e9650f5 py: Add ability to have frozen persistent bytecode from .mpy files.
The config variable MICROPY_MODULE_FROZEN is now made of two separate
parts: MICROPY_MODULE_FROZEN_STR and MICROPY_MODULE_FROZEN_MPY.  This
allows to have none, either or both of frozen strings and frozen mpy
files (aka frozen bytecode).
2016-04-13 16:07:47 +01:00
Paul Sokolovsky
777232c9a5 esp8266: Disallow recursive calls to REPL.
Before this change, if REPL blocked executing some code, it was possible
to still input new statememts and excuting them, all leading to weird,
and portentially dangerous interaction.

TODO: Current implementation may have issues processing input accumulated
while REPL was blocked.
2016-04-01 12:53:50 +03:00
Paul Sokolovsky
2e75a17bab esp8266: Fix issue when current repl line was garbage-collected.
Reference it from root pointers section.
2016-03-30 18:13:03 +03:00
Damien George
84b245f187 lib/utils: Add pyexec_frozen_module to load and execute frozen module.
This is a convenience function similar to pyexec_file.  It should be used
instead of raw mp_parse_compile_execute because the latter does not catch
and report exceptions.
2015-12-26 12:32:33 +00:00
Damien George
40274fec9c lib/pyexec: Move header pyexec.h from stmhal directory. 2015-11-09 13:13:09 +00:00
Damien George
dde0c204e7 lib/pyexec: For paste mode use "Ctrl" as the name of the key, not "CTRL". 2015-11-03 00:33:56 +00:00
Paul Sokolovsky
0ec51441de stmhal: pyexec.c is common module, move to lib/utils/ . 2015-10-31 19:35:10 +03:00