diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-05-13 15:35:42 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-04-17 14:06:45 +0200 |
commit | 8c050fb080c6e1981dc8e5a97a2313cd24e9b4b4 (patch) | |
tree | 1fc940c6bf92a3de8a5ce0d60a687979d067d447 /tmpfs/tmpfs.h | |
parent | f4823c00581eb91e5b42169405e641463256bbfa (diff) |
tmpfs: use a seperate lock to protect all_nodes
Previously, tmpfs used diskfs_node_refcnt_lock to serialize access to
the all_nodes and some other related global state related to memory
consumption.
Use a separate lock to protect all_nodes, and atomic operations to
access the state related to memory consumption. Adjust the reference
counting accordingly. Every node in the all_nodes carries a light
reference. When we are asked to give up that light reference, we
reacquire our lock momentarily to check whether someone else
reacquired a reference through the all_nodes.
* tmpfs/tmpfs.h (num_files, tmpfs_space_used): Use atomic operations
for these variables.
(adjust_used): Use atomic operations.
(get_used): New convenience function to atomically retrieve
tmpfs_space_used.
* tmpfs/node.c (all_nodes_lock): New lock.
(diskfs_alloc_node): Use a separate lock to protect all_nodes.
Adjust the reference counting accordingly.
(diskfs_free_node): Likewise.
(diskfs_cached_lookup):Likewise.
(diskfs_node_iterate): Likewise.
(diskfs_node_norefs): Do not remove the node from all_nodes. This
actually looks like a mistake, I do not know why they did that here as
well as in diskfs_free_node.
(diskfs_try_dropping_softrefs): Check whether someone reacquired a
reference, and if so hold on to our light reference.
(diskfs_grow): Use atomic operations.
* tmpfs/tmpfs.c (diskfs_set_statfs): Likewise.
Diffstat (limited to 'tmpfs/tmpfs.h')
-rw-r--r-- | tmpfs/tmpfs.h | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/tmpfs/tmpfs.h b/tmpfs/tmpfs.h index b3c636d0..ad472009 100644 --- a/tmpfs/tmpfs.h +++ b/tmpfs/tmpfs.h @@ -69,17 +69,25 @@ struct tmpfs_dirent char name[0]; }; -extern unsigned int num_files; -extern off_t tmpfs_page_limit, tmpfs_space_used; - +extern off_t tmpfs_page_limit; extern mach_port_t default_pager; +/* These two must be accessed using atomic operations. */ +extern unsigned int num_files; +extern off_t tmpfs_space_used; + +/* Convenience function to adjust tmpfs_space_used. */ static inline void adjust_used (off_t change) { - pthread_spin_lock (&diskfs_node_refcnt_lock); - tmpfs_space_used += change; - pthread_spin_unlock (&diskfs_node_refcnt_lock); + __atomic_add_fetch (&num_files, change, __ATOMIC_RELAXED); +} + +/* Convenience function to get tmpfs_space_used. */ +static inline off_t +get_used (void) +{ + return __atomic_load_n (&num_files, __ATOMIC_RELAXED); } #endif |