thr_pshared.c (d60840138f6292c1ceeb177ebe797eca0b2749da) thr_pshared.c (c7904405a8d47f64c3b0e73158572e2dc8ef0217)
1/*-
2 * Copyright (c) 2015 The FreeBSD Foundation
3 *
4 * This software was developed by Konstantin Belousov
5 * under sponsorship from the FreeBSD Foundation.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 36 unchanged lines hidden (view full) ---

45};
46
47LIST_HEAD(pshared_hash_head, psh);
48#define HASH_SIZE 128
49static struct pshared_hash_head pshared_hash[HASH_SIZE];
50#define PSHARED_KEY_HASH(key) (((unsigned long)(key) >> 8) % HASH_SIZE)
51/* XXXKIB: lock could be split to per-hash chain, if appears contested */
52static struct urwlock pshared_lock = DEFAULT_URWLOCK;
1/*-
2 * Copyright (c) 2015 The FreeBSD Foundation
3 *
4 * This software was developed by Konstantin Belousov
5 * under sponsorship from the FreeBSD Foundation.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 36 unchanged lines hidden (view full) ---

45};
46
47LIST_HEAD(pshared_hash_head, psh);
48#define HASH_SIZE 128
49static struct pshared_hash_head pshared_hash[HASH_SIZE];
50#define PSHARED_KEY_HASH(key) (((unsigned long)(key) >> 8) % HASH_SIZE)
51/* XXXKIB: lock could be split to per-hash chain, if appears contested */
52static struct urwlock pshared_lock = DEFAULT_URWLOCK;
53static int page_size;
53
54void
55__thr_pshared_init(void)
56{
57 int i;
58
54
55void
56__thr_pshared_init(void)
57{
58 int i;
59
60 page_size = getpagesize();
61 THR_ASSERT(page_size >= THR_PAGE_SIZE_MIN,
62 "THR_PAGE_SIZE_MIN is too large");
63
59 _thr_urwlock_init(&pshared_lock);
60 for (i = 0; i < HASH_SIZE; i++)
61 LIST_INIT(&pshared_hash[i]);
62}
63
64static void
65pshared_rlock(struct pthread *curthread)
66{

--- 40 unchanged lines hidden (view full) ---

107 for (i = 0; i < HASH_SIZE; i++) {
108 hd = &pshared_hash[i];
109 LIST_FOREACH_SAFE(h, hd, link, h1) {
110 error = _umtx_op(NULL, UMTX_OP_SHM, UMTX_SHM_ALIVE,
111 h->val, NULL);
112 if (error == 0)
113 continue;
114 LIST_REMOVE(h, link);
64 _thr_urwlock_init(&pshared_lock);
65 for (i = 0; i < HASH_SIZE; i++)
66 LIST_INIT(&pshared_hash[i]);
67}
68
69static void
70pshared_rlock(struct pthread *curthread)
71{

--- 40 unchanged lines hidden (view full) ---

112 for (i = 0; i < HASH_SIZE; i++) {
113 hd = &pshared_hash[i];
114 LIST_FOREACH_SAFE(h, hd, link, h1) {
115 error = _umtx_op(NULL, UMTX_OP_SHM, UMTX_SHM_ALIVE,
116 h->val, NULL);
117 if (error == 0)
118 continue;
119 LIST_REMOVE(h, link);
115 munmap(h->val, PAGE_SIZE);
120 munmap(h->val, page_size);
116 free(h);
117 }
118 }
119 pshared_unlock(curthread);
120}
121
122static void *
123pshared_lookup(void *key)

--- 35 unchanged lines hidden (view full) ---

159 * and then other page is mapped at the same key
160 * address, the hash would return the old val. I
161 * decided to handle the race of simultaneous hash
162 * insertion, leaving the unlikely remap problem
163 * unaddressed.
164 */
165 if (h->key == key) {
166 if (h->val != *val) {
121 free(h);
122 }
123 }
124 pshared_unlock(curthread);
125}
126
127static void *
128pshared_lookup(void *key)

--- 35 unchanged lines hidden (view full) ---

164 * and then other page is mapped at the same key
165 * address, the hash would return the old val. I
166 * decided to handle the race of simultaneous hash
167 * insertion, leaving the unlikely remap problem
168 * unaddressed.
169 */
170 if (h->key == key) {
171 if (h->val != *val) {
167 munmap(*val, PAGE_SIZE);
172 munmap(*val, page_size);
168 *val = h->val;
169 }
170 return (1);
171 }
172 }
173
174 h = malloc(sizeof(*h));
175 if (h == NULL)

--- 23 unchanged lines hidden (view full) ---

199 return (NULL);
200}
201
202static void
203pshared_clean(void *key, void *val)
204{
205
206 if (val != NULL)
173 *val = h->val;
174 }
175 return (1);
176 }
177 }
178
179 h = malloc(sizeof(*h));
180 if (h == NULL)

--- 23 unchanged lines hidden (view full) ---

204 return (NULL);
205}
206
207static void
208pshared_clean(void *key, void *val)
209{
210
211 if (val != NULL)
207 munmap(val, PAGE_SIZE);
212 munmap(val, page_size);
208 _umtx_op(NULL, UMTX_OP_SHM, UMTX_SHM_DESTROY, key, NULL);
209}
210
211void *
212__thr_pshared_offpage(void *key, int doalloc)
213{
214 struct pthread *curthread;
215 void *res;

--- 4 unchanged lines hidden (view full) ---

220 res = pshared_lookup(key);
221 pshared_unlock(curthread);
222 if (res != NULL)
223 return (res);
224 fd = _umtx_op(NULL, UMTX_OP_SHM, doalloc ? UMTX_SHM_CREAT :
225 UMTX_SHM_LOOKUP, key, NULL);
226 if (fd == -1)
227 return (NULL);
213 _umtx_op(NULL, UMTX_OP_SHM, UMTX_SHM_DESTROY, key, NULL);
214}
215
216void *
217__thr_pshared_offpage(void *key, int doalloc)
218{
219 struct pthread *curthread;
220 void *res;

--- 4 unchanged lines hidden (view full) ---

225 res = pshared_lookup(key);
226 pshared_unlock(curthread);
227 if (res != NULL)
228 return (res);
229 fd = _umtx_op(NULL, UMTX_OP_SHM, doalloc ? UMTX_SHM_CREAT :
230 UMTX_SHM_LOOKUP, key, NULL);
231 if (fd == -1)
232 return (NULL);
228 res = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
233 res = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
229 close(fd);
230 if (res == MAP_FAILED)
231 return (NULL);
232 pshared_wlock(curthread);
233 ins_done = pshared_insert(key, &res);
234 pshared_unlock(curthread);
235 if (!ins_done) {
236 pshared_clean(key, res);

--- 32 unchanged lines hidden ---
234 close(fd);
235 if (res == MAP_FAILED)
236 return (NULL);
237 pshared_wlock(curthread);
238 ins_done = pshared_insert(key, &res);
239 pshared_unlock(curthread);
240 if (!ins_done) {
241 pshared_clean(key, res);

--- 32 unchanged lines hidden ---