|
@@ -917,6 +917,24 @@ again:
|
|
|
return semop_completed;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * set_semotime(sma, sops) - set sem_otime
|
|
|
+ * @sma: semaphore array
|
|
|
+ * @sops: operations that modified the array, may be NULL
|
|
|
+ *
|
|
|
+ * sem_otime is replicated to avoid cache line trashing.
|
|
|
+ * This function sets one instance to the current time.
|
|
|
+ */
|
|
|
+static void set_semotime(struct sem_array *sma, struct sembuf *sops)
|
|
|
+{
|
|
|
+ if (sops == NULL) {
|
|
|
+ sma->sem_base[0].sem_otime = get_seconds();
|
|
|
+ } else {
|
|
|
+ sma->sem_base[sops[0].sem_num].sem_otime =
|
|
|
+ get_seconds();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue
|
|
|
* @sma: semaphore array
|
|
@@ -967,17 +985,10 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (otime) {
|
|
|
- if (sops == NULL) {
|
|
|
- sma->sem_base[0].sem_otime = get_seconds();
|
|
|
- } else {
|
|
|
- sma->sem_base[sops[0].sem_num].sem_otime =
|
|
|
- get_seconds();
|
|
|
- }
|
|
|
- }
|
|
|
+ if (otime)
|
|
|
+ set_semotime(sma, sops);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/* The following counts are associated to each semaphore:
|
|
|
* semncnt number of tasks waiting on semval being nonzero
|
|
|
* semzcnt number of tasks waiting on semval being zero
|
|
@@ -1839,12 +1850,17 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
|
|
|
|
|
|
error = perform_atomic_semop(sma, sops, nsops, un,
|
|
|
task_tgid_vnr(current));
|
|
|
- if (error <= 0) {
|
|
|
- if (alter && error == 0)
|
|
|
+ if (error == 0) {
|
|
|
+ /* If the operation was successful, then do
|
|
|
+ * the required updates.
|
|
|
+ */
|
|
|
+ if (alter)
|
|
|
do_smart_update(sma, sops, nsops, 1, &tasks);
|
|
|
-
|
|
|
- goto out_unlock_free;
|
|
|
+ else
|
|
|
+ set_semotime(sma, sops);
|
|
|
}
|
|
|
+ if (error <= 0)
|
|
|
+ goto out_unlock_free;
|
|
|
|
|
|
/* We need to sleep on this operation, so we put the current
|
|
|
* task into the pending queue and go to sleep.
|