nwnss: preserve yield lock boundary

This commit is contained in:
ChatGPT
2026-06-18 08:03:31 +00:00
committed by Mario Fetka
parent 2c30de2089
commit ea135aa1fa
3 changed files with 46 additions and 2 deletions

View File

@@ -120,7 +120,7 @@ still stay original and remain listed, because later imports may rely on them.
| AUDITED | `src/nwnss/library/misc/rand.c` | PORT | nwnss.rand, nwnss.namespace | No original provider found beyond rand.h/libNSS.imp/callers; seed-deterministic PRNG port checked in 0700/0701/0718; also provides xStdlib.h rand/random/srand/srandom/initstate/setstate wrappers; libsodium only initializes default state before explicit seeding. |
| AUDITED | `src/nwnss/library/misc/rbpTree.c` | PORT | nwnss.rbpTree | No original provider found beyond rbpTree.h/libNSS.imp/callers; CLRS-style algorithmic port checked against header contract in 0703 and strengthened in 0705 with explicit red/black, parent-link, binary-search-order, black-height, and Coin3D-style insertion/deletion stress coverage. Coin3D rbptree.cpp was checked only as an external BSD-licensed CLRS comparison and was not imported. |
| AUDITED | `src/nwnss/library/os/currentTime.c` | PORT | nwnss.utc | No userspace original provider exists after checking `public_core/library/utc` and `public_core/sharedsrc`; `public_core/nsslnxlib/nssLnxDummy.c` has a kernel jiffies-oriented `GetCurrentTime`, while `public_core/library/utc/gethres.386` documents the high-resolution timer unit as 100 microseconds. The userspace port keeps `GetCurrentTime()` on a monotonic centisecond/HZ=100 scale and now exposes `GetHighResolutionTimer()` on the documented 1/10000-second scale for checker/compression callers; covered by nwnss.utc. |
| AUDITED | `src/nwnss/library/os/delay.c` | ORIG+FIX/PORT | nwnss.schedule, nwnss.snooze | Scheduler functions kept as functions, not macros; checked in 0688-0690. |
| AUDITED | `src/nwnss/library/os/delay.c` | ORIG+FIX/PORT | nwnss.schedule, nwnss.snooze | Scheduler functions kept as userspace functions, not macros; original `ZOS_YieldThread`/sleep/schedule lock-boundary behavior rechecked against `nssOSAPIs.h`, and userspace yield now drops/reacquires MPKNSS when owned so other threads can run without the global lock held. |
| AUDITED | `src/nwnss/library/os/nebEventPort.c` | PORT | nwnss.neb | Explicit NEB/nebus service port; checked in 0683-0685. |
| AUDITED | `src/nwnss/library/os/pssmpk.c` | PORT | nwnss.pssmpk | pthread owner semantics checked/fixed in 0692. |
| AUDITED | `src/nwnss/library/stdlib/strtol.c` + `include/nwnss/library/xStdlib.h` | PORT + ORIG+FIX header | nwnss.stdlib | No LB_strtol original/sharedsrc found after full NSS/nss-common search; Novell/POSIX strtol semantics mapped to host libc and hardened in 0708. |
@@ -644,7 +644,7 @@ even if it already compiles or has indirect test coverage.
| AUDITED | ORIG+FIX/PORT | nwnss.alarm | `src/nwnss/library/os/alarm.c` | Compared with original `public_core/library/os/alarm.c`; alarm wheel/one-shot/cyclic logic kept. Userspace port removes kernel timer semaphore/work callback re-arm, adds typed callbacks and include-path/HZ compatibility; tests cover immediate/delayed/canceled one-shots, cyclic requeue and alarm stop. |
| AUDITED | ORIG+FIX | nwnss.config | `src/nwnss/library/os/config.c` | Compared with original `public_core/library/os/config.c`; Config initializer and startup-derived hash/tick fields kept. Differences are linux/module.h removal, include-path normalization and whitespace cleanup; tests cover defaults, hash masks, tick conversions and LV purge defaults. |
| AUDITED | PORT | nwnss.utc | `src/nwnss/library/os/currentTime.c` | No userspace original provider exists after checking `public_core/library/utc` and `public_core/sharedsrc`; `public_core/nsslnxlib/nssLnxDummy.c` has a kernel jiffies-oriented `GetCurrentTime`, while `public_core/library/utc/gethres.386` documents the high-resolution timer unit as 100 microseconds. The userspace port keeps `GetCurrentTime()` on a monotonic centisecond/HZ=100 scale and now exposes `GetHighResolutionTimer()` on the documented 1/10000-second scale for checker/compression callers; covered by nwnss.utc. |
| AUDITED | ORIG+FIX/PORT | nwnss.schedule, nwnss.snooze | `src/nwnss/library/os/delay.c` | Scheduler functions kept as functions, not macros; checked in 0688-0690. |
| AUDITED | ORIG+FIX/PORT | nwnss.schedule, nwnss.snooze | `src/nwnss/library/os/delay.c` | Compared with original `public_core/library/os/delay.c` and the original scheduler macros in `shared/sdk/internal/nssOSAPIs.h`; userspace keeps the scheduler API as real functions. `LB_delay`, `ZOS_Sleep`, `ZOS_ScheduleWorkToDo` and now `ZOS_YieldThread` preserve the original MPKNSS scheduling boundary by dropping/reacquiring the global lock when the current thread owns it; tests cover locked delay, schedule callbacks outside the lock and yield allowing another thread through the lock boundary. |
| AUDITED | ORIG+FIX | nwnss.inst | `src/nwnss/library/os/inst.c` | Compared with original `public_core/library/os/inst.c`; instrumentation harvest/reset/init logic kept. Differences are linux/module.h removal and include-path normalization; tests cover file/cache/Linux/BST counter harvest/reset and cyclic init wiring. |
| AUDITED | ORIG+FIX | nwnss.mailbox | `src/nwnss/library/os/mailbox.c` | Compared with original `public_core/library/os/mailbox.c`; mbInit/mbSetHigh behavior kept. Differences are procdefs/include-path normalization and whitespace cleanup; tests cover empty/full/FIFO, peek/drop, next/give and wraparound behavior. |
| AUDITED | PORT | nwnss.neb | `src/nwnss/library/os/nebEventPort.c` | Explicit NEB/nebus service port; checked in 0683-0685. |

View File

@@ -86,7 +86,19 @@ THREAD kCurrentThread(void)
void ZOS_YieldThread(void)
{
BOOL hadLock = MPKNSS_I_OWN_SPINLOCK();
if (hadLock)
{
MPKNSS_UNLOCK();
}
sched_yield();
if (hadLock)
{
MPKNSS_LOCK();
}
}
void CYieldUntilIdle(void)

View File

@@ -3,6 +3,9 @@
#include <include/pssmpk.h>
#include <include/xError.h>
#include <pthread.h>
#include <sched.h>
#define CHECK(expr) do { if (!(expr)) return __LINE__; } while (0)
extern LONG Delayed;
@@ -11,6 +14,19 @@ static int scheduled_called;
static int scheduled_saw_lock;
static void *scheduled_arg;
static volatile int yield_waiter_state;
static void *yield_waiter(void *arg)
{
(void)arg;
yield_waiter_state = 1;
MPKNSS_LOCK();
yield_waiter_state = 2;
MPKNSS_UNLOCK();
return NULL;
}
static void scheduled_callback(void *arg)
{
scheduled_called++;
@@ -23,6 +39,8 @@ int main(void)
LONG before;
zWorkProc_s work;
THREAD self;
pthread_t waiter;
int spins;
MPKNSS_INIT_LOCK();
@@ -51,6 +69,20 @@ int main(void)
ZOS_WakeUp(self);
Continue(self);
yield_waiter_state = 0;
CHECK(MPKNSS_LOCK());
CHECK(pthread_create(&waiter, NULL, yield_waiter, NULL) == 0);
for (spins = 0; spins < 100000 && yield_waiter_state == 0; ++spins)
{
sched_yield();
}
CHECK(yield_waiter_state == 1);
ZOS_YieldThread();
CHECK(MPKNSS_I_OWN_SPINLOCK());
CHECK(yield_waiter_state == 2);
CHECK(MPKNSS_UNLOCK());
CHECK(pthread_join(waiter, NULL) == 0);
CHECK(ZOS_ScheduleWorkToDo(NULL) == zERR_BAD_PARAMETER_VALUE);
CHECK(ZOS_CancelWorkToDo(NULL) == zOK);