From c3f9932330e1803d9c7373ca3db69557b716f359 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Sat, 21 Feb 2015 00:54:05 +0100 Subject: [PATCH gnumach 2/3] xxx vm_page_queue_clean --- vm/vm_page.h | 27 +++++++++++++++++++++++++-- vm/vm_resident.c | 5 +++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/vm/vm_page.h b/vm/vm_page.h index 4fe1b41..6d2dbd9 100644 --- a/vm/vm_page.h +++ b/vm/vm_page.h @@ -70,8 +70,10 @@ * and sundry status bits. * * Fields in this structure are locked either by the lock on the - * object that the page belongs to (O) or by the lock on the page - * queues (P). [Some fields require that both locks be held to + * object that the page belongs to (O), by the lock on the page + * queues (P), or by vm_page_queue_clean_lock (C). + * + * [Some fields require that both locks, O and P, be held to * change that field; holding either lock is sufficient to read.] */ @@ -79,6 +81,7 @@ struct vm_page { queue_chain_t pageq; /* queue info for FIFO * queue or free list (P) */ queue_chain_t listq; /* all pages in same object (O) */ + queue_chain_t cleanq; /* all clean pages (C) */ struct vm_page *next; /* VP bucket link (O) */ vm_object_t object; /* which object am I in (O,P) */ @@ -147,6 +150,8 @@ extern queue_head_t vm_page_queue_active; /* active memory queue */ extern queue_head_t vm_page_queue_inactive; /* inactive memory queue */ +extern +queue_head_t vm_page_queue_clean; /* clean memory queue */ extern int vm_page_free_count; /* How many pages are free? */ @@ -184,6 +189,8 @@ decl_simple_lock_data(extern,vm_page_queue_lock)/* lock on active and inactive page queues */ decl_simple_lock_data(extern,vm_page_queue_free_lock) /* lock on free page queue */ +decl_simple_lock_data(extern,vm_page_queue_clean_lock) + /* lock on clean page queue */ extern unsigned int vm_page_free_wanted; /* how many threads are waiting for memory */ @@ -312,4 +319,20 @@ extern unsigned int vm_page_info( } \ MACRO_END +static inline void +vm_page_mark_dirty (vm_page_t m, boolean_t dirty) +{ + if (m->dirty == dirty) + return; + + simple_lock (&vm_page_queue_clean_lock); + if (dirty && m->cleanq.next) { + queue_remove (&vm_page_queue_clean, m, vm_page_t, cleanq); + m->cleanq.next = NULL; + } + if (! dirty) + queue_enter (&vm_page_queue_clean, m, vm_page_t, cleanq); + simple_unlock (&vm_page_queue_clean_lock); +} + #endif /* _VM_VM_PAGE_H_ */ diff --git a/vm/vm_resident.c b/vm/vm_resident.c index 92b2397..49ef148 100644 --- a/vm/vm_resident.c +++ b/vm/vm_resident.c @@ -148,6 +148,8 @@ vm_offset_t vm_page_fictitious_addr = (vm_offset_t) -1; queue_head_t vm_page_queue_active; queue_head_t vm_page_queue_inactive; decl_simple_lock_data(,vm_page_queue_lock) +queue_head_t vm_page_queue_clean; +decl_simple_lock_data(,vm_page_queue_clean_lock) int vm_page_active_count; int vm_page_inactive_count; int vm_page_wire_count; @@ -200,6 +202,7 @@ void vm_page_bootstrap( */ m = &vm_page_template; + m->cleanq.next = NULL; m->object = VM_OBJECT_NULL; /* reset later */ m->offset = 0; /* reset later */ m->wire_count = 0; @@ -231,12 +234,14 @@ void vm_page_bootstrap( */ simple_lock_init(&vm_page_queue_free_lock); + simple_lock_init(&vm_page_queue_clean_lock); simple_lock_init(&vm_page_queue_lock); vm_page_queue_free = VM_PAGE_NULL; vm_page_queue_fictitious = VM_PAGE_NULL; queue_init(&vm_page_queue_active); queue_init(&vm_page_queue_inactive); + queue_init(&vm_page_queue_clean); vm_page_free_wanted = 0; -- 2.1.4