WIP link selection
This commit is contained in:
parent
a88f5be07b
commit
c0102d12fc
1 changed files with 71 additions and 47 deletions
|
@ -40,6 +40,18 @@ char* schedule_group_target_str[] = {
|
|||
"SCHEDULE_SLOW"
|
||||
};
|
||||
|
||||
enum link_cat {
|
||||
LINK_FAST = 0,
|
||||
LINK_SLOW = 1,
|
||||
LINK_NOT_USED = 2
|
||||
};
|
||||
|
||||
char* link_cat_str[] = {
|
||||
"LINK_FAST",
|
||||
"LINK_SLOW",
|
||||
"LINK_NOT_USED"
|
||||
};
|
||||
|
||||
struct stat_entry {
|
||||
uint8_t link_id;
|
||||
int64_t ooo;
|
||||
|
@ -56,7 +68,7 @@ struct timing_entry {
|
|||
|
||||
struct link_status {
|
||||
struct timespec last;
|
||||
uint8_t used;
|
||||
enum link_cat used;
|
||||
};
|
||||
|
||||
struct light_ctx {
|
||||
|
@ -80,6 +92,7 @@ struct light_ctx {
|
|||
int is_measlat;
|
||||
int explain;
|
||||
int disable_scheduler;
|
||||
struct stat_entry stats[MAX_LINKS];
|
||||
enum schedule_group_target sched_strat;
|
||||
};
|
||||
|
||||
|
@ -130,8 +143,8 @@ void algo_lightning_init(struct evt_core_ctx* ctx, struct algo_ctx* app_ctx, str
|
|||
lightc->prev_links[i] = UINT8_MAX;
|
||||
|
||||
lightc->used = lightc->fast_count * 2;
|
||||
for (int i = 0; i < lightc->used; i++) {
|
||||
lightc->status[i].used = 1;
|
||||
for (int i = 0; i < lightc->total_links; i++) {
|
||||
lightc->status[i].used = i < lightc->used ? LINK_SLOW : LINK_NOT_USED;
|
||||
}
|
||||
|
||||
union abstract_packet m;
|
||||
|
@ -286,16 +299,16 @@ int compare_stat_entry_max(const void *a, const void *b) {
|
|||
return sea->ooo - seb->ooo;
|
||||
}
|
||||
|
||||
void algo_lightning_update_stats (struct light_ctx *lightc, struct stat_entry *stats) {
|
||||
void algo_lightning_update_stats (struct light_ctx *lightc) {
|
||||
struct timespec now, not_before = {0}, temp_time;
|
||||
set_now(&now);
|
||||
timespec_diff (&now, &lightc->window, ¬_before);
|
||||
|
||||
// Init
|
||||
for (int i = 0; i < lightc->total_links; i++) {
|
||||
stats[i].link_id = i;
|
||||
stats[i].meas_occ = 0;
|
||||
stats[i].ooo = -1;
|
||||
lightc->stats[i].link_id = i;
|
||||
lightc->stats[i].meas_occ = 0;
|
||||
lightc->stats[i].ooo = -1;
|
||||
}
|
||||
|
||||
// Compute local stats
|
||||
|
@ -310,19 +323,19 @@ void algo_lightning_update_stats (struct light_ctx *lightc, struct stat_entry *s
|
|||
case OOO_ONGOING:
|
||||
timespec_diff(&now, &lightc->historic[i].detected_at, &temp_time);
|
||||
delta = timespec_get_unit (&temp_time, MILISEC);
|
||||
stats[l].ooo += delta;
|
||||
stats[l].meas_occ += 1;
|
||||
lightc->stats[l].ooo += delta;
|
||||
lightc->stats[l].meas_occ += 1;
|
||||
break;
|
||||
case OOO_DONE:
|
||||
timespec_diff(&lightc->historic[i].finished_at, &lightc->historic[i].detected_at, &temp_time);
|
||||
delta = timespec_get_unit (&temp_time, MILISEC);
|
||||
stats[l].ooo += delta;
|
||||
stats[l].meas_occ += 1;
|
||||
lightc->stats[l].ooo += delta;
|
||||
lightc->stats[l].meas_occ += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lightc->explain) printf("(stats.compute) packet=%ld, link=%d, status=%s, delta=%ld\n", lightc->historic[i].pkt_id, l, ooo_state_str[lightc->historic[i].state], delta);
|
||||
stats[l].link_id = l;
|
||||
lightc->stats[l].link_id = l;
|
||||
|
||||
if (lightc->explain) printf("(stats.local) link=%d, delta=%ld\n", l, delta);
|
||||
/*if (delta > stats[l].ooo) {
|
||||
|
@ -333,16 +346,16 @@ void algo_lightning_update_stats (struct light_ctx *lightc, struct stat_entry *s
|
|||
|
||||
// Compute average
|
||||
for (int i = 0; i < lightc->total_links; i++) {
|
||||
if (stats[i].meas_occ <= 0) continue;
|
||||
stats[i].ooo = stats[i].ooo / stats[i].meas_occ;
|
||||
if (lightc->stats[i].meas_occ <= 0) continue;
|
||||
lightc->stats[i].ooo = lightc->stats[i].ooo / lightc->stats[i].meas_occ;
|
||||
}
|
||||
|
||||
// Set my local stats + merge remote stats
|
||||
for (int i = 0; i < lightc->total_links; i++) {
|
||||
lightc->local_stats[i] = stats[i].ooo;
|
||||
lightc->local_stats[i] = lightc->stats[i].ooo;
|
||||
if (lightc->remote_stats[i] == -1) continue;
|
||||
if (stats[i].ooo == -1) stats[i].ooo = lightc->remote_stats[i];
|
||||
else stats[i].ooo = (lightc->remote_stats[i] + stats[i].ooo) / 2;
|
||||
if (lightc->stats[i].ooo == -1) lightc->stats[i].ooo = lightc->remote_stats[i];
|
||||
else lightc->stats[i].ooo = (lightc->remote_stats[i] + lightc->stats[i].ooo) / 2;
|
||||
/*
|
||||
if (lightc->remote_stats[i] > stats[i].ooo) {
|
||||
if (lightc->explain) printf("(stats.remote) link=%d, delta=%d\n", i, lightc->remote_stats[i]);
|
||||
|
@ -352,7 +365,7 @@ void algo_lightning_update_stats (struct light_ctx *lightc, struct stat_entry *s
|
|||
|
||||
// Sort
|
||||
if (!lightc->disable_scheduler) {
|
||||
qsort(stats, lightc->total_links, sizeof(struct stat_entry), compare_stat_entry_max);
|
||||
qsort(lightc->stats, lightc->total_links, sizeof(struct stat_entry), compare_stat_entry_max);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,43 +442,56 @@ void tag_packet_measlat(union abstract_packet* ap, uint8_t link_id, uint8_t is_s
|
|||
}
|
||||
}
|
||||
|
||||
void algo_lightning_update_used(struct light_ctx *lightc, struct stat_entry *stats, struct timespec *now) {
|
||||
void algo_lightning_update_used(struct light_ctx *lightc, struct timespec *now) {
|
||||
struct timespec not_before = {0}, oldest = *now;
|
||||
timespec_diff(now, &lightc->window, ¬_before);
|
||||
if (timespec_gt(&lightc->last_update_used, ¬_before)) return;
|
||||
|
||||
printf("update triggered\n");
|
||||
|
||||
int used_to_not = 0, not_to_used = 0;
|
||||
int64_t max_ooo = 0;
|
||||
for (int i = 0; i < lightc->total_links; i++) {
|
||||
if (lightc->status[stats[i].link_id].used) {
|
||||
if (stats[i].ooo >= max_ooo) {
|
||||
max_ooo = stats[i].ooo;
|
||||
used_to_not = stats[i].link_id;
|
||||
if (lightc->status[lightc->stats[i].link_id].used == LINK_FAST || lightc->status[lightc->stats[i].link_id].used == LINK_SLOW) {
|
||||
int64_t retained_ooo = lightc->stats[i].ooo == -1 ? INT64_MAX : lightc->stats[i].ooo;
|
||||
if (retained_ooo >= max_ooo) {
|
||||
max_ooo = retained_ooo;
|
||||
used_to_not = lightc->stats[i].link_id;
|
||||
}
|
||||
} else {
|
||||
if (timespec_lt(&lightc->status[stats[i].link_id].last, &oldest)) {
|
||||
oldest = lightc->status[stats[i].link_id].last;
|
||||
not_to_used = stats[i].link_id;
|
||||
if (timespec_lt(&lightc->status[lightc->stats[i].link_id].last, &oldest)) {
|
||||
oldest = lightc->status[lightc->stats[i].link_id].last;
|
||||
not_to_used = lightc->stats[i].link_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have a good link not used?
|
||||
for (int i = 0; i < lightc->used; i++) {
|
||||
if (!lightc->status[stats[i].link_id].used) {
|
||||
not_to_used = stats[i].link_id;
|
||||
if (lightc->status[lightc->stats[i].link_id].used == LINK_NOT_USED) {
|
||||
not_to_used = lightc->stats[i].link_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Swap them
|
||||
lightc->status[used_to_not].used = 0;
|
||||
lightc->status[not_to_used].used = 1;
|
||||
printf("Link %d will be disabled, %d will be enabled\n", used_to_not, not_to_used);
|
||||
lightc->status[used_to_not].used = LINK_NOT_USED;
|
||||
lightc->status[not_to_used].used = LINK_SLOW;
|
||||
lightc->last_update_used = *now;
|
||||
}
|
||||
|
||||
void algo_lightning_link_cat(struct light_ctx *lightc) {
|
||||
uint8_t used = 0;
|
||||
printf("---\n");
|
||||
for (int i = 0; i < lightc->total_links; i++) {
|
||||
if (lightc->status[lightc->stats[i].link_id].used != LINK_NOT_USED) {
|
||||
if (used < lightc->fast_count) lightc->status[lightc->stats[i].link_id].used = LINK_FAST;
|
||||
else lightc->status[lightc->stats[i].link_id].used = LINK_SLOW;
|
||||
used++;
|
||||
}
|
||||
printf("Link ID=%d, status=%s, ooo=%ld\n", lightc->stats[i].link_id, link_cat_str[lightc->status[lightc->stats[i].link_id].used], lightc->stats[i].ooo);
|
||||
}
|
||||
}
|
||||
|
||||
int algo_lightning_on_datagram(struct evt_core_ctx* ctx, struct evt_core_fdinfo* fdinfo, struct buffer_packet* bp) {
|
||||
struct algo_ctx* app_ctx = fdinfo->cat->app_ctx;
|
||||
struct light_ctx* lightc = app_ctx->misc;
|
||||
|
@ -477,14 +503,14 @@ int algo_lightning_on_datagram(struct evt_core_ctx* ctx, struct evt_core_fdinfo*
|
|||
algo_lightning_pad (ctx, fdinfo, bp);
|
||||
|
||||
// Compute stats
|
||||
struct stat_entry stats[MAX_LINKS] = {0};
|
||||
algo_lightning_update_stats(lightc, stats);
|
||||
algo_lightning_update_used(lightc, stats, &now);
|
||||
algo_lightning_update_stats(lightc);
|
||||
algo_lightning_update_used(lightc, &now);
|
||||
algo_lightning_link_cat(lightc);
|
||||
|
||||
if (ctx->verbose > 1) {
|
||||
printf("after sort: ");
|
||||
for (int i = 0; i < lightc->total_links; i++) {
|
||||
printf("%d (%ld), ", stats[i].link_id, stats[i].ooo);
|
||||
printf("%d (%ld), ", lightc->stats[i].link_id, lightc->stats[i].ooo);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -496,12 +522,11 @@ int algo_lightning_on_datagram(struct evt_core_ctx* ctx, struct evt_core_fdinfo*
|
|||
sel_link_last = now;
|
||||
lightc->selected_link = UINT8_MAX;
|
||||
for (int i = 0, j = 0; i < lightc->total_links && j < lightc->fast_count; i++) {
|
||||
if (!lightc->status[stats[i].link_id].used) continue;
|
||||
if (timespec_lt (&lightc->status[stats[i].link_id].last, &sel_link_last)) {
|
||||
lightc->selected_link = stats[i].link_id;
|
||||
sel_link_last = lightc->status[stats[i].link_id].last;
|
||||
if (lightc->status[lightc->stats[i].link_id].used != LINK_FAST) continue;
|
||||
if (timespec_lt (&lightc->status[lightc->stats[i].link_id].last, &sel_link_last)) {
|
||||
lightc->selected_link = lightc->stats[i].link_id;
|
||||
sel_link_last = lightc->status[lightc->stats[i].link_id].last;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (lightc->is_measlat) tag_packet_measlat (ap, lightc->selected_link, 0);
|
||||
send_message (ctx, bp);
|
||||
|
@ -512,13 +537,12 @@ int algo_lightning_on_datagram(struct evt_core_ctx* ctx, struct evt_core_fdinfo*
|
|||
if (lightc->sched_strat == SCHEDULE_BOTH || lightc->sched_strat == SCHEDULE_SLOW) {
|
||||
sel_link_last = now;
|
||||
lightc->selected_link = UINT8_MAX;
|
||||
for (int i = lightc->total_links-1, j = 0; i >= 0 && j < lightc->fast_count; i++) {
|
||||
if (!lightc->status[stats[i].link_id].used) continue;
|
||||
if (timespec_lt (&lightc->status[stats[i].link_id].last, &sel_link_last)) {
|
||||
lightc->selected_link = stats[i].link_id;
|
||||
sel_link_last = lightc->status[stats[i].link_id].last;
|
||||
for (int i = 0; i < lightc->total_links; i++) {
|
||||
if (lightc->status[lightc->stats[i].link_id].used != LINK_SLOW) continue;
|
||||
if (timespec_lt (&lightc->status[lightc->stats[i].link_id].last, &sel_link_last)) {
|
||||
lightc->selected_link = lightc->stats[i].link_id;
|
||||
sel_link_last = lightc->status[lightc->stats[i].link_id].last;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (lightc->is_measlat) tag_packet_measlat (ap, lightc->selected_link, 1);
|
||||
send_message (ctx, bp);
|
||||
|
|
Loading…
Reference in a new issue