summaryrefslogtreecommitdiffstats
path: root/plugins/vcgn-plugin/vcgn/spp_timers.h
blob: afb0147b2edc1bf2b6d5b5f4caa1abf25b424176 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* 
 *------------------------------------------------------------------
 * spp_timers.h
 *
 * Copyright (c) 2008-2009 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *------------------------------------------------------------------
 */
#ifndef __SPP_TIMERS_H__
#define __SPP_TIMERS_H__


typedef struct d_list_el_ {
    struct d_list_el_ *next;
    struct d_list_el_ *prev;
} d_list_el_t;

/*
 * d_list_init
 */

static inline void d_list_init (d_list_el_t *headp)
{
    headp->prev = headp->next = headp;
}

/*
 * d_list_init - add at head of list
 */

static inline void d_list_add_head (d_list_el_t *headp, 
                                                  d_list_el_t *elp)
{
    ASSERT(elp->prev == elp);     /* multiple enqueue, BAD! */
    ASSERT(elp->next == elp);

    elp->next = headp->next;
    headp->next = elp;
    elp->prev = elp->next->prev;
    elp->next->prev = elp;
}

/*
 * d_list_add_tail - add element at tail of list
 */
static inline void d_list_add_tail (d_list_el_t *headp, 
                                                  d_list_el_t *elp)
{
    ASSERT(elp->prev == elp);     /* multiple enqueue, BAD! */
    ASSERT(elp->next == elp);

    headp = headp->prev;

    elp->next = headp->next;
    headp->next = elp;
    elp->prev = elp->next->prev;
    elp->next->prev = elp;
}

/*
 * d_list_rem_head - removes first element from list
 */
static inline d_list_el_t *d_list_rem_head (d_list_el_t *headp)
{
    d_list_el_t *elp;

    elp = headp->next;
    if (elp == headp)
        return (NULL);
    headp->next = elp->next;
    elp->next->prev = elp->prev;

    elp->next = elp->prev = elp;
    return (elp);
}

/*
 * d_list_rem_elem - removes specific element from list.
 */
static inline void d_list_rem_elem (d_list_el_t *elp)
{
    d_list_el_t *headp;

    headp = elp->prev;

    headp->next = elp->next;
    elp->next->prev = elp->prev;
    elp->next = elp->prev = elp;
}

#define TIMER_BKTS_PER_WHEEL	128 /* power of 2, please */
#define TIMER_NWHEELS   	4

typedef struct {
    i32 curindex;               /* current index for this wheel */
    d_list_el_t *bkts;          /* vector of bucket listheads */
} spp_timer_wheel_t;


typedef struct {
    u64 next_run_ticks;         /* Next time we expire timers */
    spp_timer_wheel_t **wheels; /* pointers to wheels */
} spp_timer_axle_t;


typedef struct {
    d_list_el_t el;
    u16 cb_index;
    u16 flags;
    u64 expires;
} spp_timer_t;

#define SPP_TIMER_RUNNING	0x0001


/*
 * prototypes
 */
void spp_timer_set_ticks_per_ms(u64);
void spp_timer_axle_init (spp_timer_axle_t *ta);
void spp_timer_expire(spp_timer_axle_t *ta, u64 now);
void spp_timer_final_init(void);

void spp_timer_start(spp_timer_t *tp);
void spp_timer_start_axle(spp_timer_axle_t *ta, spp_timer_t *tp);
void spp_timer_stop(spp_timer_t *tp);
u16 spp_timer_register_callback (void (*fp)(spp_timer_t *));

#endif /* __SPP_TIMERS_H__ */