Expose the umtx_key structure and API to the rest of the kernel.
MFC after: 3 days
This commit is contained in:
parent
6e2b68aab6
commit
3379ac59af
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=218969
@ -59,41 +59,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <compat/freebsd32/freebsd32_proto.h>
|
#include <compat/freebsd32/freebsd32_proto.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {
|
|
||||||
TYPE_SIMPLE_WAIT,
|
|
||||||
TYPE_CV,
|
|
||||||
TYPE_SEM,
|
|
||||||
TYPE_SIMPLE_LOCK,
|
|
||||||
TYPE_NORMAL_UMUTEX,
|
|
||||||
TYPE_PI_UMUTEX,
|
|
||||||
TYPE_PP_UMUTEX,
|
|
||||||
TYPE_RWLOCK
|
|
||||||
};
|
|
||||||
|
|
||||||
#define _UMUTEX_TRY 1
|
#define _UMUTEX_TRY 1
|
||||||
#define _UMUTEX_WAIT 2
|
#define _UMUTEX_WAIT 2
|
||||||
|
|
||||||
/* Key to represent a unique userland synchronous object */
|
|
||||||
struct umtx_key {
|
|
||||||
int hash;
|
|
||||||
int type;
|
|
||||||
int shared;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
vm_object_t object;
|
|
||||||
uintptr_t offset;
|
|
||||||
} shared;
|
|
||||||
struct {
|
|
||||||
struct vmspace *vs;
|
|
||||||
uintptr_t addr;
|
|
||||||
} private;
|
|
||||||
struct {
|
|
||||||
void *a;
|
|
||||||
uintptr_t b;
|
|
||||||
} both;
|
|
||||||
} info;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Priority inheritance mutex info. */
|
/* Priority inheritance mutex info. */
|
||||||
struct umtx_pi {
|
struct umtx_pi {
|
||||||
/* Owner thread */
|
/* Owner thread */
|
||||||
@ -208,10 +176,6 @@ struct umtxq_chain {
|
|||||||
#define UMTX_CHAINS 512
|
#define UMTX_CHAINS 512
|
||||||
#define UMTX_SHIFTS (__WORD_BIT - 9)
|
#define UMTX_SHIFTS (__WORD_BIT - 9)
|
||||||
|
|
||||||
#define THREAD_SHARE 0
|
|
||||||
#define PROCESS_SHARE 1
|
|
||||||
#define AUTO_SHARE 2
|
|
||||||
|
|
||||||
#define GET_SHARE(flags) \
|
#define GET_SHARE(flags) \
|
||||||
(((flags) & USYNC_PROCESS_SHARED) == 0 ? THREAD_SHARE : PROCESS_SHARE)
|
(((flags) & USYNC_PROCESS_SHARED) == 0 ? THREAD_SHARE : PROCESS_SHARE)
|
||||||
|
|
||||||
@ -237,10 +201,6 @@ static void umtxq_insert_queue(struct umtx_q *uq, int q);
|
|||||||
static void umtxq_remove_queue(struct umtx_q *uq, int q);
|
static void umtxq_remove_queue(struct umtx_q *uq, int q);
|
||||||
static int umtxq_sleep(struct umtx_q *uq, const char *wmesg, int timo);
|
static int umtxq_sleep(struct umtx_q *uq, const char *wmesg, int timo);
|
||||||
static int umtxq_count(struct umtx_key *key);
|
static int umtxq_count(struct umtx_key *key);
|
||||||
static int umtx_key_match(const struct umtx_key *k1, const struct umtx_key *k2);
|
|
||||||
static int umtx_key_get(void *addr, int type, int share,
|
|
||||||
struct umtx_key *key);
|
|
||||||
static void umtx_key_release(struct umtx_key *key);
|
|
||||||
static struct umtx_pi *umtx_pi_alloc(int);
|
static struct umtx_pi *umtx_pi_alloc(int);
|
||||||
static void umtx_pi_free(struct umtx_pi *pi);
|
static void umtx_pi_free(struct umtx_pi *pi);
|
||||||
static int do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags);
|
static int do_unlock_pp(struct thread *td, struct umutex *m, uint32_t flags);
|
||||||
@ -307,14 +267,6 @@ umtxq_hash(struct umtx_key *key)
|
|||||||
key->hash = ((n * GOLDEN_RATIO_PRIME) >> UMTX_SHIFTS) % UMTX_CHAINS;
|
key->hash = ((n * GOLDEN_RATIO_PRIME) >> UMTX_SHIFTS) % UMTX_CHAINS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
|
||||||
umtx_key_match(const struct umtx_key *k1, const struct umtx_key *k2)
|
|
||||||
{
|
|
||||||
return (k1->type == k2->type &&
|
|
||||||
k1->info.both.a == k2->info.both.a &&
|
|
||||||
k1->info.both.b == k2->info.both.b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct umtxq_chain *
|
static inline struct umtxq_chain *
|
||||||
umtxq_getchain(struct umtx_key *key)
|
umtxq_getchain(struct umtx_key *key)
|
||||||
{
|
{
|
||||||
@ -567,7 +519,7 @@ umtxq_sleep(struct umtx_q *uq, const char *wmesg, int timo)
|
|||||||
/*
|
/*
|
||||||
* Convert userspace address into unique logical address.
|
* Convert userspace address into unique logical address.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
umtx_key_get(void *addr, int type, int share, struct umtx_key *key)
|
umtx_key_get(void *addr, int type, int share, struct umtx_key *key)
|
||||||
{
|
{
|
||||||
struct thread *td = curthread;
|
struct thread *td = curthread;
|
||||||
@ -613,7 +565,7 @@ umtx_key_get(void *addr, int type, int share, struct umtx_key *key)
|
|||||||
/*
|
/*
|
||||||
* Release key.
|
* Release key.
|
||||||
*/
|
*/
|
||||||
static inline void
|
void
|
||||||
umtx_key_release(struct umtx_key *key)
|
umtx_key_release(struct umtx_key *key)
|
||||||
{
|
{
|
||||||
if (key->shared)
|
if (key->shared)
|
||||||
|
@ -171,8 +171,59 @@ umtx_wake(u_long *p, int nr_wakeup)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The umtx_key structure is used by both the Linux futex code and the
|
||||||
|
* umtx implementation to map userland addresses to unique keys.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TYPE_SIMPLE_WAIT,
|
||||||
|
TYPE_CV,
|
||||||
|
TYPE_SEM,
|
||||||
|
TYPE_SIMPLE_LOCK,
|
||||||
|
TYPE_NORMAL_UMUTEX,
|
||||||
|
TYPE_PI_UMUTEX,
|
||||||
|
TYPE_PP_UMUTEX,
|
||||||
|
TYPE_RWLOCK,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Key to represent a unique userland synchronous object */
|
||||||
|
struct umtx_key {
|
||||||
|
int hash;
|
||||||
|
int type;
|
||||||
|
int shared;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
struct vm_object *object;
|
||||||
|
uintptr_t offset;
|
||||||
|
} shared;
|
||||||
|
struct {
|
||||||
|
struct vmspace *vs;
|
||||||
|
uintptr_t addr;
|
||||||
|
} private;
|
||||||
|
struct {
|
||||||
|
void *a;
|
||||||
|
uintptr_t b;
|
||||||
|
} both;
|
||||||
|
} info;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define THREAD_SHARE 0
|
||||||
|
#define PROCESS_SHARE 1
|
||||||
|
#define AUTO_SHARE 2
|
||||||
|
|
||||||
struct thread;
|
struct thread;
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
umtx_key_match(const struct umtx_key *k1, const struct umtx_key *k2)
|
||||||
|
{
|
||||||
|
return (k1->type == k2->type &&
|
||||||
|
k1->info.both.a == k2->info.both.a &&
|
||||||
|
k1->info.both.b == k2->info.both.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int umtx_key_get(void *, int, int, struct umtx_key *);
|
||||||
|
void umtx_key_release(struct umtx_key *);
|
||||||
struct umtx_q *umtxq_alloc(void);
|
struct umtx_q *umtxq_alloc(void);
|
||||||
void umtxq_free(struct umtx_q *);
|
void umtxq_free(struct umtx_q *);
|
||||||
int kern_umtx_wake(struct thread *, void *, int, int);
|
int kern_umtx_wake(struct thread *, void *, int, int);
|
||||||
|
Loading…
Reference in New Issue
Block a user