View | Details | Raw Unified | Return to bug 255947
Collapse All | Expand All

(-)b/sys/compat/linux/linux_futex.c (-17 / +24 lines)
Lines 664-669 linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) Link Here
664
	struct timespec uts, *ts;
664
	struct timespec uts, *ts;
665
	int error, save;
665
	int error, save;
666
	uint32_t flags, val;
666
	uint32_t flags, val;
667
	int no_compare;
667
668
668
	if (args->op & LINUX_FUTEX_PRIVATE_FLAG) {
669
	if (args->op & LINUX_FUTEX_PRIVATE_FLAG) {
669
		flags = 0;
670
		flags = 0;
Lines 688-693 linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) Link Here
688
689
689
	error = 0;
690
	error = 0;
690
	f = f2 = NULL;
691
	f = f2 = NULL;
692
	no_compare = 0;		// for FUTEX_REQUEUE
691
693
692
	switch (args->op) {
694
	switch (args->op) {
693
	case LINUX_FUTEX_WAIT:
695
	case LINUX_FUTEX_WAIT:
Lines 767-772 linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) Link Here
767
		futex_put(f, NULL);
769
		futex_put(f, NULL);
768
		break;
770
		break;
769
771
772
	case LINUX_FUTEX_REQUEUE:
773
		/*
774
		 * Glibc does not use this operation since version 2.3.3,
775
		 * as it is racy and replaced by FUTEX_CMP_REQUEUE operation.
776
		 * Glibc versions prior to 2.3.3 fall back to FUTEX_WAKE when
777
		 * FUTEX_REQUEUE returned EINVAL.
778
		 */
779
		pem = pem_find(td->td_proc);
780
		if ((pem->flags & LINUX_XDEPR_REQUEUEOP) == 0) {
781
			linux_msg(td, "warn: deprecated FUTEX_REQUEUE");
782
			pem->flags |= LINUX_XDEPR_REQUEUEOP;
783
			LIN_SDT_PROBE0(futex, linux_sys_futex,
784
					deprecated_requeue);
785
		}
786
		/*
787
		 * The above is true, however musl libc does make use of the
788
		 * futex requeue operation, so we add support for it.
789
		 */
790
		no_compare = 1;
791
		/* FALLTHROUGH */
792
770
	case LINUX_FUTEX_CMP_REQUEUE:
793
	case LINUX_FUTEX_CMP_REQUEUE:
771
		LIN_SDT_PROBE5(futex, linux_sys_futex, debug_cmp_requeue,
794
		LIN_SDT_PROBE5(futex, linux_sys_futex, debug_cmp_requeue,
772
		    args->uaddr, args->val, args->val3, args->uaddr2,
795
		    args->uaddr, args->val, args->val3, args->uaddr2,
Lines 819-825 linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) Link Here
819
			    error);
842
			    error);
820
			return (error);
843
			return (error);
821
		}
844
		}
822
		if (val != args->val3) {
845
		if ((no_compare == 0) && val != args->val3) {
823
			LIN_SDT_PROBE2(futex, linux_sys_futex,
846
			LIN_SDT_PROBE2(futex, linux_sys_futex,
824
			    debug_cmp_requeue_value_neq, args->val, val);
847
			    debug_cmp_requeue_value_neq, args->val, val);
825
			LINUX_CTR2(sys_futex, "CMP_REQUEUE val 0x%x != uval 0x%x",
848
			LINUX_CTR2(sys_futex, "CMP_REQUEUE val 0x%x != uval 0x%x",
Lines 931-952 linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) Link Here
931
		}
954
		}
932
		return (ENOSYS);
955
		return (ENOSYS);
933
956
934
	case LINUX_FUTEX_REQUEUE:
935
		/*
936
		 * Glibc does not use this operation since version 2.3.3,
937
		 * as it is racy and replaced by FUTEX_CMP_REQUEUE operation.
938
		 * Glibc versions prior to 2.3.3 fall back to FUTEX_WAKE when
939
		 * FUTEX_REQUEUE returned EINVAL.
940
		 */
941
		pem = pem_find(td->td_proc);
942
		if ((pem->flags & LINUX_XDEPR_REQUEUEOP) == 0) {
943
			linux_msg(td, "unsupported FUTEX_REQUEUE");
944
			pem->flags |= LINUX_XDEPR_REQUEUEOP;
945
			LIN_SDT_PROBE0(futex, linux_sys_futex,
946
			    deprecated_requeue);
947
		}
948
		return (EINVAL);
949
950
	case LINUX_FUTEX_WAIT_REQUEUE_PI:
957
	case LINUX_FUTEX_WAIT_REQUEUE_PI:
951
		/* not yet implemented */
958
		/* not yet implemented */
952
		pem = pem_find(td->td_proc);
959
		pem = pem_find(td->td_proc);

Return to bug 255947