diff --git a/Documentation/NuttXDemandPaging.html b/Documentation/NuttXDemandPaging.html new file mode 100755 index 00000000000..d6a6c340c3d --- /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_waitingforfillg_pendingfillg_pgworkerpg_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.
+