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 --- |