* @brief Main futex operation handler for lightweight processes * * @param[in] lwp The lightweight process structure * @param[in] uaddr Pointer to the futex word in user space * @param[in] op Futex operation code (type + flags) * @param[in] val Operation-specific value * @param[in] timeout Pointer to timeout specification (can be NULL) * @param[in] uaddr2 Second futex word pointer for certa
| 947 | * and manages futex objects. |
| 948 | */ |
| 949 | rt_err_t lwp_futex(struct rt_lwp *lwp, int *uaddr, int op, int val, |
| 950 | const struct timespec *timeout, int *uaddr2, int val3) |
| 951 | { |
| 952 | rt_futex_t futex, futex2; |
| 953 | rt_err_t rc = 0; |
| 954 | int op_type = op & ~FUTEX_FLAGS; |
| 955 | int op_flags = op & FUTEX_FLAGS; |
| 956 | |
| 957 | futex = _futex_get(uaddr, lwp, op_flags, &rc); |
| 958 | if (!rc) |
| 959 | { |
| 960 | switch (op_type) |
| 961 | { |
| 962 | case FUTEX_WAIT: |
| 963 | rc = _futex_wait(futex, lwp, uaddr, val, timeout, op_flags); |
| 964 | break; |
| 965 | case FUTEX_WAKE: |
| 966 | rc = _futex_wake(futex, lwp, val, op_flags); |
| 967 | break; |
| 968 | case FUTEX_REQUEUE: |
| 969 | futex2 = _futex_get(uaddr2, lwp, op_flags, &rc); |
| 970 | if (!rc) |
| 971 | { |
| 972 | _futex_lock(lwp, op_flags); |
| 973 | rc = _futex_requeue(futex, futex2, lwp, val, (long)timeout, |
| 974 | op_flags); |
| 975 | _futex_unlock(lwp, op_flags); |
| 976 | } |
| 977 | break; |
| 978 | case FUTEX_CMP_REQUEUE: |
| 979 | futex2 = _futex_get(uaddr2, lwp, op_flags, &rc); |
| 980 | _futex_lock(lwp, op_flags); |
| 981 | if (*uaddr == val3) |
| 982 | { |
| 983 | rc = 0; |
| 984 | } |
| 985 | else |
| 986 | { |
| 987 | rc = -EAGAIN; |
| 988 | } |
| 989 | if (rc == 0) |
| 990 | { |
| 991 | rc = _futex_requeue(futex, futex2, lwp, val, |
| 992 | (long)timeout, op_flags); |
| 993 | } |
| 994 | _futex_unlock(lwp, op_flags); |
| 995 | break; |
| 996 | case FUTEX_LOCK_PI: |
| 997 | rc = _futex_lock_pi(futex, lwp, uaddr, timeout, op_flags, |
| 998 | RT_FALSE); |
| 999 | break; |
| 1000 | case FUTEX_UNLOCK_PI: |
| 1001 | rc = _futex_unlock_pi(futex, lwp, op_flags); |
| 1002 | break; |
| 1003 | case FUTEX_TRYLOCK_PI: |
| 1004 | rc = _futex_lock_pi(futex, lwp, uaddr, 0, op_flags, RT_TRUE); |
| 1005 | break; |
| 1006 | default: |
no test coverage detected