home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / linux / futex.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  3.8 KB  |  133 lines

  1. #ifndef _LINUX_FUTEX_H
  2. #define _LINUX_FUTEX_H
  3.  
  4. #include <linux/sched.h>
  5.  
  6. /* Second argument to futex syscall */
  7.  
  8.  
  9. #define FUTEX_WAIT        0
  10. #define FUTEX_WAKE        1
  11. #define FUTEX_FD        2
  12. #define FUTEX_REQUEUE        3
  13. #define FUTEX_CMP_REQUEUE    4
  14. #define FUTEX_WAKE_OP        5
  15.  
  16. /*
  17.  * Support for robust futexes: the kernel cleans up held futexes at
  18.  * thread exit time.
  19.  */
  20.  
  21. /*
  22.  * Per-lock list entry - embedded in user-space locks, somewhere close
  23.  * to the futex field. (Note: user-space uses a double-linked list to
  24.  * achieve O(1) list add and remove, but the kernel only needs to know
  25.  * about the forward link)
  26.  *
  27.  * NOTE: this structure is part of the syscall ABI, and must not be
  28.  * changed.
  29.  */
  30. struct robust_list {
  31.     struct robust_list __user *next;
  32. };
  33.  
  34. /*
  35.  * Per-thread list head:
  36.  *
  37.  * NOTE: this structure is part of the syscall ABI, and must only be
  38.  * changed if the change is first communicated with the glibc folks.
  39.  * (When an incompatible change is done, we'll increase the structure
  40.  *  size, which glibc will detect)
  41.  */
  42. struct robust_list_head {
  43.     /*
  44.      * The head of the list. Points back to itself if empty:
  45.      */
  46.     struct robust_list list;
  47.  
  48.     /*
  49.      * This relative offset is set by user-space, it gives the kernel
  50.      * the relative position of the futex field to examine. This way
  51.      * we keep userspace flexible, to freely shape its data-structure,
  52.      * without hardcoding any particular offset into the kernel:
  53.      */
  54.     long futex_offset;
  55.  
  56.     /*
  57.      * The death of the thread may race with userspace setting
  58.      * up a lock's links. So to handle this race, userspace first
  59.      * sets this field to the address of the to-be-taken lock,
  60.      * then does the lock acquire, and then adds itself to the
  61.      * list, and then clears this field. Hence the kernel will
  62.      * always have full knowledge of all locks that the thread
  63.      * _might_ have taken. We check the owner TID in any case,
  64.      * so only truly owned locks will be handled.
  65.      */
  66.     struct robust_list __user *list_op_pending;
  67. };
  68.  
  69. /*
  70.  * Are there any waiters for this robust futex:
  71.  */
  72. #define FUTEX_WAITERS        0x80000000
  73.  
  74. /*
  75.  * The kernel signals via this bit that a thread holding a futex
  76.  * has exited without unlocking the futex. The kernel also does
  77.  * a FUTEX_WAKE on such futexes, after setting the bit, to wake
  78.  * up any possible waiters:
  79.  */
  80. #define FUTEX_OWNER_DIED    0x40000000
  81.  
  82. /*
  83.  * The rest of the robust-futex field is for the TID:
  84.  */
  85. #define FUTEX_TID_MASK        0x3fffffff
  86.  
  87. /*
  88.  * This limit protects against a deliberately circular list.
  89.  * (Not worth introducing an rlimit for it)
  90.  */
  91. #define ROBUST_LIST_LIMIT    2048
  92.  
  93. long do_futex(unsigned long uaddr, int op, int val,
  94.         unsigned long timeout, unsigned long uaddr2, int val2,
  95.         int val3);
  96.  
  97. extern int handle_futex_death(u32 __user *uaddr, struct task_struct *curr);
  98.  
  99. #ifdef CONFIG_FUTEX
  100. extern void exit_robust_list(struct task_struct *curr);
  101. #else
  102. static inline void exit_robust_list(struct task_struct *curr)
  103. {
  104. }
  105. #endif
  106.  
  107. #define FUTEX_OP_SET        0    /* *(int *)UADDR2 = OPARG; */
  108. #define FUTEX_OP_ADD        1    /* *(int *)UADDR2 += OPARG; */
  109. #define FUTEX_OP_OR        2    /* *(int *)UADDR2 |= OPARG; */
  110. #define FUTEX_OP_ANDN        3    /* *(int *)UADDR2 &= ~OPARG; */
  111. #define FUTEX_OP_XOR        4    /* *(int *)UADDR2 ^= OPARG; */
  112.  
  113. #define FUTEX_OP_OPARG_SHIFT    8    /* Use (1 << OPARG) instead of OPARG.  */
  114.  
  115. #define FUTEX_OP_CMP_EQ        0    /* if (oldval == CMPARG) wake */
  116. #define FUTEX_OP_CMP_NE        1    /* if (oldval != CMPARG) wake */
  117. #define FUTEX_OP_CMP_LT        2    /* if (oldval < CMPARG) wake */
  118. #define FUTEX_OP_CMP_LE        3    /* if (oldval <= CMPARG) wake */
  119. #define FUTEX_OP_CMP_GT        4    /* if (oldval > CMPARG) wake */
  120. #define FUTEX_OP_CMP_GE        5    /* if (oldval >= CMPARG) wake */
  121.  
  122. /* FUTEX_WAKE_OP will perform atomically
  123.    int oldval = *(int *)UADDR2;
  124.    *(int *)UADDR2 = oldval OP OPARG;
  125.    if (oldval CMP CMPARG)
  126.      wake UADDR2;  */
  127.  
  128. #define FUTEX_OP(op, oparg, cmp, cmparg) \
  129.   (((op & 0xf) << 28) | ((cmp & 0xf) << 24)        \
  130.    | ((oparg & 0xfff) << 12) | (cmparg & 0xfff))
  131.  
  132. #endif
  133.