Annotation of kernel/bsd/netiso/tp_timer.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*-
                     26:  * Copyright (c) 1991, 1993
                     27:  *     The Regents of the University of California.  All rights reserved.
                     28:  *
                     29:  * Redistribution and use in source and binary forms, with or without
                     30:  * modification, are permitted provided that the following conditions
                     31:  * are met:
                     32:  * 1. Redistributions of source code must retain the above copyright
                     33:  *    notice, this list of conditions and the following disclaimer.
                     34:  * 2. Redistributions in binary form must reproduce the above copyright
                     35:  *    notice, this list of conditions and the following disclaimer in the
                     36:  *    documentation and/or other materials provided with the distribution.
                     37:  * 3. All advertising materials mentioning features or use of this software
                     38:  *    must display the following acknowledgement:
                     39:  *     This product includes software developed by the University of
                     40:  *     California, Berkeley and its contributors.
                     41:  * 4. Neither the name of the University nor the names of its contributors
                     42:  *    may be used to endorse or promote products derived from this software
                     43:  *    without specific prior written permission.
                     44:  *
                     45:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     46:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     47:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     48:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     49:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     50:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     51:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     52:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     53:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     54:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     55:  * SUCH DAMAGE.
                     56:  *
                     57:  *     @(#)tp_timer.c  8.1 (Berkeley) 6/10/93
                     58:  */
                     59: 
                     60: /***********************************************************
                     61:                Copyright IBM Corporation 1987
                     62: 
                     63:                       All Rights Reserved
                     64: 
                     65: Permission to use, copy, modify, and distribute this software and its 
                     66: documentation for any purpose and without fee is hereby granted, 
                     67: provided that the above copyright notice appear in all copies and that
                     68: both that copyright notice and this permission notice appear in 
                     69: supporting documentation, and that the name of IBM not be
                     70: used in advertising or publicity pertaining to distribution of the
                     71: software without specific, written prior permission.  
                     72: 
                     73: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     74: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     75: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     76: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     77: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     78: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     79: SOFTWARE.
                     80: 
                     81: ******************************************************************/
                     82: 
                     83: /*
                     84:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
                     85:  */
                     86: /* 
                     87:  * ARGO TP
                     88:  */
                     89: 
                     90: #include <sys/param.h>
                     91: #include <sys/systm.h>
                     92: #include <sys/time.h>
                     93: #include <sys/malloc.h>
                     94: #include <sys/protosw.h>
                     95: #include <sys/socket.h>
                     96: #include <sys/kernel.h>
                     97: 
                     98: #include <netiso/argo_debug.h>
                     99: #include <netiso/tp_param.h>
                    100: #include <netiso/tp_timer.h>
                    101: #include <netiso/tp_stat.h>
                    102: #include <netiso/tp_pcb.h>
                    103: #include <netiso/tp_tpdu.h>
                    104: #include <netiso/tp_trace.h>
                    105: #include <netiso/tp_seq.h>
                    106: 
                    107: struct tp_ref *tp_ref;
                    108: int    tp_rttdiv, tp_rttadd, N_TPREF = 127;
                    109: struct tp_refinfo tp_refinfo;
                    110: struct tp_pcb *tp_ftimeolist = (struct tp_pcb *)&tp_ftimeolist;
                    111: 
                    112: /*
                    113:  * CALLED FROM:
                    114:  *  at autoconfig time from tp_init() 
                    115:  *     a combo of event, state, predicate
                    116:  * FUNCTION and ARGUMENTS:
                    117:  *  initialize data structures for the timers
                    118:  */
                    119: void
                    120: tp_timerinit()
                    121: {
                    122:        register int s;
                    123:        /*
                    124:         * Initialize storage
                    125:         */
                    126:        if (tp_refinfo.tpr_base)
                    127:                return;
                    128:        tp_refinfo.tpr_size = N_TPREF + 1;  /* Need to start somewhere */
                    129:        s = sizeof(*tp_ref) * tp_refinfo.tpr_size;
                    130: //     if ((tp_ref = (struct tp_ref *) malloc(s, M_PCB, M_NOWAIT)) == 0)
                    131:        MALLOC(tp_ref, struct tp_ref *, s, M_PCB, M_NOWAIT);
                    132:        if (tp_ref == 0)
                    133:                panic("tp_timerinit");
                    134:        bzero((caddr_t)tp_ref, (unsigned) s);
                    135:        tp_refinfo.tpr_base = tp_ref;
                    136:        tp_rttdiv = hz / PR_SLOWHZ;
                    137:        tp_rttadd = (2 * tp_rttdiv) - 1;
                    138: }
                    139: #ifdef TP_DEBUG_TIMERS
                    140: /**********************  e timers *************************/
                    141: 
                    142: /*
                    143:  * CALLED FROM:
                    144:  *  tp.trans all over
                    145:  * FUNCTION and ARGUMENTS:
                    146:  * Set an E type timer.
                    147:  */
                    148: void
                    149: tp_etimeout(tpcb, fun, ticks)
                    150:        register struct tp_pcb  *tpcb;
                    151:        int                                     fun;    /* function to be called */
                    152:        int                                             ticks;
                    153: {
                    154: 
                    155:        register u_int *callp;
                    156:        IFDEBUG(D_TIMER)
                    157:                printf("etimeout pcb 0x%x state 0x%x\n", tpcb, tpcb->tp_state);
                    158:        ENDDEBUG
                    159:        IFTRACE(D_TIMER)
                    160:                tptrace(TPPTmisc, "tp_etimeout ref refstate tks Etick", tpcb->tp_lref,
                    161:                tpcb->tp_state, ticks, tp_stat.ts_Eticks);
                    162:        ENDTRACE
                    163:        if (tpcb == 0)
                    164:                return;
                    165:        IncStat(ts_Eset);
                    166:        if (ticks == 0)
                    167:                ticks = 1;
                    168:        callp = tpcb->tp_timer + fun;
                    169:        if (*callp == 0 || *callp > ticks)
                    170:                *callp = ticks;
                    171: }
                    172: 
                    173: /*
                    174:  * CALLED FROM:
                    175:  *  tp.trans all over
                    176:  * FUNCTION and ARGUMENTS:
                    177:  *  Cancel all occurrences of E-timer function (fun) for reference (refp)
                    178:  */
                    179: void
                    180: tp_euntimeout(tpcb, fun)
                    181:        register struct tp_pcb  *tpcb;
                    182:        int                       fun;
                    183: {
                    184:        IFTRACE(D_TIMER)
                    185:                tptrace(TPPTmisc, "tp_euntimeout ref", tpcb->tp_lref, 0, 0, 0);
                    186:        ENDTRACE
                    187: 
                    188:        if (tpcb)
                    189:                tpcb->tp_timer[fun] = 0;
                    190: }
                    191: 
                    192: /****************  c timers **********************
                    193:  *
                    194:  * These are not chained together; they sit
                    195:  * in the tp_ref structure. they are the kind that
                    196:  * are typically cancelled so it's faster not to
                    197:  * mess with the chains
                    198:  */
                    199: #endif
                    200: /*
                    201:  * CALLED FROM:
                    202:  *  the clock, every 500 ms
                    203:  * FUNCTION and ARGUMENTS:
                    204:  *  Look for open references with active timers.
                    205:  *  If they exist, call the appropriate timer routines to update
                    206:  *  the timers and possibly generate events.
                    207:  */
                    208: ProtoHook
                    209: tp_slowtimo()
                    210: {
                    211:        register u_int  *cp;
                    212:        register struct tp_ref          *rp;
                    213:        struct tp_pcb           *tpcb;
                    214:        struct tp_event         E;
                    215:        int                             s = splnet(), t;
                    216: 
                    217:        /* check only open reference structures */
                    218:        IncStat(ts_Cticks);
                    219:        /* tp_ref[0] is never used */
                    220:        for (rp = tp_ref + tp_refinfo.tpr_maxopen; rp > tp_ref; rp--) {
                    221:                if ((tpcb = rp->tpr_pcb) == 0 || tpcb->tp_refstate < REF_OPEN) 
                    222:                        continue;
                    223:                /* check the timers */
                    224:                for (t = 0; t < TM_NTIMERS; t++) {
                    225:                        cp = tpcb->tp_timer + t;
                    226:                        if (*cp && --(*cp) <= 0 ) {
                    227:                                *cp = 0;
                    228:                                E.ev_number = t;
                    229:                                IFDEBUG(D_TIMER)
                    230:                                        printf("tp_slowtimo: pcb 0x%x t %d\n",
                    231:                                                        tpcb, t);
                    232:                                ENDDEBUG
                    233:                                IncStat(ts_Cexpired);
                    234:                                tp_driver(tpcb, &E);
                    235:                                if (t == TM_reference && tpcb->tp_state == TP_CLOSED) {
                    236:                                        if (tpcb->tp_notdetached) {
                    237:                                                IFDEBUG(D_CONN)
                    238:                                                        printf("PRU_DETACH: not detached\n");
                    239:                                                ENDDEBUG
                    240:                                                tp_detach(tpcb);
                    241:                                        }
                    242:                                        /* XXX wart; where else to do it? */
                    243:                                        free((caddr_t)tpcb, M_PCB);
                    244:                                }
                    245:                        }
                    246:                }
                    247:        }
                    248:        splx(s);
                    249:        return 0;
                    250: }
                    251: 
                    252: /*
                    253:  * Called From: tp.trans from tp_slowtimo() -- retransmission timer went off.
                    254:  */
                    255: tp_data_retrans(tpcb)
                    256: register struct tp_pcb *tpcb;
                    257: {
                    258:        int rexmt, win;
                    259:        tpcb->tp_rttemit = 0;   /* cancel current round trip time */
                    260:        tpcb->tp_dupacks = 0;
                    261:        tpcb->tp_sndnxt = tpcb->tp_snduna;
                    262:        if (tpcb->tp_fcredit == 0) {
                    263:                /*
                    264:                 * We transmitted new data, started timing it and the window
                    265:                 * got shrunk under us.  This can only happen if all data
                    266:                 * that they wanted us to send got acked, so don't
                    267:                 * bother shrinking the congestion windows, et. al.
                    268:                 * The retransmission timer should have been reset in goodack()
                    269:                 */
                    270:                IFDEBUG(D_ACKRECV)
                    271:                        printf("tp_data_retrans: 0 window tpcb 0x%x una 0x%x\n",
                    272:                                tpcb, tpcb->tp_snduna);
                    273:                ENDDEBUG
                    274:                tpcb->tp_rxtshift = 0;
                    275:                tpcb->tp_timer[TM_data_retrans] = 0;
                    276:                tpcb->tp_timer[TM_sendack] = tpcb->tp_dt_ticks;
                    277:                return;
                    278:        }
                    279:        rexmt = tpcb->tp_dt_ticks << min(tpcb->tp_rxtshift, TP_MAXRXTSHIFT);
                    280:        win = min(tpcb->tp_fcredit, (tpcb->tp_cong_win / tpcb->tp_l_tpdusize / 2));
                    281:        win = max(win, 2);
                    282:        tpcb->tp_cong_win = tpcb->tp_l_tpdusize;        /* slow start again. */
                    283:        tpcb->tp_ssthresh = win * tpcb->tp_l_tpdusize;
                    284:        /* We're losing; our srtt estimate is probably bogus.
                    285:         * Clobber it so we'll take the next rtt measurement as our srtt;
                    286:         * Maintain current rxt times until then.
                    287:         */
                    288:        if (++tpcb->tp_rxtshift > TP_NRETRANS / 4) {
                    289:                /* tpcb->tp_nlprotosw->nlp_losing(tpcb->tp_npcb) someday */
                    290:                tpcb->tp_rtt = 0;
                    291:        }
                    292:        TP_RANGESET(tpcb->tp_rxtcur, rexmt, tpcb->tp_peer_acktime, 128);
                    293:        tpcb->tp_timer[TM_data_retrans] = tpcb->tp_rxtcur;
                    294:        tp_send(tpcb);
                    295: }
                    296: 
                    297: int
                    298: tp_fasttimo()
                    299: {
                    300:        register struct tp_pcb *t;
                    301:        int s = splnet();
                    302:        struct tp_event         E;
                    303: 
                    304:        E.ev_number = TM_sendack;
                    305:        while ((t = tp_ftimeolist) != (struct tp_pcb *)&tp_ftimeolist) {
                    306:                if (t == 0) {
                    307:                        printf("tp_fasttimeo: should panic");
                    308:                        tp_ftimeolist = (struct tp_pcb *)&tp_ftimeolist;
                    309:                } else {
                    310:                        if (t->tp_flags & TPF_DELACK) {
                    311:                                IncStat(ts_Fdelack);
                    312:                                tp_driver(t, &E);
                    313:                                t->tp_flags &= ~TPF_DELACK;
                    314:                        } else
                    315:                                IncStat(ts_Fpruned);
                    316:                        tp_ftimeolist = t->tp_fasttimeo;
                    317:                        t->tp_fasttimeo = 0;
                    318:                }
                    319:        }
                    320:        splx(s);
                    321: }
                    322: 
                    323: #ifdef TP_DEBUG_TIMERS
                    324: /*
                    325:  * CALLED FROM:
                    326:  *  tp.trans, tp_emit()
                    327:  * FUNCTION and ARGUMENTS:
                    328:  *     Set a C type timer of type (which) to go off after (ticks) time.
                    329:  */
                    330: void
                    331: tp_ctimeout(tpcb, which, ticks)
                    332:        register struct tp_pcb  *tpcb;
                    333:        int                                     which, ticks; 
                    334: {
                    335: 
                    336:        IFTRACE(D_TIMER)
                    337:                tptrace(TPPTmisc, "tp_ctimeout ref which tpcb active", 
                    338:                        tpcb->tp_lref, which, tpcb, tpcb->tp_timer[which]);
                    339:        ENDTRACE
                    340:        if(tpcb->tp_timer[which])
                    341:                IncStat(ts_Ccan_act);
                    342:        IncStat(ts_Cset);
                    343:        if (ticks <= 0)
                    344:                ticks = 1;
                    345:        tpcb->tp_timer[which] = ticks;
                    346: }
                    347: 
                    348: /*
                    349:  * CALLED FROM:
                    350:  *  tp.trans 
                    351:  * FUNCTION and ARGUMENTS:
                    352:  *     Version of tp_ctimeout that resets the C-type time if the 
                    353:  *     parameter (ticks) is > the current value of the timer.
                    354:  */
                    355: void
                    356: tp_ctimeout_MIN(tpcb, which, ticks)
                    357:        register struct tp_pcb  *tpcb;
                    358:        int                                             which, ticks; 
                    359: {
                    360:        IFTRACE(D_TIMER)
                    361:                tptrace(TPPTmisc, "tp_ctimeout_MIN ref which tpcb active", 
                    362:                        tpcb->tp_lref, which, tpcb, tpcb->tp_timer[which]);
                    363:        ENDTRACE
                    364:        IncStat(ts_Cset);
                    365:        if (tpcb->tp_timer[which])  {
                    366:                tpcb->tp_timer[which] = min(ticks, tpcb->tp_timer[which]);
                    367:                IncStat(ts_Ccan_act);
                    368:        } else
                    369:                tpcb->tp_timer[which] = ticks;
                    370: }
                    371: 
                    372: /*
                    373:  * CALLED FROM:
                    374:  *  tp.trans
                    375:  * FUNCTION and ARGUMENTS:
                    376:  *  Cancel the (which) timer in the ref structure indicated by (refp).
                    377:  */
                    378: void
                    379: tp_cuntimeout(tpcb, which)
                    380:        register struct tp_pcb  *tpcb;
                    381:        int                                             which;
                    382: {
                    383:        IFDEBUG(D_TIMER)
                    384:                printf("tp_cuntimeout(0x%x, %d) active %d\n",
                    385:                                tpcb, which, tpcb->tp_timer[which]);
                    386:        ENDDEBUG
                    387: 
                    388:        IFTRACE(D_TIMER)
                    389:                tptrace(TPPTmisc, "tp_cuntimeout ref which, active", refp-tp_ref, 
                    390:                        which, tpcb->tp_timer[which], 0);
                    391:        ENDTRACE
                    392: 
                    393:        if (tpcb->tp_timer[which])
                    394:                IncStat(ts_Ccan_act);
                    395:        else
                    396:                IncStat(ts_Ccan_inact);
                    397:        tpcb->tp_timer[which] = 0;
                    398: }
                    399: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.