The return value of function mm_takesemaphore will never below
than zero, DEBUGVERIFY make no effect to check it, use DEBUGASSERT
instead.
Signed-off-by: xiangdong6 <xiangdong6@xiaomi.com>
Summary:
- In the case of CONFIG_BUILD_KERNEL=y, showing Kmem and Page
info is enough for free command
Impact:
- CONFIG_BUILD_KERNEL=y only
Testing:
- Tested with sabre-6quad:netknsh
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
It is ok to call kmm_free with a NULL pointer. Thus adopt the
DEBUGASSERT statement to cover this case.
Signed-off-by: Michael Jung <michael.jung@secore.ly>
so the user could disable the full image instrumentation,
but enable the instrumentation by files or directories.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
without UBSan
```
text data bss dec hex filename
85612 208 142258 228078 37aee nuttx
```
with UBSan:
```
text data bss dec hex filename
194290 98164 208634 501088 7a560 nuttx
```
```c
int main(int argc, FAR char *argv[])
{
uint32_t ptr[32];
printf("Hello, World!! %lu\n", ptr[64]);
return 0;
}
```
Try to run this sample:
```
nsh> hello
ubsan_prologue: ================================================================================
ubsan_prologue: UBSAN: array-index-out-of-bounds in hello_main.c:39:37
__ubsan_handle_out_of_bounds: index 64 is out of range for type 'uint32_t [32]'
ubsan_epilogue: ================================================================================
Hello, World!! 1070182368
nsh>
```
Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
since it is impossible to track producer and consumer
correctly if TCP/IP stack pass IOB directly to netdev
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
The free node is still in use after kasan_poison(), the node member
access will cause the assert report by kasan.
| (gdb) bt
| #0 kasan_report (addr=1743265406637584896, size=140737337053680, is_write=46) at kasan/kasan.c:97
| #1 0x0000555555607bdd in __asan_loadN_noabort (addr=140737272831420, size=4) at kasan/kasan.c:289
| #2 0x0000555555607cd7 in __asan_load4_noabort (addr=140737272831420) at kasan/kasan.c:323
| #3 0x00005555556061ef in gmtime_r (timep=0x7ffff3275dbc, result=0x7ffff3275e10) at time/lib_gmtimer.c:301
| #4 0x000055555560e507 in sim_rtc_rdtime (lower=0x55555576b780 <g_sim_rtc>, rtctime=0x7ffff3275e10) at sim/up_rtc.c:77
| #5 0x00005555555fcbdb in up_rtc_gettime (tp=0x7ffff3275ef0) at timers/arch_rtc.c:128
| #6 0x00005555555f08b4 in clock_systime_timespec (ts=0x7ffff3275ef0) at clock/clock_systime_timespec.c:72
| #7 0x00005555555ecc77 in note_common (tcb=0x7ffff31d2180, note=0x7ffff3275f80, length=21 '\025', type=18 '\022') at sched/sched_note.c:144
| #8 0x00005555555ed706 in sched_note_syscall_enter (nr=1, argc=0) at sched/sched_note.c:765
| #9 0x000055555560eb37 in __wrap_getpid () at wraps/WRAP_getpid.c:26
| #10 0x0000555555608d1c in mm_takesemaphore (heap=0x7ffff30ae000) at mm_heap/mm_sem.c:127
| #11 0x0000555555609477 in mm_free (heap=0x7ffff30ae000, mem=0x7ffff3265b80) at mm_heap/mm_free.c:89
| #12 0x00005555556070c5 in free (mem=0x7ffff3265b80) at umm_heap/umm_free.c:49
| #13 0x000055555560c3b0 in up_release_stack (dtcb=0x7ffff31e4b00, ttype=0 '\000') at sim/up_releasestack.c:67
| #14 0x00005555555f2515 in nxsched_release_tcb (tcb=0x7ffff31e4b00, ttype=0 '\000') at sched/sched_releasetcb.c:134
| #15 0x00005555556bdf0c in nxtask_terminate (pid=4, nonblocking=true) at task/task_terminate.c:184
| #16 0x00005555556bdb0f in nxtask_exit () at task/task_exit.c:168
| #17 0x000055555566e05f in up_exit (status=0) at sim/up_exit.c:64
| #18 0x000055555564f454 in _exit (status=0) at task/exit.c:78
| #19 0x000055555560ea89 in __wrap__exit (parm1=0) at wraps/WRAP__exit.c:27
| #20 0x00005555555eb288 in exit (status=0) at stdlib/lib_exit.c:54
| #21 0x00005555555fe2cc in nxtask_startup (entrypt=0x555555670c34 <critmon_start_main>, argc=1, argv=0x7ffff3265bb0) at sched/task_startup.c:70
| #22 0x00005555555f02a0 in nxtask_start () at task/task_start.c:134
| #23 0x0000000000000000 in ?? ()
Signed-off-by: chao.an <anchao@xiaomi.com>
Targets build during the kernel phase did not have their dependencies
specified and thus they were not rebuilt after their dependencies have
changed, for example by changing options in menuconfig.
Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
When allocation failed, it isn't too uncommon for the caller
to fall back to other allocation method.
(eg. esp32 textheap code tries iram heap when an allocation from rtc heap
failed.)
DEBUGASSERT(false) is too much in that case.
This commit removes the DEBUGASSERT, and also makes the heap dump
a separate option.
malloc() should return aligned (with MM_MIN_CHUNK) pointer, but
pr #5906 destroy that, this pr find a better method to solve
these questions.
Signed-off-by: YAMAMOTO Takashi <yamamoto@midokura.com>
and
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
usage:
echo <pid/used/free> trace > /proc/memdump
echo used > /proc/memdump //output all used memory info with backtrace
echo free > /proc/memdump //output all free memory info
echo 22 > /proc/memdump //output used memory info for task pid is 22 with backtrace
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This is a fix of:
0169a51220
This is caused by wrong memory sem operation in IDLE.
Fix:
Obey the original design, don't check the IDLE in mm_takesemaphore()
Signed-off-by: ligd <liguiding1@xiaomi.com>
Summary:
- I noticed that the user heap is corrupted
- This commit fixes this issue by reverting the change to
the NuttX-9.0.0
Impact:
- None
Testing:
- sabre6-quad:netknsh (not merged yet)
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
Co-authored-by: Oki Minabe <minabe.oki@gmail.com>
For CEVA platform CHAR_BIT is 16, and will do lots of extra work
when use IPC.
We will not support this platform anymore, so remove all the b2c operations.
Signed-off-by: ligd <liguiding1@xiaomi.com>
The operations of struct iob_queue_s in qh_head & qh_tail are performed with interrupts disabled.
change iflags to flags
add header file ref
update for check
If threads are blocking for throttled allocation,
g_throttle_sem.semcount doesn't represent the number of
usable IOBs well.
Note: For non-throttled allocations, the g_iob_committed mechanism
is a rescue. But there is no equivalent for throttled allocations.
since it's useful to redirect these functions to others
sometime(e.g. validate the memory before write).
Change-Id: I6253a9231af8809e8362f4bc5a1bd67fb094c3b0
1.Move all special process to mm_takesemaphore
2.Remove the support of recurive lock
3.Remove mm_trysemaphore function
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: Ie216a6294ab67c5d427f31b089beb15c532f08fe
it's more simple to make mm_heap_s opaque outside of mm
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: I5c8e435f6baba6d22b10c5f7e8d9191104fb5af2
and remove mm_sbrk and kmm_sbrk since it's wrong to expose
sbrk to other heaps except the default userspace heap.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Root casue:
when do thread exit, need add free stack operation to mm_delaylist,
but in SMP mode, CPU0 thread1 exit, at this time, CPU1 call malloc
and free mm_delaylist.
Fix:
Divide mm_delaylist for per CPU in SMP mode.
Change-Id: Ibf7d04614ea2f99fb5b506356b7346a0d94f0590
Signed-off-by: ligd <liguiding1@xiaomi.com>
since the similar functions(e.g. strdup/strndup) put into libs/libc/string
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: Ifb2c0c51298b09014748e5ee8275db51213d6911
Gregory Nutt is the copyright holder for those files and he has submitted the
SGA as a result we can migrate the licenses to Apache.
Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
Broken by 635cfa.
On an stm32 the heap is formed from
const uintptr_t g_idle_topstack = HEAP_BASE;
where HEAP_BASE is &_bss + CONFIG_IDLE_STACKSIZE.
Both these values are not deterministic. One
comes from the compiler, the other the system
configurator.
a 3 byte bss and 250 byte stack would lead to
and unaligned address used as the heap to be.
The compiler used clever `strd r1,r3,[r5,#8]` to
store 2 values in one memory cycle into the
heap_impl struct. Resulting in a hardfault.
Change the amount of bss or the CONFIG_IDLE_STACKSIZE
could lead to a non-functional NuttX system.
Summary:
- This commit removes critical section in mm_sem.c which was
added to stabilize the NuttX SMP kernel in Mar 2018.
Impact:
- SMP only
Testing:
- Tested with ostest with the following configs
- maix-bit:smp (QEMU), esp32-devkitc:smp (QEMU)
- sabre-6quad:smp (QEMU), spresense:smp, sim:smp
- Tested with nxplayer with the following configs
- spresense:wifi_smp, spresense:rndis_smp
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
since other subsystem doesn't need call these function anymore
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: Idfb217c412db62d9f17f427310b75bb78785dc50
Make.dep file should be updated by .config changed after first make.
There are 2 cases affected for this problem:
1) Add source files by config symbol
2) Include header files in #ifdef directive
These 2 cases may not be included in Make.dep and this may prevent the
differential build from working correctly.
When realloc up from a mem area to a larger one where a new node
is needed. The the larger memory region is copied from the source
this can both leak data as well as cause memory faults accesssing
invalid data.
This was first reported by Kwonsk
Signed-off-by: Brennan Ashton <bashton@brennanashton.com>
All complaints fixed except for those that were not possible to fix:
- Used of Mixed case identifier in ESP32 files. These are references to Expressif ROM functions which are outside of the scope of NuttX.
This commit resolves issue #620:
Remove CONFIG_CAN_PASS_STRUCTS #620
The configuration option CONFIG_CAN_PASS_STRUCTS was added many years ago to support an old version of the SDCC compiler. That compiler is currently used only with the Z80 and Z180 targets. The limitation of that old compiler was that it could not pass structures or unions as either inputs or outputs. For example:
#ifdef CONFIG_CAN_PASS_STRUCTS
struct mallinfo mallinfo(void);
#else
int mallinfo(FAR struct mallinfo *info);
#endif
And even leads to violation of a few POSIX interfaces like:
#ifdef CONFIG_CAN_PASS_STRUCTS
int sigqueue(int pid, int signo, union sigval value);
#else
int sigqueue(int pid, int signo, FAR void *sival_ptr);
#endif
This breaks the 1st INVIOLABLES rule:
Strict POSIX compliance
-----------------------
o Strict conformance to the portable standard OS interface as defined at
OpenGroup.org.
o A deeply embedded system requires some special support. Special
support must be minimized.
o The portable interface must never be compromised only for the sake of
expediency.
o Expediency or even improved performance are not justifications for
violation of the strict POSIX interface
Also, it appears that the current SDCC compilers have resolve this issue and so, perhaps, this is no longer a problem: z88dk/z88dk#1132
NOTE: This commit cannot pass the PR checks because it depends on matching changes to the apps/ directory.
So call 'make EXTRAFLAGS=-Wno-cpp' could suppress the warnings with pre-processor
directive #warning in GCC.
Change-Id: Iaa618238924c9969bf91db22117b39e6d2fc9bb6
Signed-off-by: liuhaitao <liuhaitao@xiaomi.com>
Resolution of Issue 619 will require multiple steps, this part of the first step in that resolution: Every call to nxsem_wait_uninterruptible() must handle the return value from nxsem_wait_uninterruptible properly. This commit is only for those files under fs/tmpfs and fs/spiffs. Still do do: The rest of fs/ and all of drivers/ and arch/.
Resolution of Issue 619 will require multiple steps, this part of the first step in that resolution: Every call to nxsem_wait_uninterruptible() must handle the return value from nxsem_wait_uninterruptible properly. This commit is only for those files under graphics/, mm/, net/, sched/, wireless/bluetooth.
Still to do: Files under fs/, drivers/, and arch. The last is 116 files and will take some effort.
This reverts commit b9ace36fcc.
This change was added by PR 625 but has a serious logic flaw. It removes all occurrences of INCDIROPT and replaces it with a definition in tools/Config.mk:
else ifeq ($(WINTOOL),y)
DEFINE = "$(TOPDIR)/tools/define.sh"
INCDIR = "$(TOPDIR)/tools/incdir.sh" -w
This logic flaw is the Config.mk is included in all Make.defs files BEFORE WINTOOL is defined. As a result, the definition is wrong in many places when building under Cygwin with a Windows native toolchain.
Eliminate the MOVEOBJ definition from tools/Config.mk, Makefiles, and other locations. The MOVEOBJ definition was used to work around the case where the object output of a compile or assemble is in a different directory than the source file. The ZDS-II tools have no command line option to perform this move; MOVEOBJ handled the move as a post-compiler operation.
MOVEOBJ is no longer needed because this the ez80 COMPILE and ASSEMBLE definitions now handle all of the object file movement cases.
It seems that "ld -r" on macOS doesn't include objects from
libraries for common symbols. Because of that, sim build
ends up with undefined references to globals like g_binfmts
and g_mmheap.
@(#)PROGRAM:ld PROJECT:ld64-530
BUILD 18:57:17 Dec 13 2019
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 11.0.0, (clang-1100.0.33.17) (static support for 23, runtime is 23)
TAPI support using: Apple TAPI version 11.0.0 (tapi-1100.0.11)
mm/Makefile: Same change should be applied to mm/Makefile since the mm/ build is identical to the libc/ build.
libs/libnx/Makefile: Same change should be applied to libnx/Makefile since the mm/ build is identical to the libc/ build.
Author: chao.an <anchao@xiaomi.com>
libs/libc/Makefile: Correct the dependents path
Here is the email loop talk about why it is better to remove the option:
https://groups.google.com/forum/#!topic/nuttx/AaNkS7oU6R0
Change-Id: Ib66c037752149ad4b2787ef447f966c77aa12aad
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
* Simplify EINTR/ECANCEL error handling
1. Add semaphore uninterruptible wait function
2 .Replace semaphore wait loop with a single uninterruptible wait
3. Replace all sem_xxx to nxsem_xxx
* Unify the void cast usage
1. Remove void cast for function because many place ignore the returned value witout cast
2. Replace void cast for variable with UNUSED macro
Iobinstrumentation
* mm/iob: Introduces producer/consumer id to every iob call. This is so that the calls can be instrumented to monitor the IOB resources.
* iob instrumentation - Merges producer/consumer enumeration for simpler IOB user.
* fs/procfs: Starts adding support for /proc/iobinfo
* fs/procfs: Finishes first pass of simple IOB user stastics and /proc/iobinfo entry
Approved-by: Gregory Nutt <gnutt@nuttx.org>
arch/mips/src: Previous commit used CP0 register definitions that were not defined in the cp0.h header file. Probably these were from the Microchip hacked up GCC toolchain but are not generally available. Fix: Add definitions to NuttX cp0.h header file.
mm/iob: Eliminate some warnings about testing the value of an undefined pre-processor variable.
- Logic that generates the low lever framebuffer renderers for the per-window framebuffers,
- The logic that picks off the per-window framebuffer updates from normal graphics device updates. This logic must update both the per-window framebuffer and the graphics device (from the framebuffer).
Squashed commit of the following:
graphics: Add logic to allocate the per-window framebuffer.
graphics: A few fragmentary thoughts on how a per-window framebuffer could be represented and allocated.
sched/init/nx_bringup.c: Fix a naming collision.
sched/init: Rename os_start() to nx_start()
sched/init: Rename os_smp* to nx_smp*
sched/init: Rename os_bringup to nx_bringup
sched/init: rename all internal static functions to begin with nx_ vs os_
This commit repartitions the logic by moving some of the changes from mm_sem.c into task_getpid.c. The logic is equivalent for the case of mm_trysemaphore(), but no has wider impact since it potentially affects all callers of getpid(). Hence, this change may also introduce some other issues that will need to be addressed.
This change adds a check to mm_trysemaphore() (the root implementation of both kmm_trysemaphore() and umm_trysemaphore()). It checks if the that task that is apparently executing is marked as RUNNING. If not, how could the non-running task be trying to get the MM semaphore? I think only in the exact scenario that Eunbong Song has described.
So I think the solution should provide the same protection as 91aa26774b but without the horrific consequences to memory usage.
Pullreq libc libnx updates
* NuttX: make strerror() return 'Success' for 0
* NuttX: fix strrchr() so that it considers null terminator as part of string
From strrchr(3) man page:
"The terminating null byte is considered part of the string, so that if c
is specified as '\0', these functions return a pointer to the terminator."
* NuttX: mm_free(): Add DEBUGASSERT()'s to catch memory corruption early.
It's easier to find the source when asserts fail already when freeing
an overflowed buffer, than if the corruption is only detected on next
malloc().
* MM_FILL_ALLOCATIONS: Add debug option to fill all mallocs()
This is helpful for detecting uninitialized variables,
especially in C++ code. I seem to be forgetting to initialize
member variables and then they just get random values..
* NuttX: nxtk_bitmapwindow: Fix warning message when bitmap is fully off-screen.
* nxfonts_getfont: Avoid unnecessary warnings for other whitespace chars also.
* NuttX: Fix kerning of 'I' in Sans17x22 font
The I character was running together with some other
characters, e.g. in sequence "IMI".
* NXMU: Revalidate window pointer for mouse events.
NXMU caches the previous window pointer so that further mouse
events can be sent to the same window. However, if the window
is destroyed while mouse button is held down, the pointer may
become invalid and cause a crash. This patch revalidates the
pointer before using it.
Approved-by: GregoryN <gnutt@nuttx.org>
Squashed commit of the following:
Fix up some final compile isses.
net/netdev: Convert the network down notification logic to use the new wqueue-based notification factility.
net/udp: Convert the UDP readahead notification logic to use the new wqueue-based notification factility.
net/tcp: Convert the TCP readahead notification logic to use the new wqueue-based notification factility.
mm/iob: Convert the IOB notification logic to use the new wqueue-based notification factility.
sched/wqueue: Signals are not good IPCs to support the target poll functionality for several reasons including the amount of data that can be passed with a signal and in the fact that in protected and kernel modes, user threads executing signal handlers in protected, kernel memory is problematic. Instead, convert the same logic to perform the notifications via function callback on the high priority work queue.
Squashed commit of the following:
net/tcp: Add signal notification for the case when UDP read-ahead data is buffered. This is basically of clone of the TCP notification logic with naming adapted for UDP.
net/tcp: Add signal notification for the case when TCP read-ahead data is buffered.
Squashed commit of the following:
mm/iob: The IOB available notifier is now just a wrapper around the common signal notifier.
sched/signal: Add a generic signal notification facility.
sched/signal/sig_evthread.c: More trivial naming changes.
sched/signal: Rename nxsig_notification() to nxsig_evthread() to make forthcoming naming additions more consistent.
Fix SMP related bugs
* sched/sched: Fix a deadlock in SMP mode
Two months ago, I introduced sched_tasklist_lock() and
sched_tasklist_unlock() to protect tasklists in SMP mode.
Actually, this change works pretty well for HTTP audio
streaming aging test with lc823450-xgevk.
However, I found a deadlock in the scheduler when I tried
similar aging tests with DVFS autonomous mode where CPU
clock speed changed based on cpu load. In this case, call
sequences were as follows;
cpu1: sched_unlock()->sched_mergepending()->sched_addreadytorun()->up_cpu_pause()
cpu0: sched_lock()->sched_mergepending()
To avoid this deadlock, I added sched_tasklist_unlock() when calling
up_cpu_pause() and sched_addreadytorun(). Also, added
sched_tasklist_lock() after the call.
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
* libc: Add critical section in lib_filesem.c for SMP
To set my_pid into fs_folder atomically in SMP mode,
critical section API must be used.
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
* mm: Add critical section in mm_sem.c for SMP
To set my_pid into mm_folder atomically in SMP mode,
critical section API must be used.
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
* net: Add critical section in net_lock.c for SMP
To set my pid (me) into fs_folder atomically in SMP mode,
critical section API must be used.
Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
Approved-by: Gregory Nutt <gnutt@nuttx.org>
binfmt/, configs/, grahics/, libc/, mm/, net/, sched/: OS references to the errno variable should always use the set_errno(), get_errno() macros
arch/arm/src/stm32 and stm32f7: Architecture-specific code is not permitted to modify the errno variable. drivers/ and libc/: OS references to the errno variable should always use the set_errno(), get_errno() macros
Squashed commit of the following:
net/udp: Address most of the issues with UDP write buffering. There is a remaining issue with handling one network going down in a multi-network environment. None of this has been test but it is certainly ready for test. Hence, the feature is marked EXPERIMENTAL.
net/udp: Some baby steps toward a corrected write buffering design.
net/udp: Remove pesky write buffer macros.
Eliminate trailing space at the end of lines.
net/udp: A little more UDP write buffering logic. Still at least on big gaping hole in the design.
net/udp: Undefined CONFIG_NET_SENDTO_TIMEOUT.
net/udp: Crude, naive port of the TCP write buffering logic into UDP. This commit is certainly non-functional and is simply a starting point for the implementatin of UDP write buffering.
net/udp: Rename udp/udp_psock_sendto.c udp/udp_psock_sendto_unbuffered.c.
Replace all usage kill() in the OS proper with nxsig_kill().
sched/signal: Add nxsig_kill() which is functionally equivalent to kill() except that it does not modify the errno variable.
This commit backs out most of commit b4747286b1. That change was added because sem_wait() would sometimes cause cancellation points inappropriated. But with these recent changes, nxsem_wait() is used instead and it is not a cancellation point.
In the OS, all calls to sem_wait() changed to nxsem_wait(). nxsem_wait() does not return errors via errno so each place where nxsem_wait() is now called must not examine the errno variable.
In all OS functions (not libraries), change sem_wait() to nxsem_wait(). This will prevent the OS from creating bogus cancellation points and from modifying the per-task errno variable.
sched/semaphore: Add the function nxsem_wait(). This is a new internal OS interface. It is functionally equivalent to sem_wait() except that (1) it is not a cancellation point, and (2) it does not set the per-thread errno value on return.
sched/semaphore: Add nxsem_post() which is identical to sem_post() except that it never modifies the errno variable. Changed all references to sem_post in the OS to nxsem_post().
sched/semaphore: Add nxsem_destroy() which is identical to sem_destroy() except that it never modifies the errno variable. Changed all references to sem_destroy() in the OS to nxsem_destroy().
libc/semaphore and sched/semaphore: Add nxsem_getprotocol() and nxsem_setprotocola which are identical to sem_getprotocol() and set_setprotocol() except that they never modifies the errno variable. Changed all references to sem_setprotocol in the OS to nxsem_setprotocol(). sem_getprotocol() was not used in the OS
libc/semaphore: Add nxsem_getvalue() which is identical to sem_getvalue() except that it never modifies the errno variable. Changed all references to sem_getvalue in the OS to nxsem_getvalue().
sched/semaphore: Rename all internal private functions from sem_xyz to nxsem_xyz. The sem_ prefix is (will be) reserved only for the application semaphore interfaces.
libc/semaphore: Add nxsem_init() which is identical to sem_init() except that it never modifies the errno variable. Changed all references to sem_init in the OS to nxsem_init().
sched/semaphore: Rename sem_tickwait() to nxsem_tickwait() so that it is clear this is an internal OS function.
sched/semaphoate: Rename sem_reset() to nxsem_reset() so that it is clear this is an internal OS function.
Task A holds an IOB. There are no further IOBs. The value of semcount is zero.
Task B calls iob_alloc(). Since there are not IOBs, it calls sem_wait(). The v
alue of semcount is now -1.
Task A frees the IOB. iob_free() adds the IOB to the free list and calls sem_post() this makes Task B ready to run and sets semcount to zero NOT 1. There is one IOB in the free list and semcount is zero. When Task B wakes up it would increment the sem_count back to the correct value.
But an interrupt or another task runs occurs before Task B executes. The interrupt or other tak takes the IOB off of the free list and decrements the semcount. But since semcount is then < 0, this causes the assertion because that is an invalid state in the interrupt handler.
So I think that the root cause is that there the asynchrony between incrementing the semcount. This change separates the list of IOBs: Currently there is only a free list of IOBs. The problem, I believe, is because of asynchronies due sem_post() post cause the semcount and the list content to become out of sync. This change adds a new 'committed' list: When there is a task waiting for an IOB, it will go into the committed list rather than the free list before the semaphore is posted. On the waiting side, when awakened from the semaphore wait, it will expect to find its IOB in the committed list, rather than free list.
In this way, the content of the free list and the value of the semaphore count always remain in sync.
The solution is to remove all of the memory management function calls from the interface. Instead, the interface exports the userspace heap structure and then kernel size implementations of those memory management functions will operate on the userspace heap structure. This avoids the unnecessary system calls and, more importantly, failures do to freeing memory when a test exits.