Out side world is difficult to tell whethere there is dead thread
remaining. If rt_thread_idle_excute only do one cleanup, it's hard to
finish cleanups outside the idle thread. So let is loop and do all the
cleanups in one call.
Mutex has the idea of ownership, only the thread which owns the mutex
can release it. So rt_mutex_release could only be called in thread
context. Add a debug guard to it.
Skip list is a "random" data structure that in high possibilities it
would get O(log(N)) time complexity in inserting while the old list get
O(N). Forthermore, when set RT_TIMER_SKIP_LIST_LEVEL to 1, it will just
the same as the old double linked list, both in time and space
complexity.
Benchmarks shows that when RT_TIMER_SKIP_LIST_LEVEL is 3, the average
time of random insertion of new timer is about 2 times faster than the
old timer when there are 100 timers and 3 times faster when there are
200 timers.
However, it restores the deprecated funcion rt_system_timer_init. BSPs
must invoke it upon system startup.
In thread context means: 1) the scheduler has been started; 2) not in
interrupt context. It is more stronger than RT_DEBUG_NOT_IN_INTERRUPT.
With this commit, you will catch the error on situations like taking
mutex before scheduling instead of crashing on NULL pointer reference.
vsnprintf is a common string function that could be used in many places.
Using both vsnprintf in libc and vsnprintf in the RTT could make a
bigger image. Moreover, if newlib is not enabled when compiling with
GCC, referencing vsnprintf will lead to link error:
.../arm-none-eabi/lib/armv7-ar/thumb/softfp/libc.a(lib_a-sbrkr.o):
In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
Using rt_vsnprintf could avoid such problem.
When realloc a bigger space and the next node is free and big enough, we
should directly relocate the next node instead of doing alloc/memcpy.
The new method not only faster in this cases, it would avoid memory
fragment as well.
This is a simple work around to the current device stack design. A
ref_count could let different modules to open/close the same device
independently without interfere others in some degree.
But there is still some data shared between the modules, like flag,
open_flag and user_data. Moreover, it won't yield an error if A open a
device, and B read from it before open it in B. Maybe alloc a new handle
in rt_device_open will be the ultimate solution. But that is much bigger
change and we may leave it to future development.
If two timer will timeout at the same tick, the one started later will
be called later. I've tested the patch on simulator and it _seems_ OK.
Reported-by: xdzy on the forum and delin17 <delin17@qq.com>