summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2009-05-01 15:36:02 +0000
committerdchagin <dchagin@FreeBSD.org>2009-05-01 15:36:02 +0000
commitdca50049ce746bdf7f10117a8dd8d72c8282585c (patch)
tree159658f59d3b4c2ce064cef433095d1cfa17a47c /sys/i386
parent0c2462747fbc4d0912deb7c49d3336d1791ccbd4 (diff)
downloadFreeBSD-src-dca50049ce746bdf7f10117a8dd8d72c8282585c.zip
FreeBSD-src-dca50049ce746bdf7f10117a8dd8d72c8282585c.tar.gz
Reimplement futexes.
Old implemention used Giant to protect the kernel data structures, but at the same time called malloc(M_WAITOK), that could cause the calling thread to sleep and lost Giant protection. User-visible result was the missed wakeup. New implementation uses one sx lock per futex. The sx protects the futex structures and allows to sleep while copyin or copyout are performed. Unlike linux, we return EINVAL when FUTEX_CMP_REQUEUE operation is requested and either caller specified futexes are equial or second futex already exists. This is acceptable since the situation can only occur from the application error, and glibc falls back to old FUTEX_WAKE operation when FUTEX_CMP_REQUEUE returns an error. Approved by: kib (mentor) MFC after: 1 month
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/linux/linux_sysvec.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 707ffb3..538710f 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -112,7 +112,7 @@ static int linux_szplatform;
const char *linux_platform;
extern LIST_HEAD(futex_list, futex) futex_list;
-extern struct sx futex_sx;
+extern struct mtx futex_mtx;
static eventhandler_tag linux_exit_tag;
static eventhandler_tag linux_schedtail_tag;
@@ -1083,7 +1083,7 @@ linux_elf_modevent(module_t mod, int type, void *data)
mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF);
sx_init(&emul_shared_lock, "emuldata->shared lock");
LIST_INIT(&futex_list);
- sx_init(&futex_sx, "futex protection lock");
+ mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF);
linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
NULL, 1000);
linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail, linux_schedtail,
@@ -1116,7 +1116,7 @@ linux_elf_modevent(module_t mod, int type, void *data)
linux_device_unregister_handler(*ldhp);
mtx_destroy(&emul_lock);
sx_destroy(&emul_shared_lock);
- sx_destroy(&futex_sx);
+ mtx_destroy(&futex_mtx);
EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag);
EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
OpenPOWER on IntegriCloud