Rev 1757 | Rev 1787 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1757 | Rev 1780 | ||
---|---|---|---|
Line 56... | Line 56... | ||
56 | 56 | ||
57 | #define FUTEX_HT_SIZE 1024 /* keep it a power of 2 */ |
57 | #define FUTEX_HT_SIZE 1024 /* keep it a power of 2 */ |
58 | 58 | ||
59 | static void futex_initialize(futex_t *futex); |
59 | static void futex_initialize(futex_t *futex); |
60 | 60 | ||
61 | static futex_t *futex_find(__address paddr); |
61 | static futex_t *futex_find(uintptr_t paddr); |
62 | static index_t futex_ht_hash(__native *key); |
62 | static index_t futex_ht_hash(unative_t *key); |
63 | static bool futex_ht_compare(__native *key, count_t keys, link_t *item); |
63 | static bool futex_ht_compare(unative_t *key, count_t keys, link_t *item); |
64 | static void futex_ht_remove_callback(link_t *item); |
64 | static void futex_ht_remove_callback(link_t *item); |
65 | 65 | ||
66 | /** |
66 | /** |
67 | * Read-write lock protecting global futex hash table. |
67 | * Read-write lock protecting global futex hash table. |
68 | * It is also used to serialize access to all futex_t structures. |
68 | * It is also used to serialize access to all futex_t structures. |
Line 106... | Line 106... | ||
106 | * @param flags Select mode of operation. |
106 | * @param flags Select mode of operation. |
107 | * |
107 | * |
108 | * @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See synch.h. |
108 | * @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See synch.h. |
109 | * If there is no physical mapping for uaddr ENOENT is returned. |
109 | * If there is no physical mapping for uaddr ENOENT is returned. |
110 | */ |
110 | */ |
111 | __native sys_futex_sleep_timeout(__address uaddr, __u32 usec, int flags) |
111 | unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags) |
112 | { |
112 | { |
113 | futex_t *futex; |
113 | futex_t *futex; |
114 | __address paddr; |
114 | uintptr_t paddr; |
115 | pte_t *t; |
115 | pte_t *t; |
116 | ipl_t ipl; |
116 | ipl_t ipl; |
117 | 117 | ||
118 | ipl = interrupts_disable(); |
118 | ipl = interrupts_disable(); |
119 | 119 | ||
Line 123... | Line 123... | ||
123 | page_table_lock(AS, true); |
123 | page_table_lock(AS, true); |
124 | t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE)); |
124 | t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE)); |
125 | if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) { |
125 | if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) { |
126 | page_table_unlock(AS, true); |
126 | page_table_unlock(AS, true); |
127 | interrupts_restore(ipl); |
127 | interrupts_restore(ipl); |
128 | return (__native) ENOENT; |
128 | return (unative_t) ENOENT; |
129 | } |
129 | } |
130 | paddr = PTE_GET_FRAME(t) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE)); |
130 | paddr = PTE_GET_FRAME(t) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE)); |
131 | page_table_unlock(AS, true); |
131 | page_table_unlock(AS, true); |
132 | 132 | ||
133 | interrupts_restore(ipl); |
133 | interrupts_restore(ipl); |
134 | 134 | ||
135 | futex = futex_find(paddr); |
135 | futex = futex_find(paddr); |
136 | 136 | ||
137 | return (__native) waitq_sleep_timeout(&futex->wq, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE); |
137 | return (unative_t) waitq_sleep_timeout(&futex->wq, usec, flags | SYNCH_FLAGS_INTERRUPTIBLE); |
138 | } |
138 | } |
139 | 139 | ||
140 | /** Wakeup one thread waiting in futex wait queue. |
140 | /** Wakeup one thread waiting in futex wait queue. |
141 | * |
141 | * |
142 | * @param uaddr Userspace address of the futex counter. |
142 | * @param uaddr Userspace address of the futex counter. |
143 | * |
143 | * |
144 | * @return ENOENT if there is no physical mapping for uaddr. |
144 | * @return ENOENT if there is no physical mapping for uaddr. |
145 | */ |
145 | */ |
146 | __native sys_futex_wakeup(__address uaddr) |
146 | unative_t sys_futex_wakeup(uintptr_t uaddr) |
147 | { |
147 | { |
148 | futex_t *futex; |
148 | futex_t *futex; |
149 | __address paddr; |
149 | uintptr_t paddr; |
150 | pte_t *t; |
150 | pte_t *t; |
151 | ipl_t ipl; |
151 | ipl_t ipl; |
152 | 152 | ||
153 | ipl = interrupts_disable(); |
153 | ipl = interrupts_disable(); |
154 | 154 | ||
Line 158... | Line 158... | ||
158 | page_table_lock(AS, true); |
158 | page_table_lock(AS, true); |
159 | t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE)); |
159 | t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE)); |
160 | if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) { |
160 | if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) { |
161 | page_table_unlock(AS, true); |
161 | page_table_unlock(AS, true); |
162 | interrupts_restore(ipl); |
162 | interrupts_restore(ipl); |
163 | return (__native) ENOENT; |
163 | return (unative_t) ENOENT; |
164 | } |
164 | } |
165 | paddr = PTE_GET_FRAME(t) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE)); |
165 | paddr = PTE_GET_FRAME(t) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE)); |
166 | page_table_unlock(AS, true); |
166 | page_table_unlock(AS, true); |
167 | 167 | ||
168 | interrupts_restore(ipl); |
168 | interrupts_restore(ipl); |
Line 180... | Line 180... | ||
180 | * |
180 | * |
181 | * @param paddr Physical address of the userspace futex counter. |
181 | * @param paddr Physical address of the userspace futex counter. |
182 | * |
182 | * |
183 | * @return Address of the kernel futex structure. |
183 | * @return Address of the kernel futex structure. |
184 | */ |
184 | */ |
185 | futex_t *futex_find(__address paddr) |
185 | futex_t *futex_find(uintptr_t paddr) |
186 | { |
186 | { |
187 | link_t *item; |
187 | link_t *item; |
188 | futex_t *futex; |
188 | futex_t *futex; |
189 | btree_node_t *leaf; |
189 | btree_node_t *leaf; |
190 | 190 | ||
Line 273... | Line 273... | ||
273 | * |
273 | * |
274 | * @param key Address where the key (i.e. physical address of futex counter) is stored. |
274 | * @param key Address where the key (i.e. physical address of futex counter) is stored. |
275 | * |
275 | * |
276 | * @return Index into futex hash table. |
276 | * @return Index into futex hash table. |
277 | */ |
277 | */ |
278 | index_t futex_ht_hash(__native *key) |
278 | index_t futex_ht_hash(unative_t *key) |
279 | { |
279 | { |
280 | return *key & (FUTEX_HT_SIZE-1); |
280 | return *key & (FUTEX_HT_SIZE-1); |
281 | } |
281 | } |
282 | 282 | ||
283 | /** Compare futex hash table item with a key. |
283 | /** Compare futex hash table item with a key. |
284 | * |
284 | * |
285 | * @param key Address where the key (i.e. physical address of futex counter) is stored. |
285 | * @param key Address where the key (i.e. physical address of futex counter) is stored. |
286 | * |
286 | * |
287 | * @return True if the item matches the key. False otherwise. |
287 | * @return True if the item matches the key. False otherwise. |
288 | */ |
288 | */ |
289 | bool futex_ht_compare(__native *key, count_t keys, link_t *item) |
289 | bool futex_ht_compare(unative_t *key, count_t keys, link_t *item) |
290 | { |
290 | { |
291 | futex_t *futex; |
291 | futex_t *futex; |
292 | 292 | ||
293 | ASSERT(keys == 1); |
293 | ASSERT(keys == 1); |
294 | 294 | ||
Line 321... | Line 321... | ||
321 | int i; |
321 | int i; |
322 | 322 | ||
323 | node = list_get_instance(cur, btree_node_t, leaf_link); |
323 | node = list_get_instance(cur, btree_node_t, leaf_link); |
324 | for (i = 0; i < node->keys; i++) { |
324 | for (i = 0; i < node->keys; i++) { |
325 | futex_t *ftx; |
325 | futex_t *ftx; |
326 | __address paddr = node->key[i]; |
326 | uintptr_t paddr = node->key[i]; |
327 | 327 | ||
328 | ftx = (futex_t *) node->value[i]; |
328 | ftx = (futex_t *) node->value[i]; |
329 | if (--ftx->refcount == 0) |
329 | if (--ftx->refcount == 0) |
330 | hash_table_remove(&futex_ht, &paddr, 1); |
330 | hash_table_remove(&futex_ht, &paddr, 1); |
331 | } |
331 | } |