Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ideas for adding more features/optimizing utimeq module #5

Open
pfalcon opened this issue Nov 29, 2017 · 1 comment
Open

Ideas for adding more features/optimizing utimeq module #5

pfalcon opened this issue Nov 29, 2017 · 1 comment

Comments

@pfalcon
Copy link
Owner

pfalcon commented Nov 29, 2017

First of all, currently entries lack a unique identifier, so it's not even possible for an entry, because there's no way to identify it. But actually there's a unique id stored, it's counter. So, we should switch from ordering entries by "time" to ordering them by this id, and return it on insert operation. "Time" then just becomes a payload in entry. That's not going to work, LOL.

Then, we can store pointers to entries in the heap, not the entries themselves. This will allow us to have stable addresses for entries, so we can refer to them. Of course, that takes extra memory word. We could try to compensate that by removing existing entry member. A candidate is "args" field. It's not needed for coros, only for callbacks. But we can say "callbacks with params should create a closure and store that instead".

But the reason of this ticket is trying to optimize timeout handling in uasyncio, and timeouts are handled by callbacks taking a coro as an argument. So, we would need to optimize that too. As it doesn't make to store integers as objects in utimeq, we can say that an object with low bit set is an "implicit" timeout object for coro which is stored in the object field. So, event loop handles such specially and cancels the coro on processing such an entry.

We now just need to allow a coro to cancel such implicit timeout object in its turn. For this we use "stable address" feature introduced previously. So, when timeout object is allocated, we get its stable handle, and can store that in the wait_for wrapper coro, and then call special utimeq function to "cancel" it (e.g. nullize object field).

The last optimization would be to get rid of wait_for wrapper coro, and instead store timeout object handle in the coro itself. That's of course not easy, "normal" way would be to introduce timed await on the language syntax level and make compiler spawn coro objects with extra field. Or go for compromise and recognize await wait_for(...) as a special syntax form with the expected imitations. Or can just stuff extra field into any coro %).

@pfalcon
Copy link
Owner Author

pfalcon commented Nov 29, 2017

And if we really care about removing (timeout) entries from the queue (instead of marking them as removed), then could use beap data structure, but that has O(N^1/2) insertion complexity (but such a search complexity too, except there's nothing to search for, per the strike-thru above).

pfalcon pushed a commit that referenced this issue Dec 2, 2021
asan considers that memcmp(p, q, N) is permitted to access N bytes at each
of p and q, even for values of p and q that have a difference earlier.
Accessing additional values is frequently done in practice, reading 4 or
more bytes from each input at a time for efficiency, so when completing
"non_exist<TAB>" in the repl, this causes a diagnostic:

    ==16938==ERROR: AddressSanitizer: global-buffer-overflow on
    address 0x555555cd8dc8 at pc 0x7ffff726457b bp 0x7fffffffda20 sp 0x7fff
    READ of size 9 at 0x555555cd8dc8 thread T0
        #0 0x7ffff726457a  (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xb857a)
        #1 0x555555b0e82a in mp_repl_autocomplete ../../py/repl.c:301
        #2 0x555555c89585 in readline_process_char ../../lib/mp-readline/re
        #3 0x555555c8ac6e in readline ../../lib/mp-readline/readline.c:513
        #4 0x555555b8dcbd in do_repl /home/jepler/src/micropython/ports/uni
        #5 0x555555b90859 in main_ /home/jepler/src/micropython/ports/unix/
        #6 0x555555b90a3a in main /home/jepler/src/micropython/ports/unix/m
        #7 0x7ffff619a09a in __libc_start_main ../csu/libc-start.c:308
        #8 0x55555595fd69 in _start (/home/jepler/src/micropython/ports/uni

    0x555555cd8dc8 is located 0 bytes to the right of global variable
    'import_str' defined in '../../py/repl.c:285:23' (0x555555cd8dc0) of
    size 8
      'import_str' is ascii string 'import '

Signed-off-by: Jeff Epler <jepler@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant