📄 delay_pools.c
字号:
(class2->aggregate += rates->aggregate.restore_bps * incr) > rates->aggregate.max_bytes) class2->aggregate = rates->aggregate.max_bytes; if ((restore_bytes = rates->individual.restore_bps) == -1) return; restore_bytes *= incr; if (class2->individual_255_used) i = 255; else i = 0; for (;;) { if (i != 255 && class2->individual_map[i] == 255) return; if (class2->individual[i] != rates->individual.max_bytes && (class2->individual[i] += restore_bytes) > rates->individual.max_bytes) class2->individual[i] = rates->individual.max_bytes; if (++i == 255) return; }}static voiddelayUpdateClass3(class3DelayPool * class3, delaySpecSet * rates, int incr){ int individual_restore_bytes, network_restore_bytes; int mpos; unsigned char i, j; /* delaySetSpec may be pointer to partial structure so MUST pass by * reference. */ if (rates->aggregate.restore_bps != -1 && (class3->aggregate += rates->aggregate.restore_bps * incr) > rates->aggregate.max_bytes) class3->aggregate = rates->aggregate.max_bytes; /* the following line deliberately uses &, not &&, in an if statement * to avoid conditional execution */ if (((network_restore_bytes = rates->network.restore_bps) == -1) & ((individual_restore_bytes = rates->individual.restore_bps) == -1)) return; individual_restore_bytes *= incr; network_restore_bytes *= incr; if (class3->network_255_used) i = 255; else i = 0; for (;;) { if (i != 255 && class3->network_map[i] == 255) return; if (individual_restore_bytes != -incr) { mpos = i << 8; if (class3->individual_255_used[i / 8] & (1 << (i % 8))) j = 255; else j = 0; for (;;) { if (j != 255 && class3->individual_map[i][j] == 255) break; if (class3->individual[mpos] != rates->individual.max_bytes && (class3->individual[mpos] += individual_restore_bytes) > rates->individual.max_bytes) class3->individual[mpos] = rates->individual.max_bytes; mpos++; if (j == 255) mpos -= 256; if (++j == 255) break; } } if (network_restore_bytes != -incr && class3->network[i] != rates->network.max_bytes && (class3->network[i] += network_restore_bytes) > rates->network.max_bytes) class3->network[i] = rates->network.max_bytes; if (++i == 255) return; }}voiddelayPoolsUpdate(void *unused){ int incr = squid_curtime - delay_pools_last_update; unsigned short i; unsigned char class; if (!Config.Delay.pools) return; eventAdd("delayPoolsUpdate", delayPoolsUpdate, NULL, 1.0, 1); if (incr < 1) return; delay_pools_last_update = squid_curtime; for (i = 0; i < Config.Delay.pools; i++) { class = Config.Delay.class[i]; if (!class) continue; switch (class) { case 1: delayUpdateClass1(delay_data[i].class1, Config.Delay.rates[i], incr); break; case 2: delayUpdateClass2(delay_data[i].class2, Config.Delay.rates[i], incr); break; case 3: delayUpdateClass3(delay_data[i].class3, Config.Delay.rates[i], incr); break; default: assert(0); } }}/* * this returns the number of bytes the client is permitted. it does not take * into account bytes already buffered - that is up to the caller. */intdelayBytesWanted(delay_id d, int min, int max){ unsigned short position = d & 0xFFFF; unsigned short pool = (d >> 16) - 1; unsigned char class = (pool == 0xFFFF) ? 0 : Config.Delay.class[pool]; int nbytes = max; switch (class) { case 0: break; case 1: if (Config.Delay.rates[pool]->aggregate.restore_bps != -1) nbytes = XMIN(nbytes, delay_data[pool].class1->aggregate); break; case 2: if (Config.Delay.rates[pool]->aggregate.restore_bps != -1) nbytes = XMIN(nbytes, delay_data[pool].class2->aggregate); if (Config.Delay.rates[pool]->individual.restore_bps != -1) nbytes = XMIN(nbytes, delay_data[pool].class2->individual[position]); break; case 3: if (Config.Delay.rates[pool]->aggregate.restore_bps != -1) nbytes = XMIN(nbytes, delay_data[pool].class3->aggregate); if (Config.Delay.rates[pool]->individual.restore_bps != -1) nbytes = XMIN(nbytes, delay_data[pool].class3->individual[position]); if (Config.Delay.rates[pool]->network.restore_bps != -1) nbytes = XMIN(nbytes, delay_data[pool].class3->network[position >> 8]); break; default: fatalf("delayBytesWanted: Invalid class %d\n", class); break; } nbytes = XMAX(min, nbytes); return nbytes;}/* * this records actual bytes recieved. always recorded, even if the * class is disabled - it's more efficient to just do it than to do all * the checks. */voiddelayBytesIn(delay_id d, int qty){ unsigned short position = d & 0xFFFF; unsigned short pool = (d >> 16) - 1; unsigned char class; if (pool == 0xFFFF) return; class = Config.Delay.class[pool]; switch (class) { case 1: delay_data[pool].class1->aggregate -= qty; return; case 2: delay_data[pool].class2->aggregate -= qty; delay_data[pool].class2->individual[position] -= qty; return; case 3: delay_data[pool].class3->aggregate -= qty; delay_data[pool].class3->network[position >> 8] -= qty; delay_data[pool].class3->individual[position] -= qty; return; } fatalf("delayBytesWanted: Invalid class %d\n", class); assert(0);}intdelayMostBytesWanted(const MemObject * mem, int max){ int i = 0; int found = 0; store_client *sc; for (sc = mem->clients; sc; sc = sc->next) { if (sc->callback_data == NULL) /* open slot */ continue; if (sc->type != STORE_MEM_CLIENT) continue; i = delayBytesWanted(sc->delay_id, i, max); found = 1; } return found ? i : max;}delay_iddelayMostBytesAllowed(const MemObject * mem){ int j; int jmax = -1; store_client *sc; delay_id d = 0; for (sc = mem->clients; sc; sc = sc->next) { if (sc->callback_data == NULL) /* open slot */ continue; if (sc->type != STORE_MEM_CLIENT) continue; j = delayBytesWanted(sc->delay_id, 0, SQUID_TCP_SO_RCVBUF); if (j > jmax) { jmax = j; d = sc->delay_id; } } return d;}voiddelaySetStoreClient(StoreEntry * e, void *data, delay_id delay_id){ store_client *sc = storeClientListSearch(e->mem_obj, data); assert(sc != NULL); sc->delay_id = delay_id; delayRegisterDelayIdPtr(&sc->delay_id);}static voiddelayPoolStatsAg(StoreEntry * sentry, delaySpecSet * rate, int ag){ /* note - always pass delaySpecSet's by reference as may be incomplete */ if (rate->aggregate.restore_bps == -1) { storeAppendPrintf(sentry, "\tAggregate:\n\t\tDisabled.\n\n"); return; } storeAppendPrintf(sentry, "\tAggregate:\n"); storeAppendPrintf(sentry, "\t\tMax: %d\n", rate->aggregate.max_bytes); storeAppendPrintf(sentry, "\t\tRestore: %d\n", rate->aggregate.restore_bps); storeAppendPrintf(sentry, "\t\tCurrent: %d\n\n", ag);}static voiddelayPoolStats1(StoreEntry * sentry, unsigned short pool){ /* must be a reference only - partially malloc()d struct */ delaySpecSet *rate = Config.Delay.rates[pool]; storeAppendPrintf(sentry, "Pool: %d\n\tClass: 1\n\n", pool + 1); delayPoolStatsAg(sentry, rate, delay_data[pool].class1->aggregate);}static voiddelayPoolStats2(StoreEntry * sentry, unsigned short pool){ /* must be a reference only - partially malloc()d struct */ delaySpecSet *rate = Config.Delay.rates[pool]; class2DelayPool *class2 = delay_data[pool].class2; unsigned char shown = 0, i; storeAppendPrintf(sentry, "Pool: %d\n\tClass: 2\n\n", pool + 1); delayPoolStatsAg(sentry, rate, class2->aggregate); if (rate->individual.restore_bps == -1) { storeAppendPrintf(sentry, "\tIndividual:\n\t\tDisabled.\n\n"); return; } storeAppendPrintf(sentry, "\tIndividual:\n"); storeAppendPrintf(sentry, "\t\tMax: %d\n", rate->individual.max_bytes); storeAppendPrintf(sentry, "\t\tRate: %d\n", rate->individual.restore_bps); storeAppendPrintf(sentry, "\t\tCurrent: "); for (i = 0;; i++) { if (class2->individual_map[i] == 255) break; storeAppendPrintf(sentry, "%d:%d ", class2->individual_map[i], class2->individual[i]); shown = 1; } if (class2->individual_255_used) { storeAppendPrintf(sentry, "%d:%d ", 255, class2->individual[255]); shown = 1; } if (!shown) storeAppendPrintf(sentry, "Not used yet."); storeAppendPrintf(sentry, "\n\n");}static voiddelayPoolStats3(StoreEntry * sentry, unsigned short pool){ /* fully malloc()d struct in this case only */ delaySpecSet *rate = Config.Delay.rates[pool]; class3DelayPool *class3 = delay_data[pool].class3; unsigned char shown = 0, i, j; storeAppendPrintf(sentry, "Pool: %d\n\tClass: 3\n\n", pool + 1); delayPoolStatsAg(sentry, rate, class3->aggregate); if (rate->network.restore_bps == -1) { storeAppendPrintf(sentry, "\tNetwork:\n\t\tDisabled."); } else { storeAppendPrintf(sentry, "\tNetwork:\n"); storeAppendPrintf(sentry, "\t\tMax: %d\n", rate->network.max_bytes); storeAppendPrintf(sentry, "\t\tRate: %d\n", rate->network.restore_bps); storeAppendPrintf(sentry, "\t\tCurrent: "); for (i = 0;; i++) { if (class3->network_map[i] == 255) break; storeAppendPrintf(sentry, "%d:%d ", class3->network_map[i], class3->network[i]); shown = 1; } if (class3->network_255_used) { storeAppendPrintf(sentry, "%d:%d ", 255, class3->network[255]); shown = 1; } if (!shown) storeAppendPrintf(sentry, "Not used yet."); } storeAppendPrintf(sentry, "\n\n"); shown = 0; if (rate->individual.restore_bps == -1) { storeAppendPrintf(sentry, "\tIndividual:\n\t\tDisabled.\n\n"); return; } storeAppendPrintf(sentry, "\tIndividual:\n"); storeAppendPrintf(sentry, "\t\tMax: %d\n", rate->individual.max_bytes); storeAppendPrintf(sentry, "\t\tRate: %d\n", rate->individual.restore_bps); for (i = 0;; i++) { if (class3->network_map[i] == 255) break; storeAppendPrintf(sentry, "\t\tCurrent [Network %d]: ", class3->network_map[i]); shown = 1; for (j = 0;; j++) { if (class3->individual_map[i][j] == 255) break; storeAppendPrintf(sentry, "%d:%d ", class3->individual_map[i][j], class3->individual[(i << 8) | j]); } if (class3->individual_255_used[i / 8] & (1 << (i % 8))) { storeAppendPrintf(sentry, "%d:%d ", 255, class3->individual[(i << 8) | 255]); } storeAppendPrintf(sentry, "\n"); } if (class3->network_255_used) { storeAppendPrintf(sentry, "\t\tCurrent [Network 255]: "); shown = 1; for (j = 0;; j++) { if (class3->individual_map[255][j] == 255) break; storeAppendPrintf(sentry, "%d:%d ", class3->individual_map[255][j], class3->individual[(255 << 8) | j]); } if (class3->individual_255_used[255 / 8] & (1 << (255 % 8))) { storeAppendPrintf(sentry, "%d:%d ", 255, class3->individual[(255 << 8) | 255]); } storeAppendPrintf(sentry, "\n"); } if (!shown) storeAppendPrintf(sentry, "\t\tCurrent [All networks]: Not used yet.\n"); storeAppendPrintf(sentry, "\n");}static voiddelayPoolStats(StoreEntry * sentry){ unsigned short i; storeAppendPrintf(sentry, "Delay pools configured: %d\n\n", Config.Delay.pools); for (i = 0; i < Config.Delay.pools; i++) { switch (Config.Delay.class[i]) { case 0: storeAppendPrintf(sentry, "Pool: %d\n\tClass: 0\n\n", i + 1); storeAppendPrintf(sentry, "\tMisconfigured pool.\n\n"); break; case 1: delayPoolStats1(sentry, i); break; case 2: delayPoolStats2(sentry, i); break; case 3: delayPoolStats3(sentry, i); break; default: assert(0); } }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -