diff options
author | neal <neal> | 2008-07-04 09:01:05 +0000 |
---|---|---|
committer | neal <neal> | 2008-07-04 09:01:05 +0000 |
commit | 326bc8dd2af1af31f49dde75f86a38379533f8ce (patch) | |
tree | 8bf0296aa7f6ffa5556014c84a47a772aa14429d /libhurd-mm | |
parent | dbe6fd98d3e073fce2225680bb67cd8313a5dbf5 (diff) |
2008-07-04 Neal H. Walfield <neal@gnu.org>
* as-lookup.c: Don't include <pthread.h>.
(as_rwlock): Don't define here.
* as.c: Include <pthread.h>.
(as_rwlock): Define.
(as_rwlock_owner): Likewise.
* as.h: Include <l4/types.h>.
(as_lock): Check and set as_rwlock_owner appropriately.
(as_lock_readonly): Likewise.
(as_unlock): Likewise.
* storage.c (do_serialize): New local variable.
(storage_check_reserve_internal): If AS_RWLOCK_OWNER is non-zero,
check if the caller has the AS_RWLOCK. If so, return. If
DO_SERIALIZE is set or FREE_COUNT is less than
FREE_PAGES_SERIALIZE, take the STORAGE_LOW_MUTEX. If DO_SERIALIZE
was not set, set it and remember that we set it and clear it after
allocating a folio.
Diffstat (limited to 'libhurd-mm')
-rw-r--r-- | libhurd-mm/ChangeLog | 19 | ||||
-rw-r--r-- | libhurd-mm/as-lookup.c | 5 | ||||
-rw-r--r-- | libhurd-mm/as.c | 27 | ||||
-rw-r--r-- | libhurd-mm/as.h | 44 | ||||
-rw-r--r-- | libhurd-mm/storage.c | 88 |
5 files changed, 111 insertions, 72 deletions
diff --git a/libhurd-mm/ChangeLog b/libhurd-mm/ChangeLog index 2af49e9..3f2b434 100644 --- a/libhurd-mm/ChangeLog +++ b/libhurd-mm/ChangeLog @@ -1,3 +1,22 @@ +2008-07-04 Neal H. Walfield <neal@gnu.org> + + * as-lookup.c: Don't include <pthread.h>. + (as_rwlock): Don't define here. + * as.c: Include <pthread.h>. + (as_rwlock): Define. + (as_rwlock_owner): Likewise. + * as.h: Include <l4/types.h>. + (as_lock): Check and set as_rwlock_owner appropriately. + (as_lock_readonly): Likewise. + (as_unlock): Likewise. + * storage.c (do_serialize): New local variable. + (storage_check_reserve_internal): If AS_RWLOCK_OWNER is non-zero, + check if the caller has the AS_RWLOCK. If so, return. If + DO_SERIALIZE is set or FREE_COUNT is less than + FREE_PAGES_SERIALIZE, take the STORAGE_LOW_MUTEX. If DO_SERIALIZE + was not set, set it and remember that we set it and clear it after + allocating a folio. + 2008-07-01 Neal H. Walfield <neal@gnu.org> * as-dump.c [RM_INTERN]: Include <md5.h>, "../viengoos/cap.h" and diff --git a/libhurd-mm/as-lookup.c b/libhurd-mm/as-lookup.c index a5c0bdd..1a9fc31 100644 --- a/libhurd-mm/as-lookup.c +++ b/libhurd-mm/as-lookup.c @@ -30,11 +30,6 @@ #include "../viengoos/profile.h" #endif -#ifndef RM_INTERN -# include <pthread.h> -pthread_rwlock_t as_rwlock; -#endif - #ifdef RM_INTERN #include "../viengoos/object.h" #endif diff --git a/libhurd-mm/as.c b/libhurd-mm/as.c index 9147323..f8b5d25 100644 --- a/libhurd-mm/as.c +++ b/libhurd-mm/as.c @@ -5,23 +5,23 @@ This file is part of the GNU Hurd. The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. - The GNU Hurd is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see + <http://www.gnu.org/licenses/>. */ #include "as.h" #include "storage.h" +#include <pthread.h> #include <hurd/folio.h> #include <hurd/cap.h> #include <hurd/btree.h> @@ -44,6 +44,9 @@ extern struct hurd_startup_data *__hurd_startup_data; /* Set to true before as_init returns. Indicates that the shadow page table structures may be used, etc. */ bool as_init_done; + +pthread_rwlock_t as_rwlock; +l4_thread_id_t as_rwlock_owner; /* We keep track of the regions which are unallocated. These regions are kept in a btree allowing for fast allocation, fast searching @@ -276,8 +279,8 @@ as_free (addr_t addr, l4_uint64_t count) free_space_desc_free (space); assertx (f->region.end + 1 == start || end + 1 == f->region.start, - "%llx != %llx || %llx != %llx", - f->region.end + 1, start, end + 1, f->region.start); + "Freeing %llx-%llx, but overlaps with free region %llx-%llx! ", + f->region.start, f->region.end + 1, start, end + 1); struct free_space *prev; struct free_space *next; diff --git a/libhurd-mm/as.h b/libhurd-mm/as.h index 0d0dca8..0d4d48b 100644 --- a/libhurd-mm/as.h +++ b/libhurd-mm/as.h @@ -26,6 +26,7 @@ #include <hurd/cap.h> #include <hurd/exceptions.h> #include <stdbool.h> +#include <l4/types.h> /* The address space allocator keeps track of which addresses are allocated and which are available. The allocator supports the @@ -101,6 +102,7 @@ static inline void as_lock (void) { extern pthread_rwlock_t as_rwlock; + extern l4_thread_id_t as_rwlock_owner; as_lock_ensure_stack (EXCEPTION_STACK_SIZE - PAGESIZE); @@ -108,10 +110,14 @@ as_lock (void) for (;;) { + assert (as_rwlock_owner != l4_myself ()); pthread_rwlock_wrlock (&as_rwlock); + assert (as_rwlock_owner == 0); + as_rwlock_owner = l4_myself (); if (! storage_have_reserve ()) { + as_rwlock_owner = 0; pthread_rwlock_unlock (&as_rwlock); storage_check_reserve (false); @@ -125,6 +131,7 @@ static inline void as_lock_readonly (void) { extern pthread_rwlock_t as_rwlock; + extern l4_thread_id_t as_rwlock_owner; as_lock_ensure_stack (EXCEPTION_STACK_SIZE - PAGESIZE); @@ -132,7 +139,9 @@ as_lock_readonly (void) for (;;) { + assert (as_rwlock_owner != l4_myself ()); pthread_rwlock_rdlock (&as_rwlock); + assert (as_rwlock_owner == 0); if (! storage_have_reserve ()) { @@ -149,6 +158,14 @@ static inline void as_unlock (void) { extern pthread_rwlock_t as_rwlock; + extern l4_thread_id_t as_rwlock_owner; + + if (as_rwlock_owner) + /* Only set for a write lock. */ + { + assert (as_rwlock_owner == l4_myself ()); + as_rwlock_owner = 0; + } pthread_rwlock_unlock (&as_rwlock); } @@ -189,22 +206,19 @@ extern struct cap shadow_root; &__acs_type, &__acs_p); \ \ bool die = false; \ - if (! (! __acs_err \ - && ((__acs_type == (__acs_cap)->type \ - && __acs_p.addr_trans.raw == (__acs_cap)->addr_trans.raw \ - && __acs_p.policy.priority == (__acs_cap)->priority \ + if (__acs_err) \ + die = true; \ + else if (__acs_type == cap_void) \ + /* The kernel's type is void. Either the shadow has not yet \ + been updated or the object is dead. */ \ + ; \ + else if (__acs_type != (__acs_cap)->type) \ + die = true; \ + else if (! (__acs_p.policy.priority == (__acs_cap)->priority \ && (!!__acs_p.policy.discardable \ - == !!(__acs_cap)->discardable)) \ - /* It's okay if the cap's type is void and the kernel's \ - type somethine else as long as the guard matches. \ - This means that the object has been inserted but the \ - shadow not yet updated, which is not required to be \ - atomic. */ \ - || (((__acs_cap)->type == cap_void \ - && (CAP_ADDR_TRANS_GUARD (__acs_p.addr_trans) \ - == CAP_GUARD (__acs_cap)) \ - && (CAP_ADDR_TRANS_GUARD_BITS (__acs_p.addr_trans) \ - == CAP_GUARD_BITS (__acs_cap))))))) \ + == !!(__acs_cap)->discardable))) \ + die = true; \ + else if (__acs_p.addr_trans.raw != (__acs_cap)->addr_trans.raw) \ die = true; \ \ if (die) \ diff --git a/libhurd-mm/storage.c b/libhurd-mm/storage.c index 0aeb46e..ba6b914 100644 --- a/libhurd-mm/storage.c +++ b/libhurd-mm/storage.c @@ -5,19 +5,18 @@ This file is part of the GNU Hurd. The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. - The GNU Hurd is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see + <http://www.gnu.org/licenses/>. */ #include "storage.h" @@ -343,6 +342,8 @@ storage_have_reserve (void) return likely (free_count > FREE_PAGES_LOW_WATER); } +static bool do_serialize; + static void storage_check_reserve_internal (bool force_allocate, addr_t activity, @@ -368,15 +369,32 @@ storage_check_reserve_internal (bool force_allocate, pages and if not to call some as-yet unwritten function which forces the reserve to grow. */ { - extern pthread_rwlock_t as_rwlock; - if (pthread_rwlock_trywrlock (&as_rwlock) == EBUSY) - return; + extern l4_thread_id_t as_rwlock_owner; + if (as_rwlock_owner) + { + if (as_rwlock_owner == l4_myself ()) + /* This thread has the lock. */ + return; + } + else + /* AS_RWLOCK_OWNER is 0. Either the lock is not held or its + held read-only. See if we can get a write lock. If so, + its the former. */ + { + extern pthread_rwlock_t as_rwlock; + if (pthread_rwlock_trywrlock (&as_rwlock) == EBUSY) + /* Conservatively assume that we have the lock. */ + return; - pthread_rwlock_unlock (&as_rwlock); + pthread_rwlock_unlock (&as_rwlock); + } + + i_may_have_lock = false; } bool have_lock = false; - if (free_count < FREE_PAGES_SERIALIZE) + bool did_serialize = false; + if (do_serialize || free_count < FREE_PAGES_SERIALIZE) { if (pthread_mutex_trylock (&storage_low_mutex) == EBUSY) /* Someone else is in. */ @@ -388,34 +406,17 @@ storage_check_reserve_internal (bool force_allocate, goto top; } + if (! do_serialize) + { + do_serialize = true; + did_serialize = true; + } + have_lock = true; } if (free_count == 0) - { - extern pthread_rwlock_t as_rwlock; - - int tries; - for (tries = 0; ; tries ++) - if (pthread_rwlock_trywrlock (&as_rwlock) == EBUSY) - { - int i; - for (i = 0; i < 10000; i ++) - l4_yield (); - - if (tries == 10) - { - debug (0, DEBUG_BOLD ("Free count is zero and it seems " - "that I have the as_rwlock!")); - break; - } - } - else - { - pthread_rwlock_unlock (&as_rwlock); - break; - } - } + debug (0, "free_count is zero."); debug (3, "Allocating additional folio, free count: %d", free_count); @@ -495,7 +496,14 @@ storage_check_reserve_internal (bool force_allocate, check_slab_space_reserve (); if (have_lock) - pthread_mutex_unlock (&storage_low_mutex); + { + if (did_serialize) + { + assert (do_serialize); + do_serialize = false; + } + pthread_mutex_unlock (&storage_low_mutex); + } } void |