rx: Add a helper function for delayed acks
authorSimon Wilkinson <sxw@your-file-system.com>
Sat, 22 Oct 2011 10:10:53 +0000 (11:10 +0100)
committerDerrick Brashear <shadow@dementix.org>
Sat, 12 Nov 2011 14:47:40 +0000 (06:47 -0800)
The code to schedule a new delayed ack event is distributed throughout
the RX code. Consolidate this into a single helper function.

Change-Id: If54e36b5648f8caffe64cc2203dc0041fd06b8b3
Reviewed-on: http://gerrit.openafs.org/5837
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>

src/rx/rx.c
src/rx/rx_prototypes.h
src/rx/rx_rdwr.c

index f6b8b00..b042123 100644 (file)
@@ -100,6 +100,8 @@ static void rxi_ComputeRoundTripTime(struct rx_packet *, struct rx_ackPacket *,
                                     struct clock *);
 static void rxi_Resend(struct rxevent *event, void *arg0, void *arg1,
                       int istack);
+static void rxi_SendDelayedAck(struct rxevent *event, void *call,
+                               void *dummy);
 
 #ifdef RX_ENABLE_LOCKS
 static void rxi_SetAcksInTransmitQueue(struct rx_call *call);
@@ -755,6 +757,38 @@ rx_SetBusyChannelError(afs_int32 error)
     rxi_busyChannelError = error;
 }
 
+/**
+ * Set a delayed ack event on the specified call for the given time
+ *
+ * @param[in] call - the call on which to set the event
+ * @param[in] offset - the delay from now after which the event fires
+ */
+void
+rxi_PostDelayedAckEvent(struct rx_call *call, struct clock *offset)
+{
+    struct clock now, when;
+
+    clock_GetTime(&now);
+    when = now;
+    clock_Add(&when, offset);
+
+    if (!call->delayedAckEvent
+       || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
+
+        rxevent_Cancel(call->delayedAckEvent, call,
+                      RX_CALL_REFCOUNT_DELAY);
+       MUTEX_ENTER(&rx_refcnt_mutex);
+       CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
+       MUTEX_EXIT(&rx_refcnt_mutex);
+
+       call->delayedAckEvent = rxevent_PostNow(&when, &now,
+                                               rxi_SendDelayedAck,
+                                               call, 0);
+    }
+}
+
+
+
 /* called with unincremented nRequestsRunning to see if it is OK to start
  * a new thread in this service.  Could be "no" for two reasons: over the
  * max quota, or would prevent others from reaching their min quota.
@@ -3786,7 +3820,6 @@ rxi_ReceiveDataPacket(struct rx_call *call,
     afs_uint32 serial=0, flags=0;
     int isFirst;
     struct rx_packet *tnp;
-    struct clock when, now;
     if (rx_stats_active)
         rx_atomic_inc(&rx_stats.dataPacketsRead);
 
@@ -3806,20 +3839,8 @@ rxi_ReceiveDataPacket(struct rx_call *call,
         /* We used to clear the receive queue here, in an attempt to free
          * packets. However this is unsafe if the queue has received a
          * soft ACK for the final packet */
-       clock_GetTime(&now);
-       when = now;
-       clock_Add(&when, &rx_softAckDelay);
-       if (!call->delayedAckEvent
-           || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
-           rxevent_Cancel(call->delayedAckEvent, call,
-                          RX_CALL_REFCOUNT_DELAY);
-            MUTEX_ENTER(&rx_refcnt_mutex);
-           CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
-            MUTEX_EXIT(&rx_refcnt_mutex);
+       rxi_PostDelayedAckEvent(call, &rx_softAckDelay);
 
-           call->delayedAckEvent =
-               rxevent_PostNow(&when, &now, rxi_SendDelayedAck, call, 0);
-       }
        /* we've damaged this call already, might as well do it in. */
        return np;
     }
@@ -4105,23 +4126,10 @@ rxi_ReceiveDataPacket(struct rx_call *call,
        rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
        np = rxi_SendAck(call, np, serial, RX_ACK_IDLE, istack);
     } else if (call->nSoftAcks) {
-       clock_GetTime(&now);
-       when = now;
-       if (haveLast && !(flags & RX_CLIENT_INITIATED)) {
-           clock_Add(&when, &rx_lastAckDelay);
-       } else {
-           clock_Add(&when, &rx_softAckDelay);
-       }
-       if (!call->delayedAckEvent
-           || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
-           rxevent_Cancel(call->delayedAckEvent, call,
-                          RX_CALL_REFCOUNT_DELAY);
-            MUTEX_ENTER(&rx_refcnt_mutex);
-           CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
-            MUTEX_EXIT(&rx_refcnt_mutex);
-           call->delayedAckEvent =
-               rxevent_PostNow(&when, &now, rxi_SendDelayedAck, call, 0);
-       }
+       if (haveLast && !(flags & RX_CLIENT_INITIATED))
+           rxi_PostDelayedAckEvent(call, &rx_lastAckDelay);
+       else
+           rxi_PostDelayedAckEvent(call, &rx_softAckDelay);
     } else if (call->flags & RX_CALL_RECEIVE_DONE) {
        rxevent_Cancel(call->delayedAckEvent, call, RX_CALL_REFCOUNT_DELAY);
     }
index b308c3e..5473d5c 100644 (file)
@@ -121,8 +121,7 @@ extern void rxi_AttachServerProc(struct rx_call *call,
                                 struct rx_call **newcallp);
 extern void rxi_AckAll(struct rxevent *event, struct rx_call *call,
                       char *dummy);
-extern void rxi_SendDelayedAck(struct rxevent *event,
-                              void *call /* struct rx_call *call */, void *dummy);
+extern void rxi_PostDelayedAckEvent(struct rx_call *call, struct clock *now);
 extern void rxi_ClearTransmitQueue(struct rx_call *call,
                                   int force);
 extern void rxi_ClearReceiveQueue(struct rx_call *call);
index 019a4f7..6fc124b 100644 (file)
@@ -176,25 +176,9 @@ rxi_ReadProc(struct rx_call *call, char *buf,
                                               RX_CALL_REFCOUNT_DELAY);
                                rxi_SendAck(call, 0, 0, RX_ACK_DELAY, 0);
                            } else {
-                               struct clock when, now;
-                               clock_GetTime(&now);
-                               when = now;
                                /* Delay to consolidate ack packets */
-                               clock_Add(&when, &rx_hardAckDelay);
-                               if (!call->delayedAckEvent
-                                   || clock_Gt(&call->delayedAckEvent->
-                                               eventTime, &when)) {
-                                   rxevent_Cancel(call->delayedAckEvent,
-                                                  call,
-                                                  RX_CALL_REFCOUNT_DELAY);
-                                    MUTEX_ENTER(&rx_refcnt_mutex);
-                                   CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
-                                    MUTEX_EXIT(&rx_refcnt_mutex);
-                                    call->delayedAckEvent =
-                                     rxevent_PostNow(&when, &now,
-                                                    rxi_SendDelayedAck, call,
-                                                    0);
-                               }
+                               rxi_PostDelayedAckEvent(call,
+                                                       &rx_hardAckDelay);
                            }
                        }
                        break;
@@ -544,21 +528,8 @@ rxi_FillReadVec(struct rx_call *call, afs_uint32 serial)
            rxi_SendAck(call, 0, serial, RX_ACK_DELAY, 0);
            didHardAck = 1;
        } else {
-           struct clock when, now;
-           clock_GetTime(&now);
-           when = now;
            /* Delay to consolidate ack packets */
-           clock_Add(&when, &rx_hardAckDelay);
-           if (!call->delayedAckEvent
-               || clock_Gt(&call->delayedAckEvent->eventTime, &when)) {
-               rxevent_Cancel(call->delayedAckEvent, call,
-                              RX_CALL_REFCOUNT_DELAY);
-                MUTEX_ENTER(&rx_refcnt_mutex);
-               CALL_HOLD(call, RX_CALL_REFCOUNT_DELAY);
-                MUTEX_EXIT(&rx_refcnt_mutex);
-               call->delayedAckEvent =
-                   rxevent_PostNow(&when, &now, rxi_SendDelayedAck, call, 0);
-           }
+           rxi_PostDelayedAckEvent(call, &rx_hardAckDelay);
        }
     }
     return didHardAck;