Changeset 22 for trunk/kernel/mm/page.c
- Timestamp:
- Jun 3, 2017, 6:58:06 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/page.c
r18 r22 39 39 #include <page.h> 40 40 41 42 43 41 //////////////////////////////////////// 44 42 inline void page_init( page_t * page ) … … 49 47 page->mapper = NULL; 50 48 page->private = 0; 51 49 page->refcount = 0; 52 50 spinlock_init( &page->lock ); 53 51 list_entry_init( &page->list ); … … 58 56 uint16_t value ) 59 57 { 60 58 hal_atomic_or( (uint32_t *)&page->flags , (uint32_t)value ); 61 59 } 62 60 … … 65 63 uint16_t value ) 66 64 { 67 65 hal_atomic_and( (uint32_t *)&page->flags , ~((uint32_t)value) ); 68 66 } 69 67 … … 72 70 uint16_t value ) 73 71 { 74 72 return (bool_t)(page->flags & value); 75 73 } 76 74 … … 80 78 bool_t done = false; 81 79 82 83 84 80 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 81 82 // lock the PPM dirty_list 85 83 spinlock_lock( &ppm->dirty_lock ); 86 84 87 85 if( !page_is_flag( page , PG_DIRTY ) ) 88 86 { 89 87 // set dirty flag in page descriptor 90 88 page_set_flag( page , PG_DIRTY ); 91 89 92 90 // register page in PPM dirty list 93 91 list_add_first( &ppm->dirty_root , &page->list ); 94 92 done = true; 95 93 } 96 94 97 95 // unlock the PPM dirty_list 98 96 spinlock_unlock( &ppm->dirty_lock ); 99 97 … … 106 104 bool_t done = false; 107 105 108 109 110 106 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 107 108 // lock the dirty_list 111 109 spinlock_lock( &ppm->dirty_lock ); 112 110 113 111 if( page_is_flag( page , PG_DIRTY) ) 114 112 { 115 113 // clear dirty flag in page descriptor 116 114 page_clear_flag( page , PG_DIRTY ); 117 115 118 116 // remove page from PPM dirty list 119 117 list_unlink( &page->list ); 120 118 done = true; 121 119 } 122 120 123 121 // unlock the dirty_list 124 122 spinlock_unlock( &ppm->dirty_lock ); 125 123 … … 132 130 page_t * page; 133 131 mapper_t * mapper; 134 135 136 137 132 uint32_t index; 133 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 134 135 // lock the dirty_list 138 136 spinlock_lock( &ppm->dirty_lock ); 139 137 … … 142 140 page = LIST_FIRST( &ppm->dirty_root , page_t , list ); 143 141 144 145 142 // unlock the dirty_list 143 spinlock_unlock( &ppm->dirty_lock ); 146 144 147 145 mapper = page->mapper; 148 149 150 146 index = page->index; 147 148 // lock the page 151 149 page_lock( page ); 152 150 153 151 // sync the page 154 152 mapper_sync_page( mapper , index , page ); 155 153 156 154 // unlock the page 157 155 page_unlock( page ); 158 156 159 160 161 } 162 163 157 // lock the dirty_list 158 spinlock_lock( &ppm->dirty_lock ); 159 } 160 161 // unlock the dirty_list 164 162 spinlock_unlock( &ppm->dirty_lock ); 165 163 166 } // end sync_all_pages()164 } 167 165 168 166 /////////////////////////////// 169 167 void page_lock( page_t * page ) 170 168 { 171 169 // take the spinlock protecting the PG_LOCKED flag 172 170 spinlock_lock( &page->lock ); 173 171 174 172 if( page_is_flag( page , PG_LOCKED ) ) // page is already locked 175 173 { 176 177 178 179 180 181 182 183 174 // get pointer on calling thread 175 thread_t * thread = CURRENT_THREAD; 176 177 // register thread in the page waiting queue 178 xlist_add_last( XPTR( local_cxy , &page->wait_root ), 179 XPTR( local_cxy , &thread->wait_list ) ); 180 181 // release the spinlock 184 182 spinlock_unlock( &page->lock ); 185 183 186 187 184 // deschedule the calling thread 185 thread_block( thread , THREAD_BLOCKED_PAGE ); 188 186 sched_yield(); 189 187 } 190 188 else // page is not locked 191 189 { 192 190 // set the PG_LOCKED flag 193 191 page_set_flag( page , PG_LOCKED ); 194 192 195 193 // release the spinlock 196 194 spinlock_unlock( &page->lock ); 197 195 } … … 201 199 void page_unlock( page_t * page ) 202 200 { 203 201 // take the spinlock protecting the PG_LOCKED flag 204 202 spinlock_lock( &page->lock ); 205 203 206 204 // check the page waiting list 207 205 bool_t is_empty = xlist_is_empty( XPTR( local_cxy , &page->wait_root ) ); 208 206 209 207 if( is_empty == false ) // at least one waiting thread => resume it 210 211 212 213 214 215 216 217 208 { 209 // get an extended pointer on the first waiting thread 210 xptr_t root_xp = XPTR( local_cxy , &page->wait_root ); 211 xptr_t thread_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list ); 212 213 // reactivate the first waiting thread 214 thread_unblock( thread_xp , THREAD_BLOCKED_PAGE ); 215 } 218 216 else // no waiting thread => clear the PG_LOCKED flag 219 217 { 220 221 222 223 218 page_clear_flag( page , PG_LOCKED ); 219 } 220 221 // release the spinlock 224 222 spinlock_unlock( &page->lock ); 225 223 } … … 228 226 inline void page_refcount_up( page_t *page ) 229 227 { 230 228 hal_atomic_inc( &page->refcount ); 231 229 } 232 230 … … 234 232 inline void page_refcount_down( page_t *page ) 235 233 { 236 234 hal_atomic_dec( &page->refcount ); 237 235 } 238 236 … … 246 244 247 245 if( dst->order != src->order ) 248 249 250 251 246 { 247 printk("\n[PANIC] in %s : src size != dst size\n", __FUNCTION__ ); 248 hal_core_sleep(); 249 } 252 250 253 251 size = (1 << dst->order) * CONFIG_PPM_PAGE_SIZE; … … 289 287 } 290 288 291 292 293 294 295
Note: See TracChangeset
for help on using the changeset viewer.