Change futex lock from mutex to sx. Make futex_get atomic (protected by the
futex lock). Sponsored by: Google SoC 2006 Submitted by: rdivacky Suggested by: jhb
This commit is contained in:
parent
5eee50ca36
commit
2140995733
@ -124,7 +124,7 @@ static void exec_linux_setregs(struct thread *td, u_long entry,
|
||||
static void linux32_fixlimits(struct proc *p);
|
||||
|
||||
extern LIST_HEAD(futex_list, futex) futex_list;
|
||||
extern struct mtx futex_mtx;
|
||||
extern struct sx futex_sx;
|
||||
|
||||
static eventhandler_tag linux_exit_tag;
|
||||
static eventhandler_tag linux_schedtail_tag;
|
||||
@ -1080,7 +1080,7 @@ linux_elf_modevent(module_t mod, int type, void *data)
|
||||
sx_init(&emul_lock, "emuldata lock");
|
||||
sx_init(&emul_shared_lock, "emuldata->shared lock");
|
||||
LIST_INIT(&futex_list);
|
||||
mtx_init(&futex_mtx, "futex protection lock", NULL, MTX_DEF);
|
||||
sx_init(&futex_sx, "futex protection lock");
|
||||
linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
|
||||
NULL, 1000);
|
||||
linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail, linux_schedtail,
|
||||
@ -1110,7 +1110,7 @@ linux_elf_modevent(module_t mod, int type, void *data)
|
||||
linux_device_unregister_handler(*ldhp);
|
||||
sx_destroy(&emul_lock);
|
||||
sx_destroy(&emul_shared_lock);
|
||||
mtx_destroy(&futex_mtx);
|
||||
sx_destroy(&futex_sx);
|
||||
EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
|
||||
EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag);
|
||||
EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
|
||||
|
@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/queue.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#ifdef COMPAT_LINUX32
|
||||
@ -73,10 +74,10 @@ struct futex {
|
||||
};
|
||||
|
||||
LIST_HEAD(futex_list, futex) futex_list;
|
||||
struct mtx futex_mtx; /* this protects the LIST of futexes */
|
||||
struct sx futex_sx; /* this protects the LIST of futexes */
|
||||
|
||||
#define FUTEX_LOCK mtx_lock(&futex_mtx)
|
||||
#define FUTEX_UNLOCK mtx_unlock(&futex_mtx)
|
||||
#define FUTEX_LOCK sx_xlock(&futex_sx)
|
||||
#define FUTEX_UNLOCK sx_xunlock(&futex_sx)
|
||||
|
||||
#define FUTEX_LOCKED 1
|
||||
#define FUTEX_UNLOCKED 0
|
||||
@ -343,16 +344,11 @@ futex_get(void *uaddr, int locked)
|
||||
return f;
|
||||
}
|
||||
}
|
||||
if (locked == FUTEX_UNLOCKED)
|
||||
FUTEX_UNLOCK;
|
||||
|
||||
/* Not found, create it */
|
||||
f = malloc(sizeof(*f), M_LINUX, M_WAITOK);
|
||||
f->f_uaddr = uaddr;
|
||||
f->f_refcount = 1;
|
||||
TAILQ_INIT(&f->f_waiting_proc);
|
||||
if (locked == FUTEX_UNLOCKED)
|
||||
FUTEX_LOCK;
|
||||
LIST_INSERT_HEAD(&futex_list, f, f_list);
|
||||
if (locked == FUTEX_UNLOCKED)
|
||||
FUTEX_UNLOCK;
|
||||
|
@ -108,7 +108,7 @@ static void exec_linux_setregs(struct thread *td, u_long entry,
|
||||
u_long stack, u_long ps_strings);
|
||||
|
||||
extern LIST_HEAD(futex_list, futex) futex_list;
|
||||
extern struct mtx futex_mtx;
|
||||
extern struct sx futex_sx;
|
||||
|
||||
static eventhandler_tag linux_exit_tag;
|
||||
static eventhandler_tag linux_schedtail_tag;
|
||||
@ -920,7 +920,7 @@ linux_elf_modevent(module_t mod, int type, void *data)
|
||||
sx_init(&emul_lock, "emuldata lock");
|
||||
sx_init(&emul_shared_lock, "emuldata->shared lock");
|
||||
LIST_INIT(&futex_list);
|
||||
mtx_init(&futex_mtx, "futex protection lock", NULL, MTX_DEF);
|
||||
sx_init(&futex_sx, "futex protection lock");
|
||||
linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
|
||||
NULL, 1000);
|
||||
linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail, linux_schedtail,
|
||||
@ -950,7 +950,7 @@ linux_elf_modevent(module_t mod, int type, void *data)
|
||||
linux_device_unregister_handler(*ldhp);
|
||||
sx_destroy(&emul_lock);
|
||||
sx_destroy(&emul_shared_lock);
|
||||
mtx_destroy(&futex_mtx);
|
||||
sx_destroy(&futex_sx);
|
||||
EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
|
||||
EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag);
|
||||
EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
|
||||
|
Loading…
x
Reference in New Issue
Block a user