WIP link selection

This commit is contained in:
Quentin 2019-10-22 10:22:17 +02:00
parent a88f5be07b
commit c0102d12fc

View file

@ -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, &not_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, &not_before);
if (timespec_gt(&lightc->last_update_used, &not_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);