loboris / MicroPython_ESP32_psRAM_LoBo

MicroPython for ESP32 with psRAM support
Other
831 stars 344 forks source link

_thread lock test code fail #255

Open gengshenghong opened 5 years ago

gengshenghong commented 5 years ago

The test code: https://github.com/micropython/micropython/blob/master/tests/thread/thread_gc1.py

As this branch does not support _thread.allocate_lock(), instead, it has "_thread.lock()" and "_thread.unlock", I've changed the code using these lock APIs, but the test does not pass. It hangs sometimes, it get many "True" sometimes, and it get "not Implemented error: byte code not implmented" sometimes, it seems to get random result!! Even same when remove the "gc.collect" in thread function.

Hardware: esp32 WROOM 32D Code:

# test that we can run the garbage collector within threads
#
# MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd

import gc
import _thread

def thread_entry(n):
    # allocate a bytearray and fill it
    data = bytearray(i for i in range(256))

    # do some work and call gc.collect() a few times
    for i in range(n):
        for i in range(len(data)):
            data[i] = data[i]
        #gc.collect()

    # print whether the data remains intact and indicate we are finished
    _thread.lock()
    print(list(data) == list(range(256)))
    global n_finished
    n_finished += 1
    _thread.lock()

n_thread = 4
n_finished = 0

# spawn threads
for i in range(n_thread):
    _thread.start_new_thread('test', thread_entry, (10,))

# busy wait for threads to finish
while n_finished < n_thread:
    pass
Molorius commented 5 years ago

In this section:

    # print whether the data remains intact and indicate we are finished
    _thread.lock()
    print(list(data) == list(range(256)))
    global n_finished
    n_finished += 1
    _thread.lock()

you lock the thread twice. Shouldn't you unlock it instead?

    # print whether the data remains intact and indicate we are finished
    _thread.lock()
    print(list(data) == list(range(256)))
    global n_finished
    n_finished += 1
    _thread.unlock()

That still doesn't explain why you were getting different results rather than just hanging every time, but maybe it will fix it.