diff --git a/Documentation/NuttXDemandPaging.html b/Documentation/NuttXDemandPaging.html new file mode 100755 index 0000000000..d6a6c340c3 --- /dev/null +++ b/Documentation/NuttXDemandPaging.html @@ -0,0 +1,417 @@ + +
+
+ On-Demand Paging+>>> Under Construction <<<+Last Updated: August 12, 2010 + |
+
+ Table of Contents+ |
+
+
|
+||
+
|
+||
+
|
+||
+
|
+||
+
|
+||
+
|
+
+ Terminolgy+ |
+
g_waitingforfill
g_pendingfill
g_pgworker
pg_callback()
pg_miss()
TCB
+ Initialization+ |
+
+ The following declarations will be added. +
g_waitingforfill
.
+ A doubly linked list that will be used to implement a prioritized list of the TCBs of tasks that are waiting for a page fill.
+ g_pgworker
.
+ The process ID of of the thread that will perform the page fills
+
+ During OS initialization in sched/os_start.c
, the following steps
+ will be performed:
+
g_waitingforfill
queue will be initialized.
+ pid
of the page will worker thread will be saved in g_pgworker
.
+ Note that we need a special worker thread to perform fills;
+ we cannot use the "generic" worker thread facility because we cannot be
+ assured that all actions called by that worker thread will always be resident in memory.
+
+ Declarations for g_waitingforfill
, g_pgworker
, and other
+ internal, private definitions will be provided in sched/pg_internal.h
.
+ All public definitions that should be used by the chip-specific code will be available
+ in include/nuttx/page.h
and include/nuttx/arch.h
.
+
+ Page Faults+ |
+
+ Page fault exception handling.
+ Page fault handling is performed by the function pg_miss()
.
+ This function is called from architecture-specific memory segmentation
+ fault handling logic. This function will perform the following
+ operations:
+
up_block_task()
to block the task at the head of the ready-to-run list.
+ This should cause an interrupt level context switch to the next highest priority task.
+ The blocked task will be marked with state TSTATE_WAIT_PAGEFILL
and will be retained in the g_waitingforfill
prioritized task list.
+ g_waitingforfill
list.
+ If the priority of that task is higher than the current priority of the page fill worker thread, then boost the priority of the page fill worker thread to that priority.
+
+ When signaled from pg_miss()
, the page fill worker thread will be awakenend and will initiate the fill operation.
+
+ Input Parameters. + None -- The head of the ready-to-run list is assumed to be that task that caused the exception. + The current task context should already be saved in the TCB of that task. + No additional inputs are required. +
++ Assumptions. +
pg_miss()
must be "locked" in memory.
+ Calling pg_miss()
cannot cause a nested page fault.
+ + Locking code in Memory. + One way to accomplish this would be a two phase link: +
.text
and .rodata
sections of this partial link should be collected into a single section.
+
+ Fill Initiation+ |
+
+ The page fill worker thread will be awakened on one of two conditions: +
pg_miss()
, the page fill worker thread will be awakenend (see above), or
+ pg_fillcomplete()
after completing last fill (see below).
+
+ The page fill worker thread will maintain a static variable called _TCB *g_pendingfill
.
+ If not fill is in progress, g_pendingfill
will be NULL.
+ Otherwise, will point to the TCB of the task which is receiving the fill that is in progess.
+
+ When awakened from pg_miss()
, no fill will be in progress and g_pendingfill
will be NULL.
+ In this case, the page fill worker thread will call pg_startfill()
.
+ That function will perform the following operations:
+
up_allocpage(vaddr, &page)
.
+ This chip-specific function will set aside page in memory and map to virtual address (vaddr).
+ If all pages available pages are in-use (the typical case),
+ this function will select a page in-use, un-map it, and make it available.
+ up_fillpage(page, pg_callback)
.
+ This will start asynchronous page fill.
+ The page fill worker thread will provide a callback function, pg_callback
,
+ that will be called when the page fill is finished (or an error occurs).
+ This callback will probably from interrupt level.
+
+ While the fill is in progress, other tasks may execute.
+ If another page fault occurs during this time, the faulting task will be blocked and its TCB will be added (in priority order) to g_waitingforfill
.
+ But no action will be taken until the current page fill completes.
+ NOTE: The IDLE task must also be fully locked in memory.
+ The IDLE task cannot be blocked.
+ It the case where all tasks are blocked waiting for a page fill, the IDLE task must still be available to run.
+
+ The chip-specific functions, up_allocpage(vaddr, &page)
and up_fillpage(page, pg_callback)
+ will be prototyped in include/nuttx/arch.h
+
+ Fill Complete+ |
+
+ When the chip-specific driver completes the page fill, it will call the pg_callback()
that was provided to up_fillpage
.
+ pg_callback()
will probably be called from driver interrupt-level logic.
+ The driver ill provide the result of the fill as an argument.
+ NOTE: pg_callback()
must also be locked in memory.
+
+ When pg_callback()
is called, it will perform the following operations:
+
g_pendingfill
is non-NULL.
+ g_pendingfill
is higher than page fill worker thread, boost work thread to that level.
+
+ Task Resumption+ |
+
+ When the page fill worker thread is awakened and g_pendingfill
is non-NULL (and other state variables are in concurrence),
+ the page fill thread will know that is was awakened because of a page fill completion event.
+ In this case, the page fill worker thread will:
+
g_pendingfill
.
+ up_unblocktask(g_pendingfill)
to make the task that just received the fill ready-to-run.
+ g_waitingforfill
list is empty.
+ If not:
+ g_waitingforfill
,
+ g_pendingfill
,
+ g_pendingfill
, is higher in priority than the default priority of the page fill worker thread, then set the priority of the page fill worker thread to that priority.
+ pg_startfill()
which will start the next fill (as described above).
+ g_pendingfill
to NULL.
+