Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1116 → Rev 1117

/kernel/trunk/generic/src/synch/futex.c
29,15 → 29,16
/**
* Kernel backend for futexes.
* Deallocation of orphaned kernel-side futex structures is not currently implemented.
* Timeouting futexes are currently not implemented.
*/
 
#include <synch/futex.h>
#include <synch/rwlock.h>
#include <synch/spinlock.h>
#include <synch/synch.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <mm/slab.h>
#include <proc/thread.h>
#include <genarch/mm/page_pt.h>
#include <genarch/mm/page_ht.h>
#include <adt/hash_table.h>
90,17 → 91,22
/** Sleep in futex wait queue.
*
* @param uaddr Userspace address of the futex counter.
* @param usec If non-zero, number of microseconds this thread is willing to sleep.
* @param trydown If usec is zero and trydown is non-zero, conditional operation will be attempted.
*
* @return One of ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See synch.h.
* @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See synch.h.
* If there is no physical mapping for uaddr ENOENT is returned.
*/
__native sys_futex_sleep(__address uaddr)
__native sys_futex_sleep_timeout(__address uaddr, __u32 usec, int trydown)
{
futex_t *futex;
__address paddr;
link_t *item;
pte_t *t;
ipl_t ipl;
ipl = interrupts_disable();
 
/*
* Find physical address of futex counter.
*/
108,11 → 114,14
t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE));
if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) {
page_table_unlock(AS, true);
interrupts_restore(ipl);
return (__native) ENOENT;
}
paddr = PFN2ADDR(PTE_GET_FRAME(t)) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
page_table_unlock(AS, true);
interrupts_restore(ipl);
 
/*
* Find the respective futex structure
* or allocate new one if it does not exist already.
148,7 → 157,7
}
}
return (__native) waitq_sleep(&futex->wq);
return (__native) waitq_sleep_timeout(&futex->wq, usec, trydown);
}
 
/** Wakeup one thread waiting in futex wait queue.
164,7 → 173,10
__address paddr;
link_t *item;
pte_t *t;
ipl_t ipl;
ipl = interrupts_disable();
/*
* Find physical address of futex counter.
*/
172,11 → 184,14
t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE));
if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) {
page_table_unlock(AS, true);
interrupts_restore(ipl);
return (__native) ENOENT;
}
paddr = PFN2ADDR(PTE_GET_FRAME(t)) + (uaddr - ALIGN_DOWN(uaddr, PAGE_SIZE));
page_table_unlock(AS, true);
interrupts_restore(ipl);
 
/*
* Find the respective futex structure.
*/
186,7 → 201,7
futex = hash_table_get_instance(item, futex_t, ht_link);
}
rwlock_read_unlock(&futex_ht_lock);
 
if (!futex)
return (__native) ENOENT;