* Process all "<=" type of bw_meter that should be processed now, * and for each entry prepare an upcall if necessary. Each processed * entry is rescheduled again for the (periodic) processing. * * This is run periodically (once per second normally). On each round, * all the potentially matching entries are in the hash slot that we are * looking at. */
| 2193 | * looking at. |
| 2194 | */ |
| 2195 | static void |
| 2196 | bw_meter_process() |
| 2197 | { |
| 2198 | uint32_t loops; |
| 2199 | int i; |
| 2200 | struct timeval now, process_endtime; |
| 2201 | |
| 2202 | microtime(&now); |
| 2203 | if (V_last_tv_sec == now.tv_sec) |
| 2204 | return; /* nothing to do */ |
| 2205 | |
| 2206 | loops = now.tv_sec - V_last_tv_sec; |
| 2207 | V_last_tv_sec = now.tv_sec; |
| 2208 | if (loops > BW_METER_BUCKETS) |
| 2209 | loops = BW_METER_BUCKETS; |
| 2210 | |
| 2211 | MFC_LOCK(); |
| 2212 | /* |
| 2213 | * Process all bins of bw_meter entries from the one after the last |
| 2214 | * processed to the current one. On entry, i points to the last bucket |
| 2215 | * visited, so we need to increment i at the beginning of the loop. |
| 2216 | */ |
| 2217 | for (i = (now.tv_sec - loops) % BW_METER_BUCKETS; loops > 0; loops--) { |
| 2218 | struct bw_meter *x, *tmp_list; |
| 2219 | |
| 2220 | if (++i >= BW_METER_BUCKETS) |
| 2221 | i = 0; |
| 2222 | |
| 2223 | /* Disconnect the list of bw_meter entries from the bin */ |
| 2224 | tmp_list = V_bw_meter_timers[i]; |
| 2225 | V_bw_meter_timers[i] = NULL; |
| 2226 | |
| 2227 | /* Process the list of bw_meter entries */ |
| 2228 | while (tmp_list != NULL) { |
| 2229 | x = tmp_list; |
| 2230 | tmp_list = tmp_list->bm_time_next; |
| 2231 | |
| 2232 | /* Test if the time interval is over */ |
| 2233 | process_endtime = x->bm_start_time; |
| 2234 | BW_TIMEVALADD(&process_endtime, &x->bm_threshold.b_time); |
| 2235 | if (BW_TIMEVALCMP(&process_endtime, &now, >)) { |
| 2236 | /* Not yet: reschedule, but don't reset */ |
| 2237 | int time_hash; |
| 2238 | |
| 2239 | BW_METER_TIMEHASH(x, time_hash); |
| 2240 | if (time_hash == i && process_endtime.tv_sec == now.tv_sec) { |
| 2241 | /* |
| 2242 | * XXX: somehow the bin processing is a bit ahead of time. |
| 2243 | * Put the entry in the next bin. |
| 2244 | */ |
| 2245 | if (++time_hash >= BW_METER_BUCKETS) |
| 2246 | time_hash = 0; |
| 2247 | } |
| 2248 | x->bm_time_next = V_bw_meter_timers[time_hash]; |
| 2249 | V_bw_meter_timers[time_hash] = x; |
| 2250 | x->bm_time_hash = time_hash; |
| 2251 | |
| 2252 | continue; |
no test coverage detected