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"
|
"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 {
|
struct stat_entry {
|
||||||
uint8_t link_id;
|
uint8_t link_id;
|
||||||
int64_t ooo;
|
int64_t ooo;
|
||||||
|
@ -56,7 +68,7 @@ struct timing_entry {
|
||||||
|
|
||||||
struct link_status {
|
struct link_status {
|
||||||
struct timespec last;
|
struct timespec last;
|
||||||
uint8_t used;
|
enum link_cat used;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct light_ctx {
|
struct light_ctx {
|
||||||
|
@ -80,6 +92,7 @@ struct light_ctx {
|
||||||
int is_measlat;
|
int is_measlat;
|
||||||
int explain;
|
int explain;
|
||||||
int disable_scheduler;
|
int disable_scheduler;
|
||||||
|
struct stat_entry stats[MAX_LINKS];
|
||||||
enum schedule_group_target sched_strat;
|
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->prev_links[i] = UINT8_MAX;
|
||||||
|
|
||||||
lightc->used = lightc->fast_count * 2;
|
lightc->used = lightc->fast_count * 2;
|
||||||
for (int i = 0; i < lightc->used; i++) {
|
for (int i = 0; i < lightc->total_links; i++) {
|
||||||
lightc->status[i].used = 1;
|
lightc->status[i].used = i < lightc->used ? LINK_SLOW : LINK_NOT_USED;
|
||||||
}
|
}
|
||||||
|
|
||||||
union abstract_packet m;
|
union abstract_packet m;
|
||||||
|
@ -286,16 +299,16 @@ int compare_stat_entry_max(const void *a, const void *b) {
|
||||||
return sea->ooo - seb->ooo;
|
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;
|
struct timespec now, not_before = {0}, temp_time;
|
||||||
set_now(&now);
|
set_now(&now);
|
||||||
timespec_diff (&now, &lightc->window, ¬_before);
|
timespec_diff (&now, &lightc->window, ¬_before);
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
for (int i = 0; i < lightc->total_links; i++) {
|
for (int i = 0; i < lightc->total_links; i++) {
|
||||||
stats[i].link_id = i;
|
lightc->stats[i].link_id = i;
|
||||||
stats[i].meas_occ = 0;
|
lightc->stats[i].meas_occ = 0;
|
||||||
stats[i].ooo = -1;
|
lightc->stats[i].ooo = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute local stats
|
// Compute local stats
|
||||||
|
@ -310,19 +323,19 @@ void algo_lightning_update_stats (struct light_ctx *lightc, struct stat_entry *s
|
||||||
case OOO_ONGOING:
|
case OOO_ONGOING:
|
||||||
timespec_diff(&now, &lightc->historic[i].detected_at, &temp_time);
|
timespec_diff(&now, &lightc->historic[i].detected_at, &temp_time);
|
||||||
delta = timespec_get_unit (&temp_time, MILISEC);
|
delta = timespec_get_unit (&temp_time, MILISEC);
|
||||||
stats[l].ooo += delta;
|
lightc->stats[l].ooo += delta;
|
||||||
stats[l].meas_occ += 1;
|
lightc->stats[l].meas_occ += 1;
|
||||||
break;
|
break;
|
||||||
case OOO_DONE:
|
case OOO_DONE:
|
||||||
timespec_diff(&lightc->historic[i].finished_at, &lightc->historic[i].detected_at, &temp_time);
|
timespec_diff(&lightc->historic[i].finished_at, &lightc->historic[i].detected_at, &temp_time);
|
||||||
delta = timespec_get_unit (&temp_time, MILISEC);
|
delta = timespec_get_unit (&temp_time, MILISEC);
|
||||||
stats[l].ooo += delta;
|
lightc->stats[l].ooo += delta;
|
||||||
stats[l].meas_occ += 1;
|
lightc->stats[l].meas_occ += 1;
|
||||||
break;
|
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);
|
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 (lightc->explain) printf("(stats.local) link=%d, delta=%ld\n", l, delta);
|
||||||
/*if (delta > stats[l].ooo) {
|
/*if (delta > stats[l].ooo) {
|
||||||
|
@ -333,16 +346,16 @@ void algo_lightning_update_stats (struct light_ctx *lightc, struct stat_entry *s
|
||||||
|
|
||||||
// Compute average
|
// Compute average
|
||||||
for (int i = 0; i < lightc->total_links; i++) {
|
for (int i = 0; i < lightc->total_links; i++) {
|
||||||
if (stats[i].meas_occ <= 0) continue;
|
if (lightc->stats[i].meas_occ <= 0) continue;
|
||||||
stats[i].ooo = stats[i].ooo / stats[i].meas_occ;
|
lightc->stats[i].ooo = lightc->stats[i].ooo / lightc->stats[i].meas_occ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set my local stats + merge remote stats
|
// Set my local stats + merge remote stats
|
||||||
for (int i = 0; i < lightc->total_links; i++) {
|
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 (lightc->remote_stats[i] == -1) continue;
|
||||||
if (stats[i].ooo == -1) stats[i].ooo = lightc->remote_stats[i];
|
if (lightc->stats[i].ooo == -1) lightc->stats[i].ooo = lightc->remote_stats[i];
|
||||||
else stats[i].ooo = (lightc->remote_stats[i] + stats[i].ooo) / 2;
|
else lightc->stats[i].ooo = (lightc->remote_stats[i] + lightc->stats[i].ooo) / 2;
|
||||||
/*
|
/*
|
||||||
if (lightc->remote_stats[i] > stats[i].ooo) {
|
if (lightc->remote_stats[i] > stats[i].ooo) {
|
||||||
if (lightc->explain) printf("(stats.remote) link=%d, delta=%d\n", i, lightc->remote_stats[i]);
|
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
|
// Sort
|
||||||
if (!lightc->disable_scheduler) {
|
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;
|
struct timespec not_before = {0}, oldest = *now;
|
||||||
timespec_diff(now, &lightc->window, ¬_before);
|
timespec_diff(now, &lightc->window, ¬_before);
|
||||||
if (timespec_gt(&lightc->last_update_used, ¬_before)) return;
|
if (timespec_gt(&lightc->last_update_used, ¬_before)) return;
|
||||||
|
|
||||||
printf("update triggered\n");
|
|
||||||
|
|
||||||
int used_to_not = 0, not_to_used = 0;
|
int used_to_not = 0, not_to_used = 0;
|
||||||
int64_t max_ooo = 0;
|
int64_t max_ooo = 0;
|
||||||
for (int i = 0; i < lightc->total_links; i++) {
|
for (int i = 0; i < lightc->total_links; i++) {
|
||||||
if (lightc->status[stats[i].link_id].used) {
|
if (lightc->status[lightc->stats[i].link_id].used == LINK_FAST || lightc->status[lightc->stats[i].link_id].used == LINK_SLOW) {
|
||||||
if (stats[i].ooo >= max_ooo) {
|
int64_t retained_ooo = lightc->stats[i].ooo == -1 ? INT64_MAX : lightc->stats[i].ooo;
|
||||||
max_ooo = stats[i].ooo;
|
if (retained_ooo >= max_ooo) {
|
||||||
used_to_not = stats[i].link_id;
|
max_ooo = retained_ooo;
|
||||||
|
used_to_not = lightc->stats[i].link_id;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (timespec_lt(&lightc->status[stats[i].link_id].last, &oldest)) {
|
if (timespec_lt(&lightc->status[lightc->stats[i].link_id].last, &oldest)) {
|
||||||
oldest = lightc->status[stats[i].link_id].last;
|
oldest = lightc->status[lightc->stats[i].link_id].last;
|
||||||
not_to_used = stats[i].link_id;
|
not_to_used = lightc->stats[i].link_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we have a good link not used?
|
// Do we have a good link not used?
|
||||||
for (int i = 0; i < lightc->used; i++) {
|
for (int i = 0; i < lightc->used; i++) {
|
||||||
if (!lightc->status[stats[i].link_id].used) {
|
if (lightc->status[lightc->stats[i].link_id].used == LINK_NOT_USED) {
|
||||||
not_to_used = stats[i].link_id;
|
not_to_used = lightc->stats[i].link_id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap them
|
// Swap them
|
||||||
lightc->status[used_to_not].used = 0;
|
printf("Link %d will be disabled, %d will be enabled\n", used_to_not, not_to_used);
|
||||||
lightc->status[not_to_used].used = 1;
|
lightc->status[used_to_not].used = LINK_NOT_USED;
|
||||||
|
lightc->status[not_to_used].used = LINK_SLOW;
|
||||||
lightc->last_update_used = *now;
|
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) {
|
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 algo_ctx* app_ctx = fdinfo->cat->app_ctx;
|
||||||
struct light_ctx* lightc = app_ctx->misc;
|
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);
|
algo_lightning_pad (ctx, fdinfo, bp);
|
||||||
|
|
||||||
// Compute stats
|
// Compute stats
|
||||||
struct stat_entry stats[MAX_LINKS] = {0};
|
algo_lightning_update_stats(lightc);
|
||||||
algo_lightning_update_stats(lightc, stats);
|
algo_lightning_update_used(lightc, &now);
|
||||||
algo_lightning_update_used(lightc, stats, &now);
|
algo_lightning_link_cat(lightc);
|
||||||
|
|
||||||
if (ctx->verbose > 1) {
|
if (ctx->verbose > 1) {
|
||||||
printf("after sort: ");
|
printf("after sort: ");
|
||||||
for (int i = 0; i < lightc->total_links; i++) {
|
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");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -496,12 +522,11 @@ int algo_lightning_on_datagram(struct evt_core_ctx* ctx, struct evt_core_fdinfo*
|
||||||
sel_link_last = now;
|
sel_link_last = now;
|
||||||
lightc->selected_link = UINT8_MAX;
|
lightc->selected_link = UINT8_MAX;
|
||||||
for (int i = 0, j = 0; i < lightc->total_links && j < lightc->fast_count; i++) {
|
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 (lightc->status[lightc->stats[i].link_id].used != LINK_FAST) continue;
|
||||||
if (timespec_lt (&lightc->status[stats[i].link_id].last, &sel_link_last)) {
|
if (timespec_lt (&lightc->status[lightc->stats[i].link_id].last, &sel_link_last)) {
|
||||||
lightc->selected_link = stats[i].link_id;
|
lightc->selected_link = lightc->stats[i].link_id;
|
||||||
sel_link_last = lightc->status[stats[i].link_id].last;
|
sel_link_last = lightc->status[lightc->stats[i].link_id].last;
|
||||||
}
|
}
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
if (lightc->is_measlat) tag_packet_measlat (ap, lightc->selected_link, 0);
|
if (lightc->is_measlat) tag_packet_measlat (ap, lightc->selected_link, 0);
|
||||||
send_message (ctx, bp);
|
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) {
|
if (lightc->sched_strat == SCHEDULE_BOTH || lightc->sched_strat == SCHEDULE_SLOW) {
|
||||||
sel_link_last = now;
|
sel_link_last = now;
|
||||||
lightc->selected_link = UINT8_MAX;
|
lightc->selected_link = UINT8_MAX;
|
||||||
for (int i = lightc->total_links-1, j = 0; i >= 0 && j < lightc->fast_count; i++) {
|
for (int i = 0; i < lightc->total_links; i++) {
|
||||||
if (!lightc->status[stats[i].link_id].used) continue;
|
if (lightc->status[lightc->stats[i].link_id].used != LINK_SLOW) continue;
|
||||||
if (timespec_lt (&lightc->status[stats[i].link_id].last, &sel_link_last)) {
|
if (timespec_lt (&lightc->status[lightc->stats[i].link_id].last, &sel_link_last)) {
|
||||||
lightc->selected_link = stats[i].link_id;
|
lightc->selected_link = lightc->stats[i].link_id;
|
||||||
sel_link_last = lightc->status[stats[i].link_id].last;
|
sel_link_last = lightc->status[lightc->stats[i].link_id].last;
|
||||||
}
|
}
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
if (lightc->is_measlat) tag_packet_measlat (ap, lightc->selected_link, 1);
|
if (lightc->is_measlat) tag_packet_measlat (ap, lightc->selected_link, 1);
|
||||||
send_message (ctx, bp);
|
send_message (ctx, bp);
|
||||||
|
|
Loading…
Reference in a new issue