OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [decnet/] [dn_timer.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * DECnet       An implementation of the DECnet protocol suite for the LINUX
3
 *              operating system.  DECnet is implemented using the  BSD Socket
4
 *              interface as the means of communication with the user level.
5
 *
6
 *              DECnet Socket Timer Functions
7
 *
8
 * Author:      Steve Whitehouse <SteveW@ACM.org>
9
 *
10
 *
11
 * Changes:
12
 *       Steve Whitehouse      : Made keepalive timer part of the same
13
 *                               timer idea.
14
 *       Steve Whitehouse      : Added checks for sk->sock_readers
15
 *       David S. Miller       : New socket locking
16
 *       Steve Whitehouse      : Timer grabs socket ref.
17
 */
18
#include <linux/net.h>
19
#include <linux/socket.h>
20
#include <linux/skbuff.h>
21
#include <linux/netdevice.h>
22
#include <linux/timer.h>
23
#include <linux/spinlock.h>
24
#include <net/sock.h>
25
#include <asm/atomic.h>
26
#include <net/dn.h>
27
 
28
/*
29
 * Fast timer is for delayed acks (200mS max)
30
 * Slow timer is for everything else (n * 500mS)
31
 */
32
 
33
#define FAST_INTERVAL (HZ/5)
34
#define SLOW_INTERVAL (HZ/2)
35
 
36
static void dn_slow_timer(unsigned long arg);
37
 
38
void dn_start_slow_timer(struct sock *sk)
39
{
40
        sk->timer.expires = jiffies + SLOW_INTERVAL;
41
        sk->timer.function = dn_slow_timer;
42
        sk->timer.data = (unsigned long)sk;
43
 
44
        add_timer(&sk->timer);
45
}
46
 
47
void dn_stop_slow_timer(struct sock *sk)
48
{
49
        del_timer(&sk->timer);
50
}
51
 
52
static void dn_slow_timer(unsigned long arg)
53
{
54
        struct sock *sk = (struct sock *)arg;
55
        struct dn_scp *scp = DN_SK(sk);
56
 
57
        sock_hold(sk);
58
        bh_lock_sock(sk);
59
 
60
        if (sk->lock.users != 0) {
61
                sk->timer.expires = jiffies + HZ / 10;
62
                add_timer(&sk->timer);
63
                goto out;
64
        }
65
 
66
        /*
67
         * The persist timer is the standard slow timer used for retransmits
68
         * in both connection establishment and disconnection as well as
69
         * in the RUN state. The different states are catered for by changing
70
         * the function pointer in the socket. Setting the timer to a value
71
         * of zero turns it off. We allow the persist_fxn to turn the
72
         * timer off in a permant way by returning non-zero, so that
73
         * timer based routines may remove sockets. This is why we have a
74
         * sock_hold()/sock_put() around the timer to prevent the socket
75
         * going away in the middle.
76
         */
77
        if (scp->persist && scp->persist_fxn) {
78
                if (scp->persist <= SLOW_INTERVAL) {
79
                        scp->persist = 0;
80
 
81
                        if (scp->persist_fxn(sk))
82
                                goto out;
83
                } else {
84
                        scp->persist -= SLOW_INTERVAL;
85
                }
86
        }
87
 
88
        /*
89
         * Check for keepalive timeout. After the other timer 'cos if
90
         * the previous timer caused a retransmit, we don't need to
91
         * do this. scp->stamp is the last time that we sent a packet.
92
         * The keepalive function sends a link service packet to the
93
         * other end. If it remains unacknowledged, the standard
94
         * socket timers will eventually shut the socket down. Each
95
         * time we do this, scp->stamp will be updated, thus
96
         * we won't try and send another until scp->keepalive has passed
97
         * since the last successful transmission.
98
         */
99
        if (scp->keepalive && scp->keepalive_fxn && (scp->state == DN_RUN)) {
100
                if ((jiffies - scp->stamp) >= scp->keepalive)
101
                        scp->keepalive_fxn(sk);
102
        }
103
 
104
        sk->timer.expires = jiffies + SLOW_INTERVAL;
105
 
106
        add_timer(&sk->timer);
107
out:
108
        bh_unlock_sock(sk);
109
        sock_put(sk);
110
}
111
 
112
static void dn_fast_timer(unsigned long arg)
113
{
114
        struct sock *sk = (struct sock *)arg;
115
        struct dn_scp *scp = DN_SK(sk);
116
 
117
        bh_lock_sock(sk);
118
        if (sk->lock.users != 0) {
119
                scp->delack_timer.expires = jiffies + HZ / 20;
120
                add_timer(&scp->delack_timer);
121
                goto out;
122
        }
123
 
124
        scp->delack_pending = 0;
125
 
126
        if (scp->delack_fxn)
127
                scp->delack_fxn(sk);
128
out:
129
        bh_unlock_sock(sk);
130
}
131
 
132
void dn_start_fast_timer(struct sock *sk)
133
{
134
        struct dn_scp *scp = DN_SK(sk);
135
 
136
        if (!scp->delack_pending) {
137
                scp->delack_pending = 1;
138
                init_timer(&scp->delack_timer);
139
                scp->delack_timer.expires = jiffies + FAST_INTERVAL;
140
                scp->delack_timer.data = (unsigned long)sk;
141
                scp->delack_timer.function = dn_fast_timer;
142
                add_timer(&scp->delack_timer);
143
        }
144
}
145
 
146
void dn_stop_fast_timer(struct sock *sk)
147
{
148
        struct dn_scp *scp = DN_SK(sk);
149
 
150
        if (scp->delack_pending) {
151
                scp->delack_pending = 0;
152
                del_timer(&scp->delack_timer);
153
        }
154
}
155
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.