summaryrefslogtreecommitdiff
path: root/libhurd-mm/anonymous.c
diff options
context:
space:
mode:
authorneal <neal>2007-11-27 15:33:31 +0000
committerneal <neal>2007-11-27 15:33:31 +0000
commitd6f5f00a87b6d0d9667715988ddfb7384dceefc2 (patch)
tree3b149b2a811163cd8fad3dce4d02da30901074b7 /libhurd-mm/anonymous.c
parentc744a56f1aad390e22ff14b21eb8d1a259ac861c (diff)
2007-11-27 Neal H. Walfield <neal@gnu.org>
* as.c: Include <pthread.h>. Remove dead code. (free_spaces_lock): New variable. (free_space_split): Assert that it is held. (as_alloc): Make thread-safe. (as_alloc_at): Likewise. (as_free): Likewise. (as_alloced_dump): Likewise. * storage.c: Include <pthread.h> and <atomic.h>. (free_count): Make a uatomic32_t, rather than an int. Update users to access it using atomic operations. (struct storage_desc): New field, lock. (storage_descs_lock): New global variable. (link): Assert that STORAGE_DESCS_LOCK is held. (unlink): Likewise. Don't assert that E->NEXT is NULL, which is valid. (slab_space_reserve): Make an atomicptr_t, rather than a void *. Update users to access it using atomic operations. (check_slab_space_reserve): Rewrite function to be thread-safe. (storage_desc_free): Assert that STORAGE_DESCS_LOCK is held. (storage_alloc): Rewrite function to be thread-safe. (storage_free): Likewise. (storage_init): Take STORAGE_DESCS_LOCK. Initialize SDESC->LOCK. * capalloc.c: Include <pthread.h>. (struct cappage_desc): New field, lock. (unlink): Don't assert E->NEXT. (cappage_descs_lock): New variable. (capalloc): Make thread safe. (capfree): Likewise. * pager.h: Include <pthread.h>. (pager_fault_t): Note that PAGER->LOCK will be held. (struct pager): New field, lock. (pagers_lock): New declaration. (pager_install): Note locking requirements. (pager_relocate): Likewise. (pager_deinstall): Likewise. * pager.c (pagers_lock): New definition. (pager_install): Add asserts. (pager_relocate): Likewise. (pager_deinstall): Likewise. (pager_fault): Likewise. Make function thread-safe. * anonymous.c (struct storage_desc): Add comment about locking. (fault): Add assert. (anonymous_pager_alloc): Take PAGERS_LOCK before calling pager_install and drop it afterwards. (anonymous_pager_destroy): Take PAGERS_LOCK before calling pager_deinstall and drop it afterwards. Take ANON->PAGER.LOCK.
Diffstat (limited to 'libhurd-mm/anonymous.c')
-rw-r--r--libhurd-mm/anonymous.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/libhurd-mm/anonymous.c b/libhurd-mm/anonymous.c
index 07a5a15..d4f7b78 100644
--- a/libhurd-mm/anonymous.c
+++ b/libhurd-mm/anonymous.c
@@ -34,6 +34,7 @@
#define DISCARDABLE(a) ((a)->flags & ANONYMOUS_DISCARDABLE)
+/* All fields are protected by the pager's lock. */
struct storage_desc
{
hurd_btree_node_t node;
@@ -131,6 +132,8 @@ static bool
fault (struct pager *pager,
addr_t addr, uintptr_t ip, struct exception_info info)
{
+ assert (pthread_mutex_trylock (&pager->lock) == EBUSY);
+
struct anonymous_pager *anon = (struct anonymous_pager *) pager;
addr_t page;
@@ -209,7 +212,9 @@ anonymous_pager_alloc (addr_t activity,
anon->pager.region.start = addr_chop (PTR_TO_ADDR (addr), PAGESIZE_LOG2);
anon->pager.region.count = size >> PAGESIZE_LOG2;
+ pthread_mutex_lock (&pagers_lock);
bool r = pager_install (&anon->pager);
+ pthread_mutex_unlock (&pagers_lock);
if (! r)
/* Ooops! There is a region conflict. */
{
@@ -223,9 +228,15 @@ anonymous_pager_alloc (addr_t activity,
void
anonymous_pager_destroy (struct anonymous_pager *anon)
{
+ pthread_mutex_lock (&pagers_lock);
+
/* Deinstall the pager. */
pager_deinstall (&anon->pager);
+ pthread_mutex_unlock (&pagers_lock);
+
+ pthread_mutex_lock (&anon->pager.lock);
+
/* Free the allocated storage. */
hurd_btree_storage_desc_t *storage_descs;
storage_descs = (hurd_btree_storage_desc_t *) &anon->storage;
@@ -239,6 +250,8 @@ anonymous_pager_destroy (struct anonymous_pager *anon)
storage_desc_free (node);
}
+ /* There is no need to unlock &anon->pager.lock: we free it. */
+
/* And free its storage. */
hurd_slab_dealloc (&anonymous_pager_slab, anon);
}