Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1152 → Rev 1153

/kernel/trunk/generic/src/synch/futex.c
53,6 → 53,7
 
static void futex_initialize(futex_t *futex);
 
static futex_t *futex_find(__address paddr);
static index_t futex_ht_hash(__native *key);
static bool futex_ht_compare(__native *key, count_t keys, link_t *item);
static void futex_ht_remove_callback(link_t *item);
101,7 → 102,6
{
futex_t *futex;
__address paddr;
link_t *item;
pte_t *t;
ipl_t ipl;
122,40 → 122,7
interrupts_restore(ipl);
 
/*
* Find the respective futex structure
* or allocate new one if it does not exist already.
*/
rwlock_read_lock(&futex_ht_lock);
item = hash_table_find(&futex_ht, &paddr);
if (item) {
futex = hash_table_get_instance(item, futex_t, ht_link);
rwlock_read_unlock(&futex_ht_lock);
} else {
/*
* Upgrade to writer is not currently supported,
* Therefore, it is necessary to release the read lock
* and reacquire it as a writer.
*/
rwlock_read_unlock(&futex_ht_lock);
 
rwlock_write_lock(&futex_ht_lock);
/*
* Detect possible race condition by searching
* the hash table once again with write access.
*/
item = hash_table_find(&futex_ht, &paddr);
if (item) {
futex = hash_table_get_instance(item, futex_t, ht_link);
rwlock_write_unlock(&futex_ht_lock);
} else {
futex = (futex_t *) malloc(sizeof(futex_t), 0);
futex_initialize(futex);
futex->paddr = paddr;
hash_table_insert(&futex_ht, &paddr, &futex->ht_link);
rwlock_write_unlock(&futex_ht_lock);
}
}
futex = futex_find(paddr);
return (__native) waitq_sleep_timeout(&futex->wq, usec, trydown);
}
169,9 → 136,8
*/
__native sys_futex_wakeup(__address uaddr)
{
futex_t *futex = NULL;
futex_t *futex;
__address paddr;
link_t *item;
pte_t *t;
ipl_t ipl;
192,22 → 158,62
interrupts_restore(ipl);
 
futex = futex_find(paddr);
waitq_wakeup(&futex->wq, WAKEUP_FIRST);
return 0;
}
 
/** Find kernel address of the futex structure corresponding to paddr.
*
* If the structure does not exist alreay, a new one is created.
*
* @param paddr Physical address of the userspace futex counter.
*
* @return Address of the kernel futex structure.
*/
futex_t *futex_find(__address paddr)
{
link_t *item;
futex_t *futex;
/*
* Find the respective futex structure.
* Find the respective futex structure
* or allocate new one if it does not exist already.
*/
rwlock_read_lock(&futex_ht_lock);
item = hash_table_find(&futex_ht, &paddr);
if (item) {
futex = hash_table_get_instance(item, futex_t, ht_link);
rwlock_read_unlock(&futex_ht_lock);
} else {
/*
* Upgrade to writer is not currently supported,
* Therefore, it is necessary to release the read lock
* and reacquire it as a writer.
*/
rwlock_read_unlock(&futex_ht_lock);
 
rwlock_write_lock(&futex_ht_lock);
/*
* Avoid possible race condition by searching
* the hash table once again with write access.
*/
item = hash_table_find(&futex_ht, &paddr);
if (item) {
futex = hash_table_get_instance(item, futex_t, ht_link);
rwlock_write_unlock(&futex_ht_lock);
} else {
futex = (futex_t *) malloc(sizeof(futex_t), 0);
futex_initialize(futex);
futex->paddr = paddr;
hash_table_insert(&futex_ht, &paddr, &futex->ht_link);
rwlock_write_unlock(&futex_ht_lock);
}
}
rwlock_read_unlock(&futex_ht_lock);
 
if (!futex)
return (__native) ENOENT;
waitq_wakeup(&futex->wq, WAKEUP_FIRST);
return 0;
return futex;
}
 
/** Compute hash index into futex hash table.