Blame view

include/linux/futex.h 5.93 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  #ifndef _LINUX_FUTEX_H
  #define _LINUX_FUTEX_H
0771dfefc   Ingo Molnar   [PATCH] lightweig...
3
  #include <linux/sched.h>
c19384b5b   Pierre Peiffer   Make futex_wait()...
4
  union ktime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
  /* Second argument to futex syscall */
4732efbeb   Jakub Jelinek   [PATCH] FUTEX_WAK...
6
7
8
9
10
11
  #define FUTEX_WAIT		0
  #define FUTEX_WAKE		1
  #define FUTEX_FD		2
  #define FUTEX_REQUEUE		3
  #define FUTEX_CMP_REQUEUE	4
  #define FUTEX_WAKE_OP		5
c87e2837b   Ingo Molnar   [PATCH] pi-futex:...
12
13
14
  #define FUTEX_LOCK_PI		6
  #define FUTEX_UNLOCK_PI		7
  #define FUTEX_TRYLOCK_PI	8
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15

34f01cc1f   Eric Dumazet   FUTEX: new PRIVAT...
16
17
18
19
20
21
22
23
24
25
26
  #define FUTEX_PRIVATE_FLAG	128
  #define FUTEX_CMD_MASK		~FUTEX_PRIVATE_FLAG
  
  #define FUTEX_WAIT_PRIVATE	(FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
  #define FUTEX_WAKE_PRIVATE	(FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
  #define FUTEX_REQUEUE_PRIVATE	(FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
  #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
  #define FUTEX_WAKE_OP_PRIVATE	(FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
  #define FUTEX_LOCK_PI_PRIVATE	(FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
  #define FUTEX_UNLOCK_PI_PRIVATE	(FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
  #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
0771dfefc   Ingo Molnar   [PATCH] lightweig...
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  /*
   * Support for robust futexes: the kernel cleans up held futexes at
   * thread exit time.
   */
  
  /*
   * Per-lock list entry - embedded in user-space locks, somewhere close
   * to the futex field. (Note: user-space uses a double-linked list to
   * achieve O(1) list add and remove, but the kernel only needs to know
   * about the forward link)
   *
   * NOTE: this structure is part of the syscall ABI, and must not be
   * changed.
   */
  struct robust_list {
  	struct robust_list __user *next;
  };
  
  /*
   * Per-thread list head:
   *
   * NOTE: this structure is part of the syscall ABI, and must only be
   * changed if the change is first communicated with the glibc folks.
   * (When an incompatible change is done, we'll increase the structure
   *  size, which glibc will detect)
   */
  struct robust_list_head {
  	/*
  	 * The head of the list. Points back to itself if empty:
  	 */
  	struct robust_list list;
  
  	/*
  	 * This relative offset is set by user-space, it gives the kernel
  	 * the relative position of the futex field to examine. This way
  	 * we keep userspace flexible, to freely shape its data-structure,
  	 * without hardcoding any particular offset into the kernel:
  	 */
  	long futex_offset;
  
  	/*
  	 * The death of the thread may race with userspace setting
  	 * up a lock's links. So to handle this race, userspace first
  	 * sets this field to the address of the to-be-taken lock,
  	 * then does the lock acquire, and then adds itself to the
  	 * list, and then clears this field. Hence the kernel will
  	 * always have full knowledge of all locks that the thread
  	 * _might_ have taken. We check the owner TID in any case,
  	 * so only truly owned locks will be handled.
  	 */
  	struct robust_list __user *list_op_pending;
  };
  
  /*
   * Are there any waiters for this robust futex:
   */
  #define FUTEX_WAITERS		0x80000000
  
  /*
   * The kernel signals via this bit that a thread holding a futex
   * has exited without unlocking the futex. The kernel also does
   * a FUTEX_WAKE on such futexes, after setting the bit, to wake
   * up any possible waiters:
   */
  #define FUTEX_OWNER_DIED	0x40000000
  
  /*
0771dfefc   Ingo Molnar   [PATCH] lightweig...
94
95
   * The rest of the robust-futex field is for the TID:
   */
bd197234b   Thomas Gleixner   Revert "futex_req...
96
  #define FUTEX_TID_MASK		0x3fffffff
0771dfefc   Ingo Molnar   [PATCH] lightweig...
97
98
  
  /*
76b81e2b0   Ingo Molnar   [PATCH] lightweig...
99
100
   * This limit protects against a deliberately circular list.
   * (Not worth introducing an rlimit for it)
0771dfefc   Ingo Molnar   [PATCH] lightweig...
101
   */
76b81e2b0   Ingo Molnar   [PATCH] lightweig...
102
  #define ROBUST_LIST_LIMIT	2048
0771dfefc   Ingo Molnar   [PATCH] lightweig...
103

58f64d83c   David Woodhouse   [PATCH] Fix noise...
104
  #ifdef __KERNEL__
c19384b5b   Pierre Peiffer   Make futex_wait()...
105
  long do_futex(u32 __user *uaddr, int op, u32 val, union ktime *timeout,
e2970f2fb   Ingo Molnar   [PATCH] pi-futex:...
106
  	      u32 __user *uaddr2, u32 val2, u32 val3);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107

e3f2ddeac   Ingo Molnar   [PATCH] pi-futex:...
108
109
  extern int
  handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi);
0771dfefc   Ingo Molnar   [PATCH] lightweig...
110

9adef58b1   Rusty Russell   futex: get_futex_...
111
112
113
114
115
116
  /*
   * Futexes are matched on equal values of this key.
   * The key type depends on whether it's a shared or private mapping.
   * Don't rearrange members without looking at hash_futex().
   *
   * offset is aligned to a multiple of sizeof(u32) (== 4) by definition.
34f01cc1f   Eric Dumazet   FUTEX: new PRIVAT...
117
118
119
120
121
122
123
124
125
126
127
   * We use the two low order bits of offset to tell what is the kind of key :
   *  00 : Private process futex (PTHREAD_PROCESS_PRIVATE)
   *       (no reference on an inode or mm)
   *  01 : Shared futex (PTHREAD_PROCESS_SHARED)
   *	mapped on a file (reference on the underlying inode)
   *  10 : Shared futex (PTHREAD_PROCESS_SHARED)
   *       (but private mapping on an mm, and reference taken on it)
  */
  
  #define FUT_OFF_INODE    1 /* We set bit 0 if key has a reference on inode */
  #define FUT_OFF_MMSHARED 2 /* We set bit 1 if key has a reference on mm */
9adef58b1   Rusty Russell   futex: get_futex_...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
  union futex_key {
  	struct {
  		unsigned long pgoff;
  		struct inode *inode;
  		int offset;
  	} shared;
  	struct {
  		unsigned long address;
  		struct mm_struct *mm;
  		int offset;
  	} private;
  	struct {
  		unsigned long word;
  		void *ptr;
  		int offset;
  	} both;
  };
34f01cc1f   Eric Dumazet   FUTEX: new PRIVAT...
145
146
  int get_futex_key(u32 __user *uaddr, struct rw_semaphore *shared,
  		  union futex_key *key);
9adef58b1   Rusty Russell   futex: get_futex_...
147
148
  void get_futex_key_refs(union futex_key *key);
  void drop_futex_key_refs(union futex_key *key);
0771dfefc   Ingo Molnar   [PATCH] lightweig...
149
150
  #ifdef CONFIG_FUTEX
  extern void exit_robust_list(struct task_struct *curr);
c87e2837b   Ingo Molnar   [PATCH] pi-futex:...
151
  extern void exit_pi_state_list(struct task_struct *curr);
0771dfefc   Ingo Molnar   [PATCH] lightweig...
152
153
154
155
  #else
  static inline void exit_robust_list(struct task_struct *curr)
  {
  }
c87e2837b   Ingo Molnar   [PATCH] pi-futex:...
156
157
158
  static inline void exit_pi_state_list(struct task_struct *curr)
  {
  }
0771dfefc   Ingo Molnar   [PATCH] lightweig...
159
  #endif
58f64d83c   David Woodhouse   [PATCH] Fix noise...
160
  #endif /* __KERNEL__ */
0771dfefc   Ingo Molnar   [PATCH] lightweig...
161

4732efbeb   Jakub Jelinek   [PATCH] FUTEX_WAK...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  #define FUTEX_OP_SET		0	/* *(int *)UADDR2 = OPARG; */
  #define FUTEX_OP_ADD		1	/* *(int *)UADDR2 += OPARG; */
  #define FUTEX_OP_OR		2	/* *(int *)UADDR2 |= OPARG; */
  #define FUTEX_OP_ANDN		3	/* *(int *)UADDR2 &= ~OPARG; */
  #define FUTEX_OP_XOR		4	/* *(int *)UADDR2 ^= OPARG; */
  
  #define FUTEX_OP_OPARG_SHIFT	8	/* Use (1 << OPARG) instead of OPARG.  */
  
  #define FUTEX_OP_CMP_EQ		0	/* if (oldval == CMPARG) wake */
  #define FUTEX_OP_CMP_NE		1	/* if (oldval != CMPARG) wake */
  #define FUTEX_OP_CMP_LT		2	/* if (oldval < CMPARG) wake */
  #define FUTEX_OP_CMP_LE		3	/* if (oldval <= CMPARG) wake */
  #define FUTEX_OP_CMP_GT		4	/* if (oldval > CMPARG) wake */
  #define FUTEX_OP_CMP_GE		5	/* if (oldval >= CMPARG) wake */
  
  /* FUTEX_WAKE_OP will perform atomically
     int oldval = *(int *)UADDR2;
     *(int *)UADDR2 = oldval OP OPARG;
     if (oldval CMP CMPARG)
       wake UADDR2;  */
  
  #define FUTEX_OP(op, oparg, cmp, cmparg) \
    (((op & 0xf) << 28) | ((cmp & 0xf) << 24)		\
     | ((oparg & 0xfff) << 12) | (cmparg & 0xfff))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  #endif