- Timestamp:
- Jun 3, 2017, 6:58:06 PM (8 years ago)
- Location:
- trunk/kernel/mm
- Files:
-
- 2 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 -
trunk/kernel/mm/page.h
r18 r22 88 88 89 89 /************************************************************************************* 90 * This function set one or several flags in page descriptor flags.90 * This function sets one or several flags in page descriptor flags. 91 91 * @ page : pointer to page descriptor. 92 92 * @ value : all non zero bits in value will be set. … … 96 96 97 97 /************************************************************************************* 98 * This function resetone or several flags in page descriptor flags.98 * This function clears one or several flags in page descriptor flags. 99 99 * @ page : pointer to page descriptor. 100 100 * @ value : all non zero bits in value will be cleared. … … 104 104 105 105 /************************************************************************************* 106 * This function test the value of one or several flags in page descriptor flags.106 * This function tests the value of one or several flags in page descriptor flags. 107 107 * @ page : pointer to page descriptor. 108 108 * @ value : all non zero bits will be tested. … … 114 114 /************************************************************************************* 115 115 * This function synchronizes (i.e. update the disk) all dirty pages in a cluster. 116 * It scan the PPM dirty list, that should be empty when this operation is completed.116 * It scans the PPM dirty list, that should be empty when this operation is completed. 117 117 ************************************************************************************/ 118 118 void sync_all_pages(); 119 119 120 120 /************************************************************************************* 121 * This function set the PG_DIRTY flag in the page descriptor,122 * and register the page in the dirty list in PPM.121 * This function sets the PG_DIRTY flag in the page descriptor, 122 * and registers the page in the dirty list in PPM. 123 123 * @ page : pointer on page descriptor. 124 124 * @ returns true if page was not dirty / returns false if page was dirty … … 127 127 128 128 /************************************************************************************* 129 * This function reset the PG_DIRTY flag in the page descriptor,130 * and remove the page from the dirty list in PPM.129 * This function resets the PG_DIRTY flag in the page descriptor, 130 * and removes the page from the dirty list in PPM. 131 131 * @ page : pointer on page descriptor. 132 132 * @ returns true if page was dirty / returns false if page was not dirty … … 135 135 136 136 /************************************************************************************* 137 * This function makes a local copy of the content of a src page 137 * This function makes a local copy of the content of a src page to a dst page. 138 138 * @ dst : pointer on destination page descriptor. 139 139 * @ src : pointer on source page descriptor. … … 143 143 144 144 /************************************************************************************* 145 * This function reset to 0 all bytes in a given page.145 * This function resets to 0 all bytes in a given page. 146 146 * @ page : pointer on page descriptor. 147 147 ************************************************************************************/ … … 157 157 158 158 /************************************************************************************* 159 * This blocking function reset the PG_LOCKED flag on the page, if there is no160 * other waiting thread. I Fthere is waiting thread(s), it activates the first159 * This blocking function resets the PG_LOCKED flag on the page, if there is no 160 * other waiting thread. If there is waiting thread(s), it activates the first 161 161 * waiting thread without modifying the PG_LOCKED flag. 162 162 * @ page : pointer on page descriptor. … … 165 165 166 166 /************************************************************************************* 167 * This blocking function atomically increment the page refcount.167 * This blocking function atomically increments the page refcount. 168 168 * @ page : pointer on page descriptor. 169 169 ************************************************************************************/ … … 171 171 172 172 /************************************************************************************* 173 * This blocking function atomically decrement the page refcount.173 * This blocking function atomically decrements the page refcount. 174 174 * @ page : pointer on page descriptor. 175 175 ************************************************************************************/
Note: See TracChangeset
for help on using the changeset viewer.