59 lines
2.4 KiB
C
59 lines
2.4 KiB
C
// waitpid + times regression for GNO/ME. Forks a leaf child that _exit(37)s,
|
|
// then the parent reaps it with waitpid(pid, &st, 0) -- verifying the pure-C
|
|
// waitpid loop returns the exact child pid and the real exit status -- and
|
|
// finally calls times() and checks the deterministic fields the GNO kernel
|
|
// zero-fills (return value, tms_stime, tms_cstime), a crash-free sanity marker.
|
|
//
|
|
// GNO fork is a thread-spawn: the child begins at child() on a fresh stack/DP,
|
|
// so child() is a LEAF using only absolute-long stores + _exit (no DP scratch).
|
|
// Bank-2 absolute markers (DBR-independent), per the gnoForkWaitProbe convention.
|
|
// 0x025000 C0DE reached end (no hang in waitpid/times)
|
|
// 0x025010 C41D child was scheduled + ran
|
|
// 0x025014 0025 WEXITSTATUS == 37 (status propagated through waitpid)
|
|
// 0x025016 0001 waitpid reaped the same pid fork() returned
|
|
// 0x025018 0001 times() sanity: ret==0 && tms_stime==0 && tms_cstime==0
|
|
#include <stdint.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/times.h>
|
|
|
|
extern int fork(void *subr); // GNO thread-spawn: subr = (void *)&childFn
|
|
extern __attribute__((noreturn)) void _exit(int status);
|
|
extern int waitpid(int pid, int *status, int options);
|
|
extern clock_t times(struct tms *buf);
|
|
|
|
#define M(a) (*(volatile uint16_t *)(a))
|
|
|
|
|
|
static void child(void) {
|
|
M(0x025010UL) = 0xC41D; // child was scheduled + entered child()
|
|
_exit(37); // exit code 37 -> status word 0x2500
|
|
}
|
|
|
|
|
|
int main(void) {
|
|
M(0x025000UL) = 0x0000;
|
|
int pid = fork((void *)child);
|
|
if (pid <= 0) {
|
|
M(0x025016UL) = 0xDEAD; // fork failed / returned no child
|
|
M(0x025000UL) = 0xC0DE;
|
|
for (volatile unsigned long j = 0; j < 300000UL; j++) {
|
|
}
|
|
return 0;
|
|
}
|
|
int st = 0;
|
|
int w = waitpid(pid, &st, 0); // pure-C loop over wait() until pid reaped
|
|
M(0x025014UL) = WIFEXITED(st) ? (uint16_t)WEXITSTATUS(st) : 0xEEEE; // == 0x0025
|
|
M(0x025016UL) = (w == pid) ? 0x0001 : 0xDEAD; // pid round-trip
|
|
|
|
struct tms tb;
|
|
tb.tms_stime = 0xFFFFFFFFUL; // poison; kernel must overwrite with 0
|
|
tb.tms_cstime = 0xFFFFFFFFUL;
|
|
clock_t rc = times(&tb);
|
|
uint16_t timesOk = (rc == 0 && tb.tms_stime == 0 && tb.tms_cstime == 0) ? 0x0001 : 0xDEAD;
|
|
M(0x025018UL) = timesOk;
|
|
|
|
M(0x025000UL) = 0xC0DE; // reached end
|
|
for (volatile unsigned long j = 0; j < 300000UL; j++) {
|
|
}
|
|
return 0;
|
|
}
|