diff options
-rw-r--r-- | ipc/sem.c | 42 |
1 files changed, 29 insertions, 13 deletions
@@ -918,6 +918,24 @@ again: | |||
918 | } | 918 | } |
919 | 919 | ||
920 | /** | 920 | /** |
921 | * set_semotime(sma, sops) - set sem_otime | ||
922 | * @sma: semaphore array | ||
923 | * @sops: operations that modified the array, may be NULL | ||
924 | * | ||
925 | * sem_otime is replicated to avoid cache line trashing. | ||
926 | * This function sets one instance to the current time. | ||
927 | */ | ||
928 | static void set_semotime(struct sem_array *sma, struct sembuf *sops) | ||
929 | { | ||
930 | if (sops == NULL) { | ||
931 | sma->sem_base[0].sem_otime = get_seconds(); | ||
932 | } else { | ||
933 | sma->sem_base[sops[0].sem_num].sem_otime = | ||
934 | get_seconds(); | ||
935 | } | ||
936 | } | ||
937 | |||
938 | /** | ||
921 | * do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue | 939 | * do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue |
922 | * @sma: semaphore array | 940 | * @sma: semaphore array |
923 | * @sops: operations that were performed | 941 | * @sops: operations that were performed |
@@ -967,17 +985,10 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop | |||
967 | } | 985 | } |
968 | } | 986 | } |
969 | } | 987 | } |
970 | if (otime) { | 988 | if (otime) |
971 | if (sops == NULL) { | 989 | set_semotime(sma, sops); |
972 | sma->sem_base[0].sem_otime = get_seconds(); | ||
973 | } else { | ||
974 | sma->sem_base[sops[0].sem_num].sem_otime = | ||
975 | get_seconds(); | ||
976 | } | ||
977 | } | ||
978 | } | 990 | } |
979 | 991 | ||
980 | |||
981 | /* The following counts are associated to each semaphore: | 992 | /* The following counts are associated to each semaphore: |
982 | * semncnt number of tasks waiting on semval being nonzero | 993 | * semncnt number of tasks waiting on semval being nonzero |
983 | * semzcnt number of tasks waiting on semval being zero | 994 | * semzcnt number of tasks waiting on semval being zero |
@@ -1839,12 +1850,17 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | |||
1839 | 1850 | ||
1840 | error = perform_atomic_semop(sma, sops, nsops, un, | 1851 | error = perform_atomic_semop(sma, sops, nsops, un, |
1841 | task_tgid_vnr(current)); | 1852 | task_tgid_vnr(current)); |
1842 | if (error <= 0) { | 1853 | if (error == 0) { |
1843 | if (alter && error == 0) | 1854 | /* If the operation was successful, then do |
1855 | * the required updates. | ||
1856 | */ | ||
1857 | if (alter) | ||
1844 | do_smart_update(sma, sops, nsops, 1, &tasks); | 1858 | do_smart_update(sma, sops, nsops, 1, &tasks); |
1845 | 1859 | else | |
1846 | goto out_unlock_free; | 1860 | set_semotime(sma, sops); |
1847 | } | 1861 | } |
1862 | if (error <= 0) | ||
1863 | goto out_unlock_free; | ||
1848 | 1864 | ||
1849 | /* We need to sleep on this operation, so we put the current | 1865 | /* We need to sleep on this operation, so we put the current |
1850 | * task into the pending queue and go to sleep. | 1866 | * task into the pending queue and go to sleep. |