Deleted Added
full compact
kern_umtx.c (139292) kern_umtx.c (139427)
1/*
2 * Copyright (c) 2004, David Xu <davidxu@freebsd.org>
3 * Copyright (c) 2002, Jeffrey Roberson <jeff@freebsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*
2 * Copyright (c) 2004, David Xu <davidxu@freebsd.org>
3 * Copyright (c) 2002, Jeffrey Roberson <jeff@freebsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/kern/kern_umtx.c 139292 2004-12-25 13:02:50Z davidxu $");
29__FBSDID("$FreeBSD: head/sys/kern/kern_umtx.c 139427 2004-12-30 02:56:17Z davidxu $");
30
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/limits.h>
34#include <sys/lock.h>
35#include <sys/malloc.h>
36#include <sys/mutex.h>
37#include <sys/proc.h>

--- 565 unchanged lines hidden (view full) ---

603 if (old == -1)
604 return (EFAULT);
605 if (old != owner)
606 return (EINVAL);
607 return (0);
608}
609
610static int
30
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/limits.h>
34#include <sys/lock.h>
35#include <sys/malloc.h>
36#include <sys/mutex.h>
37#include <sys/proc.h>

--- 565 unchanged lines hidden (view full) ---

603 if (old == -1)
604 return (EFAULT);
605 if (old != owner)
606 return (EINVAL);
607 return (0);
608}
609
610static int
611do_unlock_and_wait(struct thread *td, struct umtx *umtx, long id, void *uaddr,
612 struct timespec *abstime)
611do_wait(struct thread *td, struct umtx *umtx, long id, struct timespec *abstime)
613{
614 struct umtx_q uq;
612{
613 struct umtx_q uq;
615 intptr_t owner;
616 intptr_t old;
617 struct timespec ts1, ts2;
618 struct timeval tv;
614 struct timespec ts1, ts2;
615 struct timeval tv;
616 long tmp;
619 int timo, error = 0;
620
617 int timo, error = 0;
618
621 if (umtx == uaddr)
622 return (EINVAL);
623
624 /*
625 * Make sure we own this mtx.
626 *
627 * XXX Need a {fu,su}ptr this is not correct on arch where
628 * sizeof(intptr_t) != sizeof(long).
629 */
630 if ((owner = fuword(&umtx->u_owner)) == -1)
631 return (EFAULT);
632
633 if ((owner & ~UMTX_CONTESTED) != id)
634 return (EPERM);
635
636 if ((error = umtxq_queue_me(td, uaddr, &uq)) != 0)
619 if ((error = umtxq_queue_me(td, umtx, &uq)) != 0)
637 return (error);
620 return (error);
638
639 old = casuptr((intptr_t *)&umtx->u_owner, id, UMTX_UNOWNED);
640 if (old == -1) {
621 tmp = fuword(&umtx->u_owner);
622 if (tmp != id) {
641 umtxq_lock(&uq.uq_key);
642 umtxq_remove(&uq);
643 umtxq_unlock(&uq.uq_key);
623 umtxq_lock(&uq.uq_key);
624 umtxq_remove(&uq);
625 umtxq_unlock(&uq.uq_key);
644 umtx_key_release(&uq.uq_key);
645 return (EFAULT);
646 }
647 if (old != id) {
648 error = do_unlock(td, umtx, id);
649 if (error) {
650 umtxq_lock(&uq.uq_key);
651 umtxq_remove(&uq);
652 umtxq_unlock(&uq.uq_key);
653 umtx_key_release(&uq.uq_key);
654 return (error);
655 }
656 }
657 if (abstime == NULL) {
626 } else if (abstime == NULL) {
658 umtxq_lock(&uq.uq_key);
659 if (td->td_flags & TDF_UMTXQ)
660 error = umtxq_sleep(td, &uq.uq_key,
661 td->td_priority | PCATCH, "ucond", 0);
662 if (!(td->td_flags & TDF_UMTXQ))
663 error = 0;
664 else
665 umtxq_remove(&uq);

--- 79 unchanged lines hidden (view full) ---

745 if (abstime.tv_nsec >= 1000000000 ||
746 abstime.tv_nsec < 0)
747 return (EINVAL);
748 ts = &abstime;
749 }
750 return do_lock(td, uap->umtx, uap->id, ts);
751 case UMTX_OP_UNLOCK:
752 return do_unlock(td, uap->umtx, uap->id);
627 umtxq_lock(&uq.uq_key);
628 if (td->td_flags & TDF_UMTXQ)
629 error = umtxq_sleep(td, &uq.uq_key,
630 td->td_priority | PCATCH, "ucond", 0);
631 if (!(td->td_flags & TDF_UMTXQ))
632 error = 0;
633 else
634 umtxq_remove(&uq);

--- 79 unchanged lines hidden (view full) ---

714 if (abstime.tv_nsec >= 1000000000 ||
715 abstime.tv_nsec < 0)
716 return (EINVAL);
717 ts = &abstime;
718 }
719 return do_lock(td, uap->umtx, uap->id, ts);
720 case UMTX_OP_UNLOCK:
721 return do_unlock(td, uap->umtx, uap->id);
753 case UMTX_OP_UNLOCK_AND_WAIT:
722 case UMTX_OP_WAIT:
754 /* Allow a null timespec (wait forever). */
755 if (uap->uaddr2 == NULL)
756 ts = NULL;
757 else {
758 error = copyin(uap->uaddr2, &abstime, sizeof(abstime));
759 if (error != 0)
760 return (error);
761 if (abstime.tv_nsec >= 1000000000 ||
762 abstime.tv_nsec < 0)
763 return (EINVAL);
764 ts = &abstime;
765 }
723 /* Allow a null timespec (wait forever). */
724 if (uap->uaddr2 == NULL)
725 ts = NULL;
726 else {
727 error = copyin(uap->uaddr2, &abstime, sizeof(abstime));
728 if (error != 0)
729 return (error);
730 if (abstime.tv_nsec >= 1000000000 ||
731 abstime.tv_nsec < 0)
732 return (EINVAL);
733 ts = &abstime;
734 }
766 return do_unlock_and_wait(td, uap->umtx, uap->id,
767 uap->uaddr, ts);
735 return do_wait(td, uap->umtx, uap->id, ts);
768 case UMTX_OP_WAKE:
736 case UMTX_OP_WAKE:
769 return do_wake(td, uap->uaddr, uap->id);
737 return do_wake(td, uap->umtx, uap->id);
770 default:
771 return (EINVAL);
772 }
773}
738 default:
739 return (EINVAL);
740 }
741}