Commit 25b129dc authored by Tristan Gingold's avatar Tristan Gingold

wrtd: fixes, prepare for delay

parent f3c837e1
......@@ -199,10 +199,6 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
struct wrtd_event tev;
struct wrtd_tstamp now;
/* Discard if rule is not enabled. */
if (!rule->conf.enabled)
return;
/* Event was received. */
rule->stat.rx_events++;
rule->stat.rx_last = ev->ts;
......@@ -262,16 +258,15 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
rule->conf.enabled = 0;
}
/* Rename event. */
memcpy(tev.id, rule->conf.dest_id, WRTD_ID_LEN);
tev.seq = rule->stat.seq++;
/* Send. */
rule->stat.tx_events++;
rule->stat.tx_last = ev->ts;
wrtd_log(7, 0, &tev, NULL);
if (rule->conf.dest_ch == WRTD_DEST_CH_NET) {
/* Rename event, and send it. */
memcpy(tev.id, rule->conf.dest_id, WRTD_ID_LEN);
tev.seq = rule->stat.seq++;
#ifdef WRTD_NET_TX
wrtd_send_network(&tev);
#else
......@@ -295,14 +290,18 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
static void wrtd_route_in(struct wrtd_event *ev)
{
struct wrtd_rule *rule;
unsigned int hash = wrtd_hash_id(ev->id) % NBR_RULES;
unsigned int hash = wrtd_id_hash(ev->id) % NBR_RULES;
rule = &rules[hash];
while (1) {
/* A disabled rule cannot be followed by an enabled one. */
if (!rule->conf.enabled)
break;
if (memcmp(ev->id, rule->conf.source_id, WRTD_ID_LEN) == 0)
wrtd_route(rule, ev);
if (rule->conf.hash_chain == 0)
if (rule->conf.hash_chain == -1)
break;
rule = &rules[rule->conf.hash_chain];
}
......
......@@ -49,7 +49,7 @@ struct wrtd_event {
unsigned char flags;
};
inline static unsigned char wrtd_hash_id(char id[WRTD_ID_LEN])
inline static unsigned char wrtd_id_hash(const char *id)
{
/* This assumes ID is properly padded. */
return id[0] ^ id[3] ^ id[4] ^ id[7];
......
......@@ -71,8 +71,8 @@ static const struct wrtd_mt_config configs[] =
{
.mt_app_id = 0x115790de,
.nbr_cpus = 2,
.rx_cpu = 0,
.tx_cpu = 1,
.tx_cpu = 0,
.rx_cpu = 1,
.cpus = {
{
WRTD_APP_TDC_5CH,
......
......@@ -13,7 +13,6 @@ struct rule_map {
struct wrtd_lib_rule *rule;
int cpu;
int idx;
int hash_chain;
};
struct device_map {
......@@ -204,10 +203,12 @@ static enum wrtd_status wrtd_reconfigure_place(struct wrtd_dev *wrtd,
disable_idx = 0;
cpu_offset = 0;
for(cpu = 0; cpu < wrtd->nbr_cpus; cpu++) {
unsigned nbr_cpu_rules = wrtd->roots[cpu].nbr_rules;
const unsigned nbr_cpu_rules = wrtd->roots[cpu].nbr_rules;
/* SLOTS[N] contains the index of the rule in map. */
int *slots;
int free_slots;
int free_slot_idx;
/* Allocate slots array. */
slots = (int *)calloc(nbr_cpu_rules, sizeof(int));
if (slots == NULL)
return wrtd_return_error
......@@ -219,59 +220,56 @@ static enum wrtd_status wrtd_reconfigure_place(struct wrtd_dev *wrtd,
for (i = 0; i < nbr_cpu_rules; i++)
slots[i] = -1;
/* Create chain of collisions. */
/* Compute hash and place heads. */
for (i = 0; i < map->nbr_rules; i++) {
struct rule_map *m = &map->rules[i];
unsigned int hash;
if (m->cpu != cpu)
continue;
hash = wrtd_hash_id(m->rule->rule.conf.source_id)
hash = wrtd_id_hash(m->rule->rule.conf.source_id)
% nbr_cpu_rules;
m->hash_chain = slots[hash];
slots[hash] = i;
m->idx = cpu_offset + hash;
m->rule->rule.conf.hash_chain = -1;
if (slots[hash] == -1)
slots[hash] = i;
}
/* Place heads. */
for (i = 0; i < nbr_cpu_rules; i++) {
if (slots[i] == -1)
/* Place collisions. */
free_slot_idx = 0;
for (i = 0; i < map->nbr_rules; i++) {
struct rule_map *m = &map->rules[i];
unsigned head_idx;
if (m->cpu != cpu)
continue;
assert(map->rules[slots[i]].cpu == cpu);
map->rules[slots[i]].idx = cpu_offset + i;
}
head_idx = m->idx - cpu_offset;
assert(head_idx < nbr_cpu_rules);
/* Place collisions. */
free_slots = 0;
for (i = 0; i < nbr_cpu_rules; i++) {
struct rule_map *m;
if (slots[i] == -1)
/* Skip it if already placed. */
if (slots[head_idx] == i)
continue;
m = &map->rules[slots[i]];
while (m->hash_chain != -1) {
m = &map->rules[m->hash_chain];
/* Find next free slot. */
while (slots[free_slots] != -1)
free_slots++;
assert(free_slots < nbr_cpu_rules);
m->idx = cpu_offset + free_slots;
slots[free_slots] = -2; /* Idx is not known,
but we don't care. */
free_slots++;
/* Find next free slot (there must be one). */
while (slots[free_slot_idx] != -1) {
free_slot_idx++;
assert(free_slot_idx < nbr_cpu_rules);
}
m->idx = cpu_offset + free_slot_idx;
slots[free_slot_idx] = i;
/* Chain. */
m->rule->rule.conf.hash_chain =
map->rules[head_idx].rule->rule.conf.hash_chain;
map->rules[head_idx].rule->rule.conf.hash_chain =
free_slot_idx;
free_slot_idx++;
}
/* Place disabled rules. */
while(1) {
/* Find next free slot. */
while (free_slots < nbr_cpu_rules
&& slots[free_slots] != -1)
free_slots++;
if (free_slots >= nbr_cpu_rules)
break;
/* Find next disable rule. */
while (disable_idx < map->nbr_rules
&& map->rules[disable_idx].rule->rule.conf.enabled)
......@@ -279,8 +277,15 @@ static enum wrtd_status wrtd_reconfigure_place(struct wrtd_dev *wrtd,
if (disable_idx >= map->nbr_rules)
break;
map->rules[disable_idx].idx = cpu_offset + free_slots;
free_slots++;
/* Find next free slot. */
while (slots[free_slot_idx] != -1) {
free_slot_idx++;
assert(free_slot_idx < nbr_cpu_rules);
}
map->rules[disable_idx].idx =
cpu_offset + free_slot_idx;
free_slot_idx++;
disable_idx++;
}
......
......@@ -105,7 +105,7 @@ static void disp_alarm(const struct wrtd_alarm *alarm)
printf("\n");
}
static void disp_rule_conf(const struct wrtd_rule *rule)
static void disp_rule_conf(const struct wrtd_rule *rule, unsigned nbr_rules)
{
const struct wrtd_rule_config *cfg = &rule->conf;
printf(" id: ");
......@@ -120,6 +120,9 @@ static void disp_rule_conf(const struct wrtd_rule *rule)
" dest_cpu: %u\n", cfg->dest_cpu);
printf(" dest_ch: %u\n", cfg->dest_ch);
printf(" enabled: %d\n", cfg->enabled);
printf(" hash: %u, hash_chain: %d\n",
wrtd_id_hash(cfg->source_id) % nbr_rules,
cfg->hash_chain);
printf(" send late: %d\n", cfg->send_late);
printf(" repeat count: %d\n", cfg->repeat_count);
printf(" delay_ns: ");
......@@ -133,8 +136,7 @@ static void disp_rule_conf(const struct wrtd_rule *rule)
printf("\n"
" resync_delay_ns: ");
print_ns(cfg->resync_delay_ns);
printf("\n"
" hash_chain: %d\n", cfg->hash_chain);
printf("\n");
}
static void disp_rule_stat(const struct wrtd_rule *rule)
......@@ -196,7 +198,7 @@ static enum wrtd_status disp_cpu_config(struct wrtd_dev *wrtd, int cpu,
(uint32_t *)&rule);
WRTD_RETURN_IF_ERROR(res);
printf("rule #%d\n", j);
disp_rule_conf(&rule);
disp_rule_conf(&rule, root.nbr_rules);
}
}
......@@ -221,8 +223,10 @@ static enum wrtd_status disp_cpu_config(struct wrtd_dev *wrtd, int cpu,
static void disp_config(const struct wrtd_mt_config *config)
{
unsigned cpu;
printf("MT app_id: 0x%08x, nbr_cpus: %d\n",
printf("MT app_id: 0x%08x, nbr_cpus: %u\n",
config->mt_app_id, config->nbr_cpus);
printf(" tx_cpu: %u, rx_cpu: %u\n",
config->tx_cpu, config->rx_cpu);
for (cpu = 0; cpu < config->nbr_cpus; cpu++) {
const struct wrtd_mt_cpu_config *cpucfg =
&config->cpus[cpu];
......@@ -283,6 +287,26 @@ static enum wrtd_status wrtd_cmd_dump_config(struct wrtd_dev *wrtd,
return WRTD_SUCCESS;
}
static enum wrtd_status wrtd_cmd_dump_cpus(struct wrtd_dev *wrtd,
int argc, char *argv[])
{
const struct wrtd_mt_config *config;
enum wrtd_status status;
int cpu;
status = wrtd_fill_config(wrtd);
WRTD_RETURN_IF_ERROR(status);
config = wrtd->config;
for (cpu = 0; cpu < config->nbr_cpus; cpu++) {
status = disp_cpu_config(wrtd, cpu, 0, 0);
WRTD_RETURN_IF_ERROR(status);
}
return WRTD_SUCCESS;
}
static enum wrtd_status wrtd_cmd_dump_rules(struct wrtd_dev *wrtd,
int argc, char *argv[])
{
......@@ -297,7 +321,7 @@ static enum wrtd_status wrtd_cmd_dump_rules(struct wrtd_dev *wrtd,
if (wrtd_id_null(r->rule.conf.id))
continue;
printf("cpu#%u rule %u:\n", r->cpu, r->idx);
disp_rule_conf(&r->rule);
disp_rule_conf(&r->rule, wrtd->roots[r->cpu].nbr_rules);
disp_rule_stat(&r->rule);
}
......@@ -570,25 +594,66 @@ static enum wrtd_status wrtd_cmd_add_rule(struct wrtd_dev *wrtd,
static enum wrtd_status wrtd_cmd_set_rule(struct wrtd_dev *wrtd,
int argc, char *argv[])
{
unsigned i;
struct wrtd_tstamp ts;
const char *id;
enum wrtd_status status;
uint64_t delay;
bool has_delay;
has_delay = false;
if (argc != 3) {
fprintf(stderr, "invalid arguments\n");
if (argc < 1) {
fprintf(stderr, "rule id missing\n");
/* Don't print another message. */
return WRTD_SUCCESS;
}
id = argv[0];
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-')
break;
if (strcmp(argv[i], "-d") == 0) {
i++;
if (i == argc) {
fprintf(stderr, "missing argument for -t");
return WRTD_SUCCESS;
}
if (parse_delay(argv[i], &delay) != 0) {
fprintf(stderr, "bad delay\n");
/* Don't print another message. */
return WRTD_SUCCESS;
}
has_delay = true;
}
}
if (i + 2 != argc) {
fprintf(stderr, "missing <src> <dest>\n");
/* Don't print another message. */
return WRTD_SUCCESS;
}
status = wrtd_set_attr_string(wrtd, id,
WRTD_ATTR_RULE_SOURCE, argv[1]);
WRTD_ATTR_RULE_SOURCE, argv[i + 0]);
WRTD_RETURN_IF_ERROR(status);
status = wrtd_set_attr_string(wrtd, id,
WRTD_ATTR_RULE_DESTINATION, argv[2]);
WRTD_ATTR_RULE_DESTINATION, argv[i + 1]);
WRTD_RETURN_IF_ERROR(status);
/* Set delay. */
if (has_delay) {
ts.seconds = 0;
ts.ns = 0;
ts.frac = 0;
ts_add_ps(&ts, delay);
status = wrtd_set_attr_tstamp(wrtd, id,
WRTD_ATTR_RULE_DELAY, &ts);
WRTD_RETURN_IF_ERROR(status);
}
return WRTD_SUCCESS;
}
......@@ -710,6 +775,8 @@ static struct wrtd_commands cmds[] = {
wrtd_cmd_dump_all },
{ "dump-config", "", "shows wrtd config",
wrtd_cmd_dump_config },
{ "dump-cpu", "", "shows wrtd cpu",
wrtd_cmd_dump_cpus },
{ "dump-rules", "", "shows wrtd rules",
wrtd_cmd_dump_rules },
{ "dump-alarms", "", "shows wrtd alarms",
......@@ -729,7 +796,8 @@ static struct wrtd_commands cmds[] = {
wrtd_cmd_list_alarms },
{ "add-rule", "<name>", "create a rule",
wrtd_cmd_add_rule },
{ "set-rule", "<name> <src> <dest>", "set rule source and dest",
{ "set-rule", "<name> [-d <delay>] <src> <dest>",
"set rule source and dest",
wrtd_cmd_set_rule },
{ "list-rules", "", "list all rules",
wrtd_cmd_list_rules },
......@@ -823,8 +891,7 @@ int main(int argc, char *argv[])
/* Open. */
status = wrtd_init(dev_name, 0, NULL, &wrtd);
if (status != WRTD_SUCCESS) {
fprintf(stderr, "Cannot open WRTD: %s\n",
wrtd_get_error_msg(wrtd));
fprintf(stderr, "Cannot open WRTD, status=0x%08x\n", status);
return 1;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment