Willy Tarreau | 7f062c4 | 2009-03-05 18:43:00 +0100 | [diff] [blame] | 1 | /* |
| 2 | include/proto/freq_ctr.h |
| 3 | This file contains macros and inline functions for frequency counters. |
| 4 | |
| 5 | Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu |
| 6 | |
| 7 | This library is free software; you can redistribute it and/or |
| 8 | modify it under the terms of the GNU Lesser General Public |
| 9 | License as published by the Free Software Foundation, version 2.1 |
| 10 | exclusively. |
| 11 | |
| 12 | This library is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | Lesser General Public License for more details. |
| 16 | |
| 17 | You should have received a copy of the GNU Lesser General Public |
| 18 | License along with this library; if not, write to the Free Software |
| 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ |
| 21 | |
| 22 | #ifndef _PROTO_FREQ_CTR_H |
| 23 | #define _PROTO_FREQ_CTR_H |
| 24 | |
| 25 | #include <common/config.h> |
| 26 | #include <types/freq_ctr.h> |
| 27 | |
| 28 | /* Rotate a frequency counter when current period is over. Must not be called |
| 29 | * during a valid period. It is important that it correctly initializes a null |
| 30 | * area. |
| 31 | */ |
| 32 | static inline void rotate_freq_ctr(struct freq_ctr *ctr) |
| 33 | { |
| 34 | ctr->prev_ctr = ctr->curr_ctr; |
| 35 | if (likely(now.tv_sec - ctr->curr_sec != 1)) { |
| 36 | /* we missed more than one second */ |
| 37 | ctr->prev_ctr = 0; |
| 38 | } |
| 39 | ctr->curr_sec = now.tv_sec; |
| 40 | ctr->curr_ctr = 0; /* leave it at the end to help gcc optimize it away */ |
| 41 | } |
| 42 | |
| 43 | /* Update a frequency counter by <inc> incremental units. It is automatically |
| 44 | * rotated if the period is over. It is important that it correctly initializes |
| 45 | * a null area. |
| 46 | */ |
| 47 | static inline void update_freq_ctr(struct freq_ctr *ctr, unsigned int inc) |
| 48 | { |
| 49 | if (likely(ctr->curr_sec == now.tv_sec)) { |
| 50 | ctr->curr_ctr += inc; |
| 51 | return; |
| 52 | } |
| 53 | rotate_freq_ctr(ctr); |
| 54 | ctr->curr_ctr = inc; |
| 55 | /* Note: later we may want to propagate the update to other counters */ |
| 56 | } |
| 57 | |
| 58 | /* Read a frequency counter taking history into account for missing time in |
| 59 | * current period. |
| 60 | */ |
| 61 | unsigned int read_freq_ctr(struct freq_ctr *ctr); |
| 62 | |
Willy Tarreau | 7958422 | 2009-03-06 09:18:27 +0100 | [diff] [blame] | 63 | /* returns the number of remaining events that can occur on this freq counter |
| 64 | * while respecting <freq> and taking into account that <pend> events are |
| 65 | * already known to be pending. Returns 0 if limit was reached. |
| 66 | */ |
| 67 | unsigned int freq_ctr_remain(struct freq_ctr *ctr, unsigned int freq, unsigned int pend); |
| 68 | |
| 69 | /* return the expected wait time in ms before the next event may occur, |
| 70 | * respecting frequency <freq>, and assuming there may already be some pending |
| 71 | * events. It returns zero if we can proceed immediately, otherwise the wait |
| 72 | * time, which will be rounded down 1ms for better accuracy, with a minimum |
| 73 | * of one ms. |
| 74 | */ |
| 75 | unsigned int next_event_delay(struct freq_ctr *ctr, unsigned int freq, unsigned int pend); |
| 76 | |
Willy Tarreau | 7f062c4 | 2009-03-05 18:43:00 +0100 | [diff] [blame] | 77 | #endif /* _PROTO_FREQ_CTR_H */ |
| 78 | |
| 79 | /* |
| 80 | * Local variables: |
| 81 | * c-indent-level: 8 |
| 82 | * c-basic-offset: 8 |
| 83 | * End: |
| 84 | */ |