Deleted Added
full compact
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}