1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
From d58f0ac175e0506a9e76e4197497be20337e444d Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Tue, 6 May 2014 18:58:10 +0200
Subject: [PATCH 06/16] libdiskfs: lock-less reference counting for peropen
objects
* libdiskfs/diskfs.h (struct peropen): Use refcount_t for field refcnt.
* libdiskfs/peropen-make.c (diskfs_make_peropen): Initialize refcnt.
* libdiskfs/peropen-rele.c (diskfs_release_peropen): Adjust accordingly.
* libdiskfs/protid-make.c (diskfs_start_protid): Likewise. Also, the
node must no longer be locked, adjust comment accordingly.
(diskfs_create_protid): Likewise.
---
libdiskfs/diskfs.h | 7 ++++---
libdiskfs/peropen-make.c | 2 +-
libdiskfs/peropen-rele.c | 21 ++++++++++-----------
libdiskfs/protid-make.c | 8 ++++----
4 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index a3f860d..acd1910 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -28,6 +28,7 @@
#include <hurd/iohelp.h>
#include <idvec.h>
#include <features.h>
+#include <refcount.h>
#ifdef DISKFS_DEFINE_EXTERN_INLINE
#define DISKFS_EXTERN_INLINE
@@ -57,7 +58,7 @@ struct peropen
{
int filepointer;
int lock_status;
- int refcnt;
+ refcount_t refcnt;
int openstat;
struct node *np;
@@ -817,12 +818,12 @@ diskfs_create_node (struct node *dir, const char *name, mode_t mode,
struct dirstat *ds);
/* Create and return a protid for an existing peropen PO in CRED,
- referring to user USER. The node PO->np must be locked. */
+ referring to user USER. */
error_t diskfs_create_protid (struct peropen *po, struct iouser *user,
struct protid **cred);
/* Build and return in CRED a protid which has no user identification, for
- peropen PO. The node PO->np must be locked. */
+ peropen PO. */
error_t diskfs_start_protid (struct peropen *po, struct protid **cred);
/* Finish building protid CRED started with diskfs_start_protid;
diff --git a/libdiskfs/peropen-make.c b/libdiskfs/peropen-make.c
index eba037f..6d5ca01 100644
--- a/libdiskfs/peropen-make.c
+++ b/libdiskfs/peropen-make.c
@@ -31,7 +31,7 @@ diskfs_make_peropen (struct node *np, int flags, struct peropen *context,
po->filepointer = 0;
po->lock_status = LOCK_UN;
- po->refcnt = 0;
+ refcount_init (&po->refcnt, 0);
po->openstat = flags;
po->np = np;
po->path = NULL;
diff --git a/libdiskfs/peropen-rele.c b/libdiskfs/peropen-rele.c
index d3f7492..877137b 100644
--- a/libdiskfs/peropen-rele.c
+++ b/libdiskfs/peropen-rele.c
@@ -22,13 +22,8 @@
void
diskfs_release_peropen (struct peropen *po)
{
- pthread_mutex_lock (&po->np->lock);
-
- if (--po->refcnt)
- {
- pthread_mutex_unlock (&po->np->lock);
- return;
- }
+ if (refcount_deref (&po->refcnt) > 0)
+ return;
if (po->root_parent)
mach_port_deallocate (mach_task_self (), po->root_parent);
@@ -40,10 +35,14 @@ diskfs_release_peropen (struct peropen *po)
mach_port_deallocate (mach_task_self (), po->shadow_root_parent);
if (po->lock_status != LOCK_UN)
- fshelp_acquire_lock (&po->np->userlock, &po->lock_status,
- &po->np->lock, LOCK_UN);
-
- diskfs_nput (po->np);
+ {
+ pthread_mutex_lock (&po->np->lock);
+ fshelp_acquire_lock (&po->np->userlock, &po->lock_status,
+ &po->np->lock, LOCK_UN);
+ diskfs_nput (po->np);
+ }
+ else
+ diskfs_nrele (po->np);
free (po->path);
free (po);
diff --git a/libdiskfs/protid-make.c b/libdiskfs/protid-make.c
index b39b92a..22aaa2e 100644
--- a/libdiskfs/protid-make.c
+++ b/libdiskfs/protid-make.c
@@ -20,7 +20,7 @@
#include <assert.h>
/* Build and return in CRED a protid which has no user identification, for
- peropen PO. The node PO->np must be locked. */
+ peropen PO. */
error_t
diskfs_start_protid (struct peropen *po, struct protid **cred)
{
@@ -29,7 +29,7 @@ diskfs_start_protid (struct peropen *po, struct protid **cred)
sizeof (struct protid), cred);
if (! err)
{
- po->refcnt++;
+ refcount_ref (&po->refcnt);
(*cred)->po = po;
(*cred)->shared_object = MACH_PORT_NULL;
(*cred)->mapped = 0;
@@ -55,8 +55,8 @@ diskfs_finish_protid (struct protid *cred, struct iouser *user)
assert_perror (err);
}
-/* Create and return a protid for an existing peropen PO in CRED for USER.
- The node PO->np must be locked. */
+/* Create and return a protid for an existing peropen PO in CRED for
+ USER. */
error_t
diskfs_create_protid (struct peropen *po, struct iouser *user,
struct protid **cred)
--
2.0.0.rc2
|