aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipc/sem.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index cd6a733011a2..8c4f59b0204a 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -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 */
928static 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.