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} |