sysv_sem.c (100511) | sysv_sem.c (100523) |
---|---|
1/* $FreeBSD: head/sys/kern/sysv_sem.c 100511 2002-07-22 16:12:55Z alfred $ */ | 1/* $FreeBSD: head/sys/kern/sysv_sem.c 100523 2002-07-22 18:27:54Z alfred $ */ |
2 3/* 4 * Implementation of SVID semaphores 5 * 6 * Author: Daniel Boulet 7 * 8 * This software is provided ``AS IS'' without any warranties of any kind. 9 */ --- 11 unchanged lines hidden (view full) --- 21#include <sys/syscall.h> 22#include <sys/sysent.h> 23#include <sys/sysctl.h> 24#include <sys/malloc.h> 25#include <sys/jail.h> 26 27static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores"); 28 | 2 3/* 4 * Implementation of SVID semaphores 5 * 6 * Author: Daniel Boulet 7 * 8 * This software is provided ``AS IS'' without any warranties of any kind. 9 */ --- 11 unchanged lines hidden (view full) --- 21#include <sys/syscall.h> 22#include <sys/sysent.h> 23#include <sys/sysctl.h> 24#include <sys/malloc.h> 25#include <sys/jail.h> 26 27static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores"); 28 |
29#ifdef SEM_DEBUG 30#define DPRINTF(a) printf a 31#else 32#define DPRINTF(a) 33#endif 34 |
|
29static void seminit(void); 30static int sysvsem_modload(struct module *, int, void *); 31static int semunload(void); 32static void semexit_myhook(struct proc *p); 33static int sysctl_sema(SYSCTL_HANDLER_ARGS); 34 35#ifndef _SYS_SYSPROTO_H_ 36struct __semctl_args; --- 435 unchanged lines hidden (view full) --- 472 union semun *arg = uap->arg; 473 union semun real_arg; 474 struct ucred *cred = td->td_ucred; 475 int i, rval, error; 476 struct semid_ds sbuf; 477 register struct semid_ds *semaptr; 478 u_short usval; 479 | 35static void seminit(void); 36static int sysvsem_modload(struct module *, int, void *); 37static int semunload(void); 38static void semexit_myhook(struct proc *p); 39static int sysctl_sema(SYSCTL_HANDLER_ARGS); 40 41#ifndef _SYS_SYSPROTO_H_ 42struct __semctl_args; --- 435 unchanged lines hidden (view full) --- 478 union semun *arg = uap->arg; 479 union semun real_arg; 480 struct ucred *cred = td->td_ucred; 481 int i, rval, error; 482 struct semid_ds sbuf; 483 register struct semid_ds *semaptr; 484 u_short usval; 485 |
480#ifdef SEM_DEBUG 481 printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg); 482#endif | 486 DPRINTF(("call to semctl(%d, %d, %d, 0x%x)\n", 487 semid, semnum, cmd, arg)); |
483 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 484 return (ENOSYS); 485 486 mtx_lock(&Giant); 487 switch(cmd) { 488 case SEM_STAT: 489 if (semid < 0 || semid >= seminfo.semmni) 490 UGAR(EINVAL); --- 190 unchanged lines hidden (view full) --- 681 register struct semget_args *uap; 682{ 683 int semid, error = 0; 684 int key = uap->key; 685 int nsems = uap->nsems; 686 int semflg = uap->semflg; 687 struct ucred *cred = td->td_ucred; 688 | 488 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 489 return (ENOSYS); 490 491 mtx_lock(&Giant); 492 switch(cmd) { 493 case SEM_STAT: 494 if (semid < 0 || semid >= seminfo.semmni) 495 UGAR(EINVAL); --- 190 unchanged lines hidden (view full) --- 686 register struct semget_args *uap; 687{ 688 int semid, error = 0; 689 int key = uap->key; 690 int nsems = uap->nsems; 691 int semflg = uap->semflg; 692 struct ucred *cred = td->td_ucred; 693 |
689#ifdef SEM_DEBUG 690 printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg); 691#endif | 694 DPRINTF(("semget(0x%x, %d, 0%o)\n", key, nsems, semflg)); |
692 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 693 return (ENOSYS); 694 695 mtx_lock(&Giant); 696 if (key != IPC_PRIVATE) { 697 for (semid = 0; semid < seminfo.semmni; semid++) { 698 if ((sema[semid].sem_perm.mode & SEM_ALLOC) && 699 sema[semid].sem_perm.key == key) 700 break; 701 } 702 if (semid < seminfo.semmni) { | 695 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 696 return (ENOSYS); 697 698 mtx_lock(&Giant); 699 if (key != IPC_PRIVATE) { 700 for (semid = 0; semid < seminfo.semmni; semid++) { 701 if ((sema[semid].sem_perm.mode & SEM_ALLOC) && 702 sema[semid].sem_perm.key == key) 703 break; 704 } 705 if (semid < seminfo.semmni) { |
703#ifdef SEM_DEBUG 704 printf("found public key\n"); 705#endif | 706 DPRINTF(("found public key\n")); |
706 if ((error = ipcperm(td, &sema[semid].sem_perm, 707 semflg & 0700))) { 708 goto done2; 709 } 710 if (nsems > 0 && sema[semid].sem_nsems < nsems) { | 707 if ((error = ipcperm(td, &sema[semid].sem_perm, 708 semflg & 0700))) { 709 goto done2; 710 } 711 if (nsems > 0 && sema[semid].sem_nsems < nsems) { |
711#ifdef SEM_DEBUG 712 printf("too small\n"); 713#endif | 712 DPRINTF(("too small\n")); |
714 error = EINVAL; 715 goto done2; 716 } 717 if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) { | 713 error = EINVAL; 714 goto done2; 715 } 716 if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) { |
718#ifdef SEM_DEBUG 719 printf("not exclusive\n"); 720#endif | 717 DPRINTF(("not exclusive\n")); |
721 error = EEXIST; 722 goto done2; 723 } 724 goto found; 725 } 726 } 727 | 718 error = EEXIST; 719 goto done2; 720 } 721 goto found; 722 } 723 } 724 |
728#ifdef SEM_DEBUG 729 printf("need to allocate the semid_ds\n"); 730#endif | 725 DPRINTF(("need to allocate the semid_ds\n")); |
731 if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) { 732 if (nsems <= 0 || nsems > seminfo.semmsl) { | 726 if (key == IPC_PRIVATE || (semflg & IPC_CREAT)) { 727 if (nsems <= 0 || nsems > seminfo.semmsl) { |
733#ifdef SEM_DEBUG 734 printf("nsems out of range (0<%d<=%d)\n", nsems, 735 seminfo.semmsl); 736#endif | 728 DPRINTF(("nsems out of range (0<%d<=%d)\n", nsems, 729 seminfo.semmsl)); |
737 error = EINVAL; 738 goto done2; 739 } 740 if (nsems > seminfo.semmns - semtot) { | 730 error = EINVAL; 731 goto done2; 732 } 733 if (nsems > seminfo.semmns - semtot) { |
741#ifdef SEM_DEBUG 742 printf("not enough semaphores left (need %d, got %d)\n", 743 nsems, seminfo.semmns - semtot); 744#endif | 734 DPRINTF(( 735 "not enough semaphores left (need %d, got %d)\n", 736 nsems, seminfo.semmns - semtot)); |
745 error = ENOSPC; 746 goto done2; 747 } 748 for (semid = 0; semid < seminfo.semmni; semid++) { 749 if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0) 750 break; 751 } 752 if (semid == seminfo.semmni) { | 737 error = ENOSPC; 738 goto done2; 739 } 740 for (semid = 0; semid < seminfo.semmni; semid++) { 741 if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0) 742 break; 743 } 744 if (semid == seminfo.semmni) { |
753#ifdef SEM_DEBUG 754 printf("no more semid_ds's available\n"); 755#endif | 745 DPRINTF(("no more semid_ds's available\n")); |
756 error = ENOSPC; 757 goto done2; 758 } | 746 error = ENOSPC; 747 goto done2; 748 } |
759#ifdef SEM_DEBUG 760 printf("semid %d is available\n", semid); 761#endif | 749 DPRINTF(("semid %d is available\n", semid)); |
762 sema[semid].sem_perm.key = key; 763 sema[semid].sem_perm.cuid = cred->cr_uid; 764 sema[semid].sem_perm.uid = cred->cr_uid; 765 sema[semid].sem_perm.cgid = cred->cr_gid; 766 sema[semid].sem_perm.gid = cred->cr_gid; 767 sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC; 768 sema[semid].sem_perm.seq = 769 (sema[semid].sem_perm.seq + 1) & 0x7fff; 770 sema[semid].sem_nsems = nsems; 771 sema[semid].sem_otime = 0; 772 sema[semid].sem_ctime = time_second; 773 sema[semid].sem_base = &sem[semtot]; 774 semtot += nsems; 775 bzero(sema[semid].sem_base, 776 sizeof(sema[semid].sem_base[0])*nsems); | 750 sema[semid].sem_perm.key = key; 751 sema[semid].sem_perm.cuid = cred->cr_uid; 752 sema[semid].sem_perm.uid = cred->cr_uid; 753 sema[semid].sem_perm.cgid = cred->cr_gid; 754 sema[semid].sem_perm.gid = cred->cr_gid; 755 sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC; 756 sema[semid].sem_perm.seq = 757 (sema[semid].sem_perm.seq + 1) & 0x7fff; 758 sema[semid].sem_nsems = nsems; 759 sema[semid].sem_otime = 0; 760 sema[semid].sem_ctime = time_second; 761 sema[semid].sem_base = &sem[semtot]; 762 semtot += nsems; 763 bzero(sema[semid].sem_base, 764 sizeof(sema[semid].sem_base[0])*nsems); |
777#ifdef SEM_DEBUG 778 printf("sembase = 0x%x, next = 0x%x\n", sema[semid].sem_base, 779 &sem[semtot]); 780#endif | 765 DPRINTF(("sembase = 0x%x, next = 0x%x\n", sema[semid].sem_base, 766 &sem[semtot])); |
781 } else { | 767 } else { |
782#ifdef SEM_DEBUG 783 printf("didn't find it and wasn't asked to create it\n"); 784#endif | 768 DPRINTF(("didn't find it and wasn't asked to create it\n")); |
785 error = ENOENT; 786 goto done2; 787 } 788 789found: 790 td->td_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm); 791done2: 792 mtx_unlock(&Giant); --- 21 unchanged lines hidden (view full) --- 814 struct sembuf *sops = NULL; 815 register struct semid_ds *semaptr; 816 register struct sembuf *sopptr = 0; 817 register struct sem *semptr = 0; 818 struct sem_undo *suptr; 819 int i, j, error; 820 int do_wakeup, do_undos; 821 | 769 error = ENOENT; 770 goto done2; 771 } 772 773found: 774 td->td_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm); 775done2: 776 mtx_unlock(&Giant); --- 21 unchanged lines hidden (view full) --- 798 struct sembuf *sops = NULL; 799 register struct semid_ds *semaptr; 800 register struct sembuf *sopptr = 0; 801 register struct sem *semptr = 0; 802 struct sem_undo *suptr; 803 int i, j, error; 804 int do_wakeup, do_undos; 805 |
822#ifdef SEM_DEBUG 823 printf("call to semop(%d, 0x%x, %u)\n", semid, sops, nsops); 824#endif | 806 DPRINTF(("call to semop(%d, 0x%x, %u)\n", semid, sops, nsops)); |
825 826 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 827 return (ENOSYS); 828 829 mtx_lock(&Giant); 830 semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ 831 832 if (semid < 0 || semid >= seminfo.semmni) { --- 6 unchanged lines hidden (view full) --- 839 error = EINVAL; 840 goto done2; 841 } 842 if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { 843 error = EINVAL; 844 goto done2; 845 } 846 if (nsops > seminfo.semopm) { | 807 808 if (!jail_sysvipc_allowed && jailed(td->td_ucred)) 809 return (ENOSYS); 810 811 mtx_lock(&Giant); 812 semid = IPCID_TO_IX(semid); /* Convert back to zero origin */ 813 814 if (semid < 0 || semid >= seminfo.semmni) { --- 6 unchanged lines hidden (view full) --- 821 error = EINVAL; 822 goto done2; 823 } 824 if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { 825 error = EINVAL; 826 goto done2; 827 } 828 if (nsops > seminfo.semopm) { |
847#ifdef SEM_DEBUG 848 printf("too many sops (max=%d, nsops=%d)\n", seminfo.semopm, 849 nsops); 850#endif | 829 DPRINTF(("too many sops (max=%d, nsops=%d)\n", seminfo.semopm, 830 nsops)); |
851 error = E2BIG; 852 goto done2; 853 } 854 855 /* Allocate memory for sem_ops */ 856 sops = malloc(nsops * sizeof(sops[0]), M_SEM, M_WAITOK); 857 if (!sops) 858 panic("Failed to allocate %d sem_ops", nsops); 859 860 if ((error = copyin(uap->sops, sops, nsops * sizeof(sops[0]))) != 0) { | 831 error = E2BIG; 832 goto done2; 833 } 834 835 /* Allocate memory for sem_ops */ 836 sops = malloc(nsops * sizeof(sops[0]), M_SEM, M_WAITOK); 837 if (!sops) 838 panic("Failed to allocate %d sem_ops", nsops); 839 840 if ((error = copyin(uap->sops, sops, nsops * sizeof(sops[0]))) != 0) { |
861#ifdef SEM_DEBUG 862 printf("error = %d from copyin(%08x, %08x, %d)\n", error, 863 uap->sops, sops, nsops * sizeof(sops[0])); 864#endif | 841 DPRINTF(("error = %d from copyin(%08x, %08x, %d)\n", error, 842 uap->sops, sops, nsops * sizeof(sops[0]))); |
865 goto done2; 866 } 867 868 /* 869 * Initial pass thru sops to see what permissions are needed. 870 * Also perform any checks that don't need repeating on each 871 * attempt to satisfy the request vector. 872 */ --- 6 unchanged lines hidden (view full) --- 879 goto done2; 880 } 881 if (sopptr->sem_flg & SEM_UNDO && sopptr->sem_op != 0) 882 do_undos = 1; 883 j |= (sopptr->sem_op == 0) ? SEM_R : SEM_A; 884 } 885 886 if ((error = ipcperm(td, &semaptr->sem_perm, j))) { | 843 goto done2; 844 } 845 846 /* 847 * Initial pass thru sops to see what permissions are needed. 848 * Also perform any checks that don't need repeating on each 849 * attempt to satisfy the request vector. 850 */ --- 6 unchanged lines hidden (view full) --- 857 goto done2; 858 } 859 if (sopptr->sem_flg & SEM_UNDO && sopptr->sem_op != 0) 860 do_undos = 1; 861 j |= (sopptr->sem_op == 0) ? SEM_R : SEM_A; 862 } 863 864 if ((error = ipcperm(td, &semaptr->sem_perm, j))) { |
887#ifdef SEM_DEBUG 888 printf("error = %d from ipaccess\n", error); 889#endif | 865 DPRINTF(("error = %d from ipaccess\n", error)); |
890 goto done2; 891 } 892 893 /* 894 * Loop trying to satisfy the vector of requests. 895 * If we reach a point where we must wait, any requests already 896 * performed are rolled back and we go to sleep until some other 897 * process wakes us up. At this point, we start all over again. --- 4 unchanged lines hidden (view full) --- 902 for (;;) { 903 do_wakeup = 0; 904 error = 0; /* error return if necessary */ 905 906 for (i = 0; i < nsops; i++) { 907 sopptr = &sops[i]; 908 semptr = &semaptr->sem_base[sopptr->sem_num]; 909 | 866 goto done2; 867 } 868 869 /* 870 * Loop trying to satisfy the vector of requests. 871 * If we reach a point where we must wait, any requests already 872 * performed are rolled back and we go to sleep until some other 873 * process wakes us up. At this point, we start all over again. --- 4 unchanged lines hidden (view full) --- 878 for (;;) { 879 do_wakeup = 0; 880 error = 0; /* error return if necessary */ 881 882 for (i = 0; i < nsops; i++) { 883 sopptr = &sops[i]; 884 semptr = &semaptr->sem_base[sopptr->sem_num]; 885 |
910#ifdef SEM_DEBUG 911 printf("semop: semaptr=%x, sem_base=%x, semptr=%x, sem[%d]=%d : op=%d, flag=%s\n", | 886 DPRINTF(( 887 "semop: semaptr=%x, sem_base=%x, " 888 "semptr=%x, sem[%d]=%d : op=%d, flag=%s\n", |
912 semaptr, semaptr->sem_base, semptr, 913 sopptr->sem_num, semptr->semval, sopptr->sem_op, | 889 semaptr, semaptr->sem_base, semptr, 890 sopptr->sem_num, semptr->semval, sopptr->sem_op, |
914 (sopptr->sem_flg & IPC_NOWAIT) ? "nowait" : "wait"); 915#endif | 891 (sopptr->sem_flg & IPC_NOWAIT) ? 892 "nowait" : "wait")); |
916 917 if (sopptr->sem_op < 0) { 918 if (semptr->semval + sopptr->sem_op < 0) { | 893 894 if (sopptr->sem_op < 0) { 895 if (semptr->semval + sopptr->sem_op < 0) { |
919#ifdef SEM_DEBUG 920 printf("semop: can't do it now\n"); 921#endif | 896 DPRINTF(("semop: can't do it now\n")); |
922 break; 923 } else { 924 semptr->semval += sopptr->sem_op; 925 if (semptr->semval == 0 && 926 semptr->semzcnt > 0) 927 do_wakeup = 1; 928 } 929 } else if (sopptr->sem_op == 0) { 930 if (semptr->semval != 0) { | 897 break; 898 } else { 899 semptr->semval += sopptr->sem_op; 900 if (semptr->semval == 0 && 901 semptr->semzcnt > 0) 902 do_wakeup = 1; 903 } 904 } else if (sopptr->sem_op == 0) { 905 if (semptr->semval != 0) { |
931#ifdef SEM_DEBUG 932 printf("semop: not zero now\n"); 933#endif | 906 DPRINTF(("semop: not zero now\n")); |
934 break; 935 } 936 } else if (semptr->semval + sopptr->sem_op > 937 seminfo.semvmx) { 938 error = ERANGE; 939 break; 940 } else { 941 if (semptr->semncnt > 0) --- 6 unchanged lines hidden (view full) --- 948 * Did we get through the entire vector? 949 */ 950 if (i >= nsops) 951 goto done; 952 953 /* 954 * No ... rollback anything that we've already done 955 */ | 907 break; 908 } 909 } else if (semptr->semval + sopptr->sem_op > 910 seminfo.semvmx) { 911 error = ERANGE; 912 break; 913 } else { 914 if (semptr->semncnt > 0) --- 6 unchanged lines hidden (view full) --- 921 * Did we get through the entire vector? 922 */ 923 if (i >= nsops) 924 goto done; 925 926 /* 927 * No ... rollback anything that we've already done 928 */ |
956#ifdef SEM_DEBUG 957 printf("semop: rollback 0 through %d\n", i-1); 958#endif | 929 DPRINTF(("semop: rollback 0 through %d\n", i-1)); |
959 for (j = 0; j < i; j++) 960 semaptr->sem_base[sops[j].sem_num].semval -= 961 sops[j].sem_op; 962 963 /* If we detected an error, return it */ 964 if (error != 0) 965 goto done2; 966 --- 6 unchanged lines hidden (view full) --- 973 goto done2; 974 } 975 976 if (sopptr->sem_op == 0) 977 semptr->semzcnt++; 978 else 979 semptr->semncnt++; 980 | 930 for (j = 0; j < i; j++) 931 semaptr->sem_base[sops[j].sem_num].semval -= 932 sops[j].sem_op; 933 934 /* If we detected an error, return it */ 935 if (error != 0) 936 goto done2; 937 --- 6 unchanged lines hidden (view full) --- 944 goto done2; 945 } 946 947 if (sopptr->sem_op == 0) 948 semptr->semzcnt++; 949 else 950 semptr->semncnt++; 951 |
981#ifdef SEM_DEBUG 982 printf("semop: good night!\n"); 983#endif | 952 DPRINTF(("semop: good night!\n")); |
984 error = tsleep(semaptr, (PZERO - 4) | PCATCH, "semwait", 0); | 953 error = tsleep(semaptr, (PZERO - 4) | PCATCH, "semwait", 0); |
985#ifdef SEM_DEBUG 986 printf("semop: good morning (error=%d)!\n", error); 987#endif | 954 DPRINTF(("semop: good morning (error=%d)!\n", error)); |
988 989 if (error != 0) { 990 error = EINTR; 991 goto done2; 992 } | 955 956 if (error != 0) { 957 error = EINTR; 958 goto done2; 959 } |
993#ifdef SEM_DEBUG 994 printf("semop: good morning!\n"); 995#endif | 960 DPRINTF(("semop: good morning!\n")); |
996 997 /* 998 * Make sure that the semaphore still exists 999 */ 1000 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || 1001 semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { 1002 error = EIDRM; 1003 goto done2; --- 51 unchanged lines hidden (view full) --- 1055 sops[j].sem_num, adjval) != 0) 1056 panic("semop - can't undo undos"); 1057 } 1058 1059 for (j = 0; j < nsops; j++) 1060 semaptr->sem_base[sops[j].sem_num].semval -= 1061 sops[j].sem_op; 1062 | 961 962 /* 963 * Make sure that the semaphore still exists 964 */ 965 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 || 966 semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) { 967 error = EIDRM; 968 goto done2; --- 51 unchanged lines hidden (view full) --- 1020 sops[j].sem_num, adjval) != 0) 1021 panic("semop - can't undo undos"); 1022 } 1023 1024 for (j = 0; j < nsops; j++) 1025 semaptr->sem_base[sops[j].sem_num].semval -= 1026 sops[j].sem_op; 1027 |
1063#ifdef SEM_DEBUG 1064 printf("error = %d from semundo_adjust\n", error); 1065#endif | 1028 DPRINTF(("error = %d from semundo_adjust\n", error)); |
1066 goto done2; 1067 } /* loop through the sops */ 1068 } /* if (do_undos) */ 1069 1070 /* We're definitely done - set the sempid's and time */ 1071 for (i = 0; i < nsops; i++) { 1072 sopptr = &sops[i]; 1073 semptr = &semaptr->sem_base[sopptr->sem_num]; 1074 semptr->sempid = td->td_proc->p_pid; 1075 } 1076 semaptr->sem_otime = time_second; 1077 1078 /* 1079 * Do a wakeup if any semaphore was up'd whilst something was 1080 * sleeping on it. 1081 */ 1082 if (do_wakeup) { | 1029 goto done2; 1030 } /* loop through the sops */ 1031 } /* if (do_undos) */ 1032 1033 /* We're definitely done - set the sempid's and time */ 1034 for (i = 0; i < nsops; i++) { 1035 sopptr = &sops[i]; 1036 semptr = &semaptr->sem_base[sopptr->sem_num]; 1037 semptr->sempid = td->td_proc->p_pid; 1038 } 1039 semaptr->sem_otime = time_second; 1040 1041 /* 1042 * Do a wakeup if any semaphore was up'd whilst something was 1043 * sleeping on it. 1044 */ 1045 if (do_wakeup) { |
1083#ifdef SEM_DEBUG 1084 printf("semop: doing wakeup\n"); 1085#endif | 1046 DPRINTF(("semop: doing wakeup\n")); |
1086 wakeup(semaptr); | 1047 wakeup(semaptr); |
1087#ifdef SEM_DEBUG 1088 printf("semop: back from wakeup\n"); 1089#endif | 1048 DPRINTF(("semop: back from wakeup\n")); |
1090 } | 1049 } |
1091#ifdef SEM_DEBUG 1092 printf("semop: done\n"); 1093#endif | 1050 DPRINTF(("semop: done\n")); |
1094 td->td_retval[0] = 0; 1095done2: 1096 if (sops) 1097 free(sops, M_SEM); 1098 mtx_unlock(&Giant); 1099 return (error); 1100} 1101 --- 17 unchanged lines hidden (view full) --- 1119 supptr = &suptr->un_next) { 1120 if (suptr->un_proc == p) 1121 break; 1122 } 1123 1124 if (suptr == NULL) 1125 return; 1126 | 1051 td->td_retval[0] = 0; 1052done2: 1053 if (sops) 1054 free(sops, M_SEM); 1055 mtx_unlock(&Giant); 1056 return (error); 1057} 1058 --- 17 unchanged lines hidden (view full) --- 1076 supptr = &suptr->un_next) { 1077 if (suptr->un_proc == p) 1078 break; 1079 } 1080 1081 if (suptr == NULL) 1082 return; 1083 |
1127#ifdef SEM_DEBUG 1128 printf("proc @%08x has undo structure with %d entries\n", p, 1129 suptr->un_cnt); 1130#endif | 1084 DPRINTF(("proc @%08x has undo structure with %d entries\n", p, 1085 suptr->un_cnt)); |
1131 1132 /* 1133 * If there are any active undo elements then process them. 1134 */ 1135 if (suptr->un_cnt > 0) { 1136 int ix; 1137 1138 for (ix = 0; ix < suptr->un_cnt; ix++) { 1139 int semid = suptr->un_ent[ix].un_id; 1140 int semnum = suptr->un_ent[ix].un_num; 1141 int adjval = suptr->un_ent[ix].un_adjval; 1142 struct semid_ds *semaptr; 1143 1144 semaptr = &sema[semid]; 1145 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) 1146 panic("semexit - semid not allocated"); 1147 if (semnum >= semaptr->sem_nsems) 1148 panic("semexit - semnum out of range"); 1149 | 1086 1087 /* 1088 * If there are any active undo elements then process them. 1089 */ 1090 if (suptr->un_cnt > 0) { 1091 int ix; 1092 1093 for (ix = 0; ix < suptr->un_cnt; ix++) { 1094 int semid = suptr->un_ent[ix].un_id; 1095 int semnum = suptr->un_ent[ix].un_num; 1096 int adjval = suptr->un_ent[ix].un_adjval; 1097 struct semid_ds *semaptr; 1098 1099 semaptr = &sema[semid]; 1100 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) 1101 panic("semexit - semid not allocated"); 1102 if (semnum >= semaptr->sem_nsems) 1103 panic("semexit - semnum out of range"); 1104 |
1150#ifdef SEM_DEBUG 1151 printf("semexit: %08x id=%d num=%d(adj=%d) ; sem=%d\n", | 1105 DPRINTF(( 1106 "semexit: %08x id=%d num=%d(adj=%d) ; sem=%d\n", |
1152 suptr->un_proc, suptr->un_ent[ix].un_id, 1153 suptr->un_ent[ix].un_num, 1154 suptr->un_ent[ix].un_adjval, | 1107 suptr->un_proc, suptr->un_ent[ix].un_id, 1108 suptr->un_ent[ix].un_num, 1109 suptr->un_ent[ix].un_adjval, |
1155 semaptr->sem_base[semnum].semval); 1156#endif | 1110 semaptr->sem_base[semnum].semval)); |
1157 1158 if (adjval < 0) { 1159 if (semaptr->sem_base[semnum].semval < -adjval) 1160 semaptr->sem_base[semnum].semval = 0; 1161 else 1162 semaptr->sem_base[semnum].semval += 1163 adjval; 1164 } else 1165 semaptr->sem_base[semnum].semval += adjval; 1166 1167 wakeup(semaptr); | 1111 1112 if (adjval < 0) { 1113 if (semaptr->sem_base[semnum].semval < -adjval) 1114 semaptr->sem_base[semnum].semval = 0; 1115 else 1116 semaptr->sem_base[semnum].semval += 1117 adjval; 1118 } else 1119 semaptr->sem_base[semnum].semval += adjval; 1120 1121 wakeup(semaptr); |
1168#ifdef SEM_DEBUG 1169 printf("semexit: back from wakeup\n"); 1170#endif | 1122 DPRINTF(("semexit: back from wakeup\n")); |
1171 } 1172 } 1173 1174 /* 1175 * Deallocate the undo vector. 1176 */ | 1123 } 1124 } 1125 1126 /* 1127 * Deallocate the undo vector. 1128 */ |
1177#ifdef SEM_DEBUG 1178 printf("removing vector\n"); 1179#endif | 1129 DPRINTF(("removing vector\n")); |
1180 suptr->un_proc = NULL; 1181 *supptr = suptr->un_next; 1182} 1183 1184static int 1185sysctl_sema(SYSCTL_HANDLER_ARGS) 1186{ 1187 1188 return (SYSCTL_OUT(req, sema, 1189 sizeof(struct semid_ds) * seminfo.semmni)); 1190} | 1130 suptr->un_proc = NULL; 1131 *supptr = suptr->un_next; 1132} 1133 1134static int 1135sysctl_sema(SYSCTL_HANDLER_ARGS) 1136{ 1137 1138 return (SYSCTL_OUT(req, sema, 1139 sizeof(struct semid_ds) * seminfo.semmni)); 1140} |