feat: extend rtc with RtcDateTime
This commit is contained in:
1 parent
8af9a09f89
commit
30188c37d0
2 files changed
+165
-1
No files matched your search
+100
-1
@@ -3,13 +3,78 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "vfs.h"
|
||||
#include "prioq.h"
|
||||
#include "isr.h"
|
||||
#include "signalnum.h"
|
||||
#include "mmap.h"
|
||||
|
||||
/* Default scheduling weight (xv6/CFS-style "nice" niceWeight -- higher runs
|
||||
more often, not longer). threadSetPriority scales relative to this. */
|
||||
#define schedDefaultWeight 1024u
|
||||
|
||||
/* Returned by threadCreate/threadCreateUser when the thread table is full
|
||||
(see threadCapacity) -- never a valid thread id, since id 0 is always the
|
||||
permanent idle thread. Callers must check for this before using the
|
||||
result to index into anything thread-related. */
|
||||
#define threadInvalidId 0xFFFFFFFFu
|
||||
|
||||
/* Capacity of Thread.name, including the terminator. Large enough for every
|
||||
name this kernel currently produces (kernel thread literals, "/bin/..."
|
||||
paths passed to threadCreateUser by spawnUser/doSpawn) with room to
|
||||
spare; longer names are truncated, never overflowed. */
|
||||
#define threadNameMax 32
|
||||
|
||||
/* Capacity of Thread.env below: envMaxVars is how many "NAME=VALUE" slots
|
||||
a process may hold at once, envEntryMax is the max size in bytes of a
|
||||
single slot INCLUDING both the '=' separator and the nul terminator
|
||||
(so "NAME=VALUE\0" must fit in envEntryMax bytes). Generous enough for
|
||||
anything this kernel's own shell/demos actually set (see user/envprint.c)
|
||||
with room to spare, the same "small fixed table, not a growable heap
|
||||
allocation" choice Thread.cwd already made for a single path. */
|
||||
#define envMaxVars 8
|
||||
#define envEntryMax 64
|
||||
|
||||
/* One bit per signal number in Thread.sigPending/sigBlocked, and the size
|
||||
of Thread.sigHandlers[] below -- see signal.h for the actual signal
|
||||
subsystem this supports. Defined here, not signal.h, purely to break the
|
||||
include cycle (signal.h includes sched.h for the Thread type). */
|
||||
#define sigMaxSignals 32
|
||||
|
||||
/* Depth of the per-thread nested-handler context stack (Thread.sigSavedRegs/
|
||||
sigSavedBlocked below) -- how many signal handlers may genuinely interrupt
|
||||
each other (handler A running, a second signal arrives and is not blocked
|
||||
by A's own sa_mask, so handler B runs nested inside A, then A resumes once
|
||||
B returns) before sigConsumePending (signal.c) refuses to deliver a new
|
||||
one and simply leaves it pending. A real kernel bounds this too (rlimit
|
||||
on the signal-frame stack it pushes into user memory); this one has no
|
||||
user-memory signal frame to overflow at all (see signal.h's file comment
|
||||
-- the saved context lives in the Thread struct itself), so the bound
|
||||
exists purely to keep that struct's size fixed and to fail a runaway
|
||||
signal-storm safely (further deliveries just wait) instead of unboundedly
|
||||
growing kernel memory per thread. 4 is generous headroom for anything
|
||||
this kernel's own handlers actually do (none nest more than one deep
|
||||
today -- see user/nesttarget.c) without being large enough to make
|
||||
Thread noticeably bigger than sigMaxSignals-worth of handlers already
|
||||
makes it. */
|
||||
#define sigMaxNestDepth 4
|
||||
|
||||
typedef enum {
|
||||
threadUnused = 0,
|
||||
threadRunnable = 1,
|
||||
threadRunning = 2,
|
||||
threadSleeping = 3,
|
||||
threadDead = 4
|
||||
threadDead = 4,
|
||||
threadBlocked = 5,
|
||||
/* Job-control stop (signal.h's SIGSTOP/SIGTSTP): excluded from
|
||||
schedule()'s ready-queue rebuild exactly like Sleeping/Blocked
|
||||
already are (only threadRunnable is ever inserted), so a stopped
|
||||
thread simply never gets picked until threadContinue moves it back
|
||||
to threadRunnable. Distinct from threadBlocked because it is NOT
|
||||
waiting on a wait-channel condition -- schedWakeChannel must never
|
||||
treat it as a match (see schedWakeChannel), only threadContinue
|
||||
(an explicit SIGCONT, not "the resource became available") ever
|
||||
moves a thread out of this state. */
|
||||
threadStopped = 6
|
||||
} ThreadState;
|
||||
|
||||
typedef void (*ThreadEntry)(void);
|
||||
@@ -19,7 +84,41 @@ typedef struct Thread {
|
||||
uint64 stackBase;
|
||||
uint64 kernelStackTop;
|
||||
uint64 sleepUntil;
|
||||
/* Absolute pitTicks() deadline for a pending alarm(2)-style SIGALRM
|
||||
(0 == no alarm pending), set by threadSetAlarm and consulted once
|
||||
per timer tick by schedule() -- the exact same shape as sleepUntil
|
||||
above, checked in the exact same loop, except expiry raises a real
|
||||
signal (sigRaise, signal.h) against the owning thread instead of
|
||||
just flipping its own ThreadState back to Runnable. Deliberately a
|
||||
plain deadline, not a wait-channel/ThreadState change: unlike
|
||||
threadSleep, a thread with a pending alarm keeps running (or
|
||||
sleeping, or blocked on something unrelated) exactly as it already
|
||||
was right up until the deadline, exactly like real alarm()'s timer
|
||||
ticking down in the background regardless of what the process is
|
||||
doing. */
|
||||
uint64 alarmAt;
|
||||
/* poll.h's sysPoll (syscall.c) uses the same restart-the-syscall park
|
||||
pattern sysRead/sysWrite/sysWait already use, but a poll call can be
|
||||
woken by any one of several unrelated fds, not one -- so instead of
|
||||
parking on a single fd's own wait channel (vfsBlockingChannel),
|
||||
sysPoll blocks every waiting thread on ONE shared channel
|
||||
(schedPollChannel below) and simply re-checks its whole fd list from
|
||||
scratch on every wake, spurious or not, exactly like the retry loop
|
||||
every OTHER restartable syscall already has. pollActive marks "this
|
||||
thread is mid a not-yet-satisfied sysPoll call" (so a retry entry
|
||||
can tell itself apart from a genuinely fresh call); pollDeadline is
|
||||
the absolute pitTicks() deadline schedule()'s own expiry scan forces
|
||||
a wake at if no fd ever becomes ready first (0 == wait forever,
|
||||
meaningful only while pollActive is true -- the same "0 reserved"
|
||||
convention alarmAt above already uses, but here 0 is a real,
|
||||
legal, requested state (a timeout of -1) rather than "nothing
|
||||
pending"). */
|
||||
bool pollActive;
|
||||
uint64 pollDeadline;
|
||||
uint64 brk;
|
||||
uint64 vruntime;
|
||||
uint64 exitCode;
|
||||
uint32 weight;
|
||||
uint32 id;
|
||||
ThreadState state;
|
||||
const char* name;
|
||||
|
||||
Reference in new issue
Block a user