summaryrefslogtreecommitdiff
path: root/libhurd-mm
diff options
context:
space:
mode:
authorneal <neal>2008-07-04 09:01:05 +0000
committerneal <neal>2008-07-04 09:01:05 +0000
commit326bc8dd2af1af31f49dde75f86a38379533f8ce (patch)
tree8bf0296aa7f6ffa5556014c84a47a772aa14429d /libhurd-mm
parentdbe6fd98d3e073fce2225680bb67cd8313a5dbf5 (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/ChangeLog19
-rw-r--r--libhurd-mm/as-lookup.c5
-rw-r--r--libhurd-mm/as.c27
-rw-r--r--libhurd-mm/as.h44
-rw-r--r--libhurd-mm/storage.c88
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