Changeset 567 for trunk/kernel/mm/page.c
- Timestamp:
- Oct 5, 2018, 12:01:52 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/page.c
r486 r567 27 27 #include <hal_atomic.h> 28 28 #include <list.h> 29 #include < xlist.h>29 #include <queuelock.h> 30 30 #include <memcpy.h> 31 #include <thread.h>32 #include <scheduler.h>33 #include <cluster.h>34 #include <ppm.h>35 #include <mapper.h>36 31 #include <printk.h> 37 32 #include <vfs.h> 38 33 #include <process.h> 39 34 #include <page.h> 35 40 36 41 37 //////////////////////////////////////// … … 49 45 page->forks = 0; 50 46 51 spinlock_init( &page->lock ); 47 remote_busylock_init( XPTR( local_cxy , &page->lock ), LOCK_PAGE_STATE ); 48 52 49 list_entry_init( &page->list ); 53 xlist_root_init( XPTR( local_cxy , &page->wait_root ) );54 50 } 55 51 … … 73 69 { 74 70 return ( (page->flags & value) ? 1 : 0 ); 75 }76 77 //////////////////////////////////////78 bool_t page_do_dirty( page_t * page )79 {80 bool_t done = false;81 82 ppm_t * ppm = &LOCAL_CLUSTER->ppm;83 84 // lock the PPM dirty_list85 spinlock_lock( &ppm->dirty_lock );86 87 if( !page_is_flag( page , PG_DIRTY ) )88 {89 // set dirty flag in page descriptor90 page_set_flag( page , PG_DIRTY );91 92 // register page in PPM dirty list93 list_add_first( &ppm->dirty_root , &page->list );94 done = true;95 }96 97 // unlock the PPM dirty_list98 spinlock_unlock( &ppm->dirty_lock );99 100 return done;101 }102 103 ////////////////////////////////////////104 bool_t page_undo_dirty( page_t * page )105 {106 bool_t done = false;107 108 ppm_t * ppm = &LOCAL_CLUSTER->ppm;109 110 // lock the dirty_list111 spinlock_lock( &ppm->dirty_lock );112 113 if( page_is_flag( page , PG_DIRTY) )114 {115 // clear dirty flag in page descriptor116 page_clear_flag( page , PG_DIRTY );117 118 // remove page from PPM dirty list119 list_unlink( &page->list );120 done = true;121 }122 123 // unlock the dirty_list124 spinlock_unlock( &ppm->dirty_lock );125 126 return done;127 }128 129 /////////////////////130 void sync_all_pages( void )131 {132 page_t * page;133 ppm_t * ppm = &LOCAL_CLUSTER->ppm;134 135 // lock the dirty_list136 spinlock_lock( &ppm->dirty_lock );137 138 while( !list_is_empty( &ppm->dirty_root ) )139 {140 page = LIST_FIRST( &ppm->dirty_root , page_t , list );141 142 // unlock the dirty_list143 spinlock_unlock( &ppm->dirty_lock );144 145 // lock the page146 page_lock( page );147 148 // sync the page149 vfs_mapper_move_page( page , false ); // from mapper150 151 // unlock the page152 page_unlock( page );153 154 // lock the dirty_list155 spinlock_lock( &ppm->dirty_lock );156 }157 158 // unlock the dirty_list159 spinlock_unlock( &ppm->dirty_lock );160 161 }162 163 ///////////////////////////////164 void page_lock( page_t * page )165 {166 // take the spinlock protecting the PG_LOCKED flag167 spinlock_lock( &page->lock );168 169 if( page_is_flag( page , PG_LOCKED ) ) // page is already locked170 {171 // get pointer on calling thread172 thread_t * thread = CURRENT_THREAD;173 174 // register thread in the page waiting queue175 xlist_add_last( XPTR( local_cxy , &page->wait_root ),176 XPTR( local_cxy , &thread->wait_list ) );177 178 // release the spinlock179 spinlock_unlock( &page->lock );180 181 // deschedule the calling thread182 thread_block( XPTR( local_cxy , thread ) , THREAD_BLOCKED_PAGE );183 sched_yield("cannot lock a page");184 }185 else // page is not locked186 {187 // set the PG_LOCKED flag188 page_set_flag( page , PG_LOCKED );189 190 // release the spinlock191 spinlock_unlock( &page->lock );192 }193 }194 195 /////////////////////////////////196 void page_unlock( page_t * page )197 {198 // take the spinlock protecting the PG_LOCKED flag199 spinlock_lock( &page->lock );200 201 // check the page waiting list202 bool_t is_empty = xlist_is_empty( XPTR( local_cxy , &page->wait_root ) );203 204 if( is_empty == false ) // at least one waiting thread => resume it205 {206 // get an extended pointer on the first waiting thread207 xptr_t root_xp = XPTR( local_cxy , &page->wait_root );208 xptr_t thread_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );209 210 // reactivate the first waiting thread211 thread_unblock( thread_xp , THREAD_BLOCKED_PAGE );212 }213 else // no waiting thread => clear the PG_LOCKED flag214 {215 page_clear_flag( page , PG_LOCKED );216 }217 218 // release the spinlock219 spinlock_unlock( &page->lock );220 71 } 221 72
Note: See TracChangeset
for help on using the changeset viewer.