Subversion Repositories HelenOS

Rev

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
        }