Commit fc282bb9 authored by Federico Vaga's avatar Federico Vaga

wrtd:rt:out: improve trigger assignement by returing back to a hash table

Now the hash table is simpler than before. Most of the work is done in
user space
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>


NOTE
This commit has been created by `git subtree` on the Mock Turtle repository
on tag mock-turtle-2.0

This commit will not compile
parent a6526326
...@@ -106,7 +106,9 @@ enum wrtd_in_actions { ...@@ -106,7 +106,9 @@ enum wrtd_in_actions {
enum wrtd_out_actions { enum wrtd_out_actions {
WRTD_OUT_ACTION_SW_TRIG = __RT_ACTION_RECV_STANDARD_NUMBER, WRTD_OUT_ACTION_SW_TRIG = __RT_ACTION_RECV_STANDARD_NUMBER,
WRTD_OUT_ACTION_TRIG_IDX, WRTD_OUT_ACTION_TRIG_IDX,
WRTD_OUT_ACTION_TRIG_ORD, WRTD_OUT_ACTION_TRIG_FRE,
WRTD_OUT_ACTION_TRIG_ADD,
WRTD_OUT_ACTION_TRIG_DEL,
WRTD_OUT_ACTION_LOG, WRTD_OUT_ACTION_LOG,
}; };
...@@ -475,4 +477,18 @@ struct wrtd_out { ...@@ -475,4 +477,18 @@ struct wrtd_out {
struct wrtd_trigger_entry last_received; struct wrtd_trigger_entry last_received;
}; };
/**
* Hash function, returing the hash table index corresponding to a given
* trigger ID
*/
static inline int wrtd_hash_func(struct wrtd_trig_id *id)
{
int h = 0;
h += id->system * 10291;
h += id->source_port * 10017;
h += id->trigger * 3111;
return h & (FD_HASH_ENTRIES - 1); // hash table size must be a power of 2
}
#endif #endif
...@@ -104,19 +104,22 @@ static int wrtd_out_trigger_index_get(struct wrtd_desc *wrtd, ...@@ -104,19 +104,22 @@ static int wrtd_out_trigger_index_get(struct wrtd_desc *wrtd,
errno = EWRTD_NOFOUND_TRIGGER; errno = EWRTD_NOFOUND_TRIGGER;
return -1; return -1;
} }
if (hdr.msg_id != WRTD_OUT_ACTION_TRIG_IDX &&
hdr.msg_id != WRTD_OUT_ACTION_TRIG_FRE) {
errno = EWRNC_INVALID_MESSAGE;
return -1;
}
/* return the trigger index */ /* return the trigger index */
return msg.data[sizeof(struct wrnc_proto_header) / 4]; return msg.data[sizeof(struct wrnc_proto_header) / 4];
} }
/** static inline int wrtd_out_trigger_hash(struct wrtd_desc *wrtd, uint32_t tid,
* It retrieves the trigger index for the given trigger ID uint8_t msgid)
*/
static int wrtd_out_trigger_order(struct wrtd_desc *wrtd, uint32_t tid)
{ {
struct wrnc_proto_header hdr = { struct wrnc_proto_header hdr = {
.msg_id = WRTD_OUT_ACTION_TRIG_ORD, .msg_id = msgid,
.slot_io = (WRTD_IN_FD_CONTROL << 4) | .slot_io = (WRTD_IN_FD_CONTROL << 4) |
(WRTD_OUT_FD_CONTROL & 0xF), (WRTD_OUT_FD_CONTROL & 0xF),
.flags = WRNC_PROTO_FLAG_SYNC, .flags = WRNC_PROTO_FLAG_SYNC,
...@@ -143,6 +146,17 @@ static int wrtd_out_trigger_order(struct wrtd_desc *wrtd, uint32_t tid) ...@@ -143,6 +146,17 @@ static int wrtd_out_trigger_order(struct wrtd_desc *wrtd, uint32_t tid)
return 0; return 0;
} }
static int wrtd_out_trigger_insert(struct wrtd_desc *wrtd, uint32_t tid)
{
return wrtd_out_trigger_hash(wrtd, tid, WRTD_OUT_ACTION_TRIG_ADD);
}
static int wrtd_out_trigger_remove(struct wrtd_desc *wrtd, uint32_t tid)
{
return wrtd_out_trigger_hash(wrtd, tid, WRTD_OUT_ACTION_TRIG_DEL);
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * PROTOTYPEs IMPLEMENTATION * * * * * * * * * */ /* * * * * * * * * * PROTOTYPEs IMPLEMENTATION * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
...@@ -320,6 +334,70 @@ static int wrtd_out_trig_assign_condition_by_index(struct wrtd_node *dev, ...@@ -320,6 +334,70 @@ static int wrtd_out_trig_assign_condition_by_index(struct wrtd_node *dev,
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1); return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
} }
/**
* It sets the given bitmaks (it means that it does OR with the current value)
*/
static int wrtd_out_flag_set(struct wrtd_node *dev, unsigned int output,
uint32_t flags)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = hdr_base_sync;
int err;
if (output >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
chan.config.flags |= flags;
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
/**
* It sets the given bitmaks (it means that it does AND NOT with the current
* value)
*/
static int wrtd_out_flag_clr(struct wrtd_node *dev, unsigned int output,
uint32_t flags)
{
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrtd_out_channel chan;
struct wrnc_structure_tlv tlv = {
.index = OUT_STRUCT_CHAN_0 + output,
.size = sizeof(struct wrtd_out_channel)
- sizeof(struct wrtd_out_channel_private),
.structure = &chan,
};
struct wrnc_proto_header hdr = hdr_base_sync;
int err;
if (output >= FD_NUM_CHANNELS) {
errno = EWRTD_INVALID_CHANNEL;
return -1;
}
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err)
return err;
chan.config.flags &= ~flags;
return wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
}
static int wrtd_out_trig_assign_one(struct wrtd_node *dev, unsigned int output, static int wrtd_out_trig_assign_one(struct wrtd_node *dev, unsigned int output,
struct wrtd_trigger_handle *handle, struct wrtd_trigger_handle *handle,
struct wrtd_trig_id *tid) struct wrtd_trig_id *tid)
...@@ -341,24 +419,14 @@ static int wrtd_out_trig_assign_one(struct wrtd_node *dev, unsigned int output, ...@@ -341,24 +419,14 @@ static int wrtd_out_trig_assign_one(struct wrtd_node *dev, unsigned int output,
} }
ret = wrtd_out_trigger_index_get(wrtd, tid); ret = wrtd_out_trigger_index_get(wrtd, tid);
if (ret < 0) { if (ret < 0)
handle->ptr_trig = wrtd_out_trigger_first_free(dev); return ret;
if (handle->ptr_trig < 0) handle->ptr_trig = ret;
return -1;
} else {
handle->ptr_trig = ret;
}
tlv.index += handle->ptr_trig; tlv.index += handle->ptr_trig;
err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1); err = wrnc_rt_structure_get(wrtd->wrnc, &hdr, &tlv, 1);
if (err) if (err)
return err; return err;
if (trig.flags & ENTRY_FLAG_VALID) {
errno = EINVAL;
return -1;
}
trig.flags |= ENTRY_FLAG_VALID; trig.flags |= ENTRY_FLAG_VALID;
trig.id = *tid; trig.id = *tid;
memset(&trig.ocfg[handle->channel], 0, sizeof(struct lrt_output_rule)); memset(&trig.ocfg[handle->channel], 0, sizeof(struct lrt_output_rule));
...@@ -371,7 +439,11 @@ static int wrtd_out_trig_assign_one(struct wrtd_node *dev, unsigned int output, ...@@ -371,7 +439,11 @@ static int wrtd_out_trig_assign_one(struct wrtd_node *dev, unsigned int output,
if (err) if (err)
return err; return err;
return wrtd_out_trigger_order(wrtd, handle->ptr_trig); err = wrtd_out_trigger_insert(wrtd, handle->ptr_trig);
if (err)
return err;
return wrtd_out_flag_set(dev, handle->channel, WRTD_TRIGGER_ASSIGNED);
} }
...@@ -423,6 +495,7 @@ int wrtd_out_trig_unassign(struct wrtd_node *dev, ...@@ -423,6 +495,7 @@ int wrtd_out_trig_unassign(struct wrtd_node *dev,
struct wrtd_trigger_handle *handle) struct wrtd_trigger_handle *handle)
{ {
struct wrtd_desc *wrtd = (struct wrtd_desc *)dev; struct wrtd_desc *wrtd = (struct wrtd_desc *)dev;
struct wrtd_output_trigger_state triggers[256];
struct wrtd_out_trigger trig; struct wrtd_out_trigger trig;
struct wrnc_structure_tlv tlv = { struct wrnc_structure_tlv tlv = {
.index = __WRTD_OUT_STRUCT_MAX + handle->ptr_trig, .index = __WRTD_OUT_STRUCT_MAX + handle->ptr_trig,
...@@ -451,7 +524,16 @@ int wrtd_out_trig_unassign(struct wrtd_node *dev, ...@@ -451,7 +524,16 @@ int wrtd_out_trig_unassign(struct wrtd_node *dev,
err = wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1); err = wrnc_rt_structure_set(wrtd->wrnc, &hdr, &tlv, 1);
if (err) if (err)
return err; return err;
return wrtd_out_trigger_order(wrtd, handle->ptr_trig); err = wrtd_out_trigger_remove(wrtd, handle->ptr_trig);
if (err)
return err;
err = wrtd_out_trig_get_all(dev, handle->channel, triggers, 256);
if (err < 0)
return -1;
if (err > 0)
return 0;
return wrtd_out_flag_clr(dev, handle->channel, WRTD_TRIGGER_ASSIGNED);
} }
...@@ -468,6 +550,7 @@ int wrtd_out_trig_get_all(struct wrtd_node *dev, unsigned int output, ...@@ -468,6 +550,7 @@ int wrtd_out_trig_get_all(struct wrtd_node *dev, unsigned int output,
struct wrtd_output_trigger_state *triggers, struct wrtd_output_trigger_state *triggers,
int max_count) int max_count)
{ {
struct wrtd_output_trigger_state tmp;
int err = 0, i, count = 0; int err = 0, i, count = 0;
if (output >= FD_NUM_CHANNELS) { if (output >= FD_NUM_CHANNELS) {
...@@ -475,9 +558,8 @@ int wrtd_out_trig_get_all(struct wrtd_node *dev, unsigned int output, ...@@ -475,9 +558,8 @@ int wrtd_out_trig_get_all(struct wrtd_node *dev, unsigned int output,
return -1; return -1;
} }
for (i = 0; i < max_count && i < FD_HASH_ENTRIES; i++) { for (i = 0; count < max_count && i < FD_HASH_ENTRIES; i++) {
err = wrtd_out_trig_state_get_by_index(dev, i, output, err = wrtd_out_trig_state_get_by_index(dev, i, output, &tmp);
&triggers[count]);
if (err) { if (err) {
if (errno == EWRTD_NOFOUND_TRIGGER) { if (errno == EWRTD_NOFOUND_TRIGGER) {
err = 0; err = 0;
...@@ -486,6 +568,8 @@ int wrtd_out_trig_get_all(struct wrtd_node *dev, unsigned int output, ...@@ -486,6 +568,8 @@ int wrtd_out_trig_get_all(struct wrtd_node *dev, unsigned int output,
break; break;
} }
} else { } else {
memcpy(&triggers[count], &tmp,
sizeof(struct wrtd_output_trigger_state));
count++; count++;
} }
...@@ -571,11 +655,13 @@ int wrtd_out_trig_state_get_by_index(struct wrtd_node *dev, unsigned int index, ...@@ -571,11 +655,13 @@ int wrtd_out_trig_state_get_by_index(struct wrtd_node *dev, unsigned int index,
if (err) if (err)
return err; return err;
if (!(trig.flags & ENTRY_FLAG_VALID)) { if (!(trig.flags & ENTRY_FLAG_VALID) ||
(trig.ocfg[output].state == HASH_ENT_EMPTY)) {
errno = EWRTD_NOFOUND_TRIGGER; errno = EWRTD_NOFOUND_TRIGGER;
return -1; return -1;
} }
memset(trigger, 0, sizeof(struct wrtd_output_trigger_state));
trigger->handle.channel = output; trigger->handle.channel = output;
trigger->handle.ptr_trig = index; trigger->handle.ptr_trig = index;
trigger->handle.ptr_cond = (uint32_t)trig.ocfg[output].cond_ptr; trigger->handle.ptr_cond = (uint32_t)trig.ocfg[output].cond_ptr;
......
...@@ -8,6 +8,6 @@ WRNC = ../../../../ ...@@ -8,6 +8,6 @@ WRNC = ../../../../
EXTRA_CFLAGS += -I../../include EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -I../common EXTRA_CFLAGS += -I../common
EXTRA_CFLAGS += -DLIBRT_ERROR EXTRA_CFLAGS += -DLIBRT_ERROR
EXTRA_CFLAGS += -DLIBRT_DEBUG #EXTRA_CFLAGS += -DLIBRT_DEBUG
RT_USE_LIBRT := 1 RT_USE_LIBRT := 1
include $(WRNC)/applications/common/rt/Makefile include $(WRNC)/applications/common/rt/Makefile
...@@ -103,8 +103,7 @@ int wr_is_timing_ok() ...@@ -103,8 +103,7 @@ int wr_is_timing_ok()
struct wrtd_out_trigger triggers[FD_HASH_ENTRIES]; /**< list of triggers */ struct wrtd_out_trigger triggers[FD_HASH_ENTRIES]; /**< list of triggers */
struct wrtd_out_trigger *ord_tlist[FD_HASH_ENTRIES]; /**< list of triggers struct wrtd_out_trigger *ht[FD_HASH_ENTRIES]; /* hash table */
ordered by 'id' */
unsigned int tlist_count = 0; /**< number of valid trigger entry unsigned int tlist_count = 0; /**< number of valid trigger entry
in tlist */ in tlist */
static struct wrtd_out_channel wrtd_out_channels[FD_NUM_CHANNELS]; /**< Output static struct wrtd_out_channel wrtd_out_channels[FD_NUM_CHANNELS]; /**< Output
...@@ -112,67 +111,53 @@ static struct wrtd_out_channel wrtd_out_channels[FD_NUM_CHANNELS]; /**< Output ...@@ -112,67 +111,53 @@ static struct wrtd_out_channel wrtd_out_channels[FD_NUM_CHANNELS]; /**< Output
array */ array */
static struct wrtd_out wrtd_out_device; static struct wrtd_out wrtd_out_device;
int trigger_search(struct wrtd_out_trigger **tlist,
struct wrtd_trig_id *id,
unsigned int min, unsigned int max,
unsigned int *mid)
{
int cmp;
#if 0
/* Binary search */
while (max > min)
{
*mid = min + (max - min) / 2;
cmp = memcmp(&tlist[*mid]->id, id, sizeof(struct wrtd_trig_id));
if(cmp == 0)
return 1;
else if (cmp < 0)
min = *mid + 1;
else
max = *mid - 1;
}
/* When we do not find our element, then mid + 1 is the ideal position
for a the new entry */
*mid++;
#else
/* FIXME Temporary HACK to be able to use memcmp
(smem not byte addressable - VHDL problem) */
volatile struct wrtd_trig_id tmp;
tmp.system = id->system;
tmp.source_port = id->source_port;
tmp.trigger = id->trigger;
for (*mid = min; *mid < max; (*mid)++) {
cmp = memcmp(&tlist[*mid]->id, &tmp, sizeof(struct wrtd_trig_id));
if (cmp == 0)
return 1;
else if (cmp > 0)
break;
}
#endif static void print_hash_table(void)
{
int i;
#ifdef RTDEBUG pp_printf("%s <><><><><><>\n", __func__);
pp_printf("%s:%d %d %d %d %d - trig ID %d:%d:%d == %d:%d:%d ?\n", for (i = 0; i < FD_HASH_ENTRIES; ++i) {
__func__, __LINE__, delay(100000);
cmp, min, *mid, max, if (ht[i]) {
tlist[*mid]->id.system, tlist[*mid]->id.source_port, tlist[*mid]->id.trigger, pp_printf("%s [%d]=%d:%d:%d - %p\n", __func__,
id->system, id->source_port, id->trigger); i, ht[i]->id.system,
#endif ht[i]->id.source_port,
return 0; ht[i]->id.trigger,
&ht[i]);
} else {
pp_printf("%s [%d]=--:--:-- - %p\n", __func__,
i);
}
}
pp_printf("%s ==========\n", __func__);
}
static inline int trig_eq(struct wrtd_trig_id *id1, struct wrtd_trig_id *id2)
{
return id1->system == id2->system &&
id1->source_port == id2->source_port &&
id1->trigger == id2->trigger;
} }
struct wrtd_out_trigger *rtfd_trigger_entry_find(struct wrtd_trig_id *id) static int wrtd_out_hash_table_find(struct wrtd_trig_id *tid)
{ {
unsigned int index; int hidx;
int ret;
for (hidx = wrtd_hash_func(tid); hidx < FD_HASH_ENTRIES; hidx++)
if (trig_eq(tid, &ht[hidx]->id))
return hidx;
ret = trigger_search(ord_tlist, id, 0, tlist_count, &index); return -1;
}
static inline struct wrtd_out_trigger *rtfd_trigger_entry_find(struct wrtd_trig_id *tid)
{
int hidx = wrtd_out_hash_table_find(tid);
return ret ? ord_tlist[index] : NULL; return hidx >= 0 ? ht[hidx] : NULL;
} }
...@@ -577,6 +562,7 @@ void enqueue_trigger(int output, struct lrt_output_rule *rule, ...@@ -577,6 +562,7 @@ void enqueue_trigger(int output, struct lrt_output_rule *rule,
} }
static void filter_trigger(struct wrtd_trigger_entry *trig) static void filter_trigger(struct wrtd_trigger_entry *trig)
{ {
struct wrtd_out_trigger *ent = rtfd_trigger_entry_find(&trig->id); struct wrtd_out_trigger *ent = rtfd_trigger_entry_find(&trig->id);
...@@ -679,69 +665,78 @@ static int wrtd_out_trigger_sw(struct wrnc_proto_header *hin, void *pin, ...@@ -679,69 +665,78 @@ static int wrtd_out_trigger_sw(struct wrnc_proto_header *hin, void *pin,
return 0; return 0;
} }
/**
* Clear order array by removing unused triggers
*/ static int wrtd_out_hash_table_free(struct wrtd_trig_id *tid)
static inline void wrtd_out_trigger_order_remove(void) {
{ int hidx = wrtd_hash_func(tid);
int i, k;
for (; hidx < FD_HASH_ENTRIES; hidx++) {
pp_printf("%s >> qua (%d)\n", __func__, tlist_count); if (!ht[hidx])
for (i = 0; i < tlist_count; i++) { return hidx;
pp_printf("%s --- qua (%d/%d)\n", __func__, i, tlist_count); /* Check if it already exists */
if (ord_tlist[i]->flags & ENTRY_FLAG_VALID) if (trig_eq(tid, &ht[hidx]->id))
continue; break;
/* Found a removed trigger */
for (k = i; k < tlist_count - 1; k++)
ord_tlist[k] = ord_tlist[k + 1];
ord_tlist[k] = NULL;
tlist_count--;
} }
pp_printf("%s <<< qua (%d)\n", __func__, tlist_count); return -1;
} }
/** static int wrtd_out_hash_table_insert(struct wrnc_proto_header *hin, void *pin,
* Insert a trigger the ordered array struct wrnc_proto_header *hout, void *pout)
*/
static inline void wrtd_out_trigger_order_insert(unsigned int trig_idx)
{ {
int ret, index = 0, k; uint32_t tidx = *(uint32_t *)pin;
int hidx;
pp_printf("%s >>> qua trig %d\n", __func__, trig_idx); if (tlist_count >= FD_HASH_ENTRIES) {
ret = trigger_search(ord_tlist, &triggers[trig_idx].id, 0, pp_printf("Too many triggers %d/%d\n",
tlist_count, &index); tlist_count, FD_HASH_ENTRIES);
if (ret) { return -1;
pp_printf("%s: trigger already there\n");
return;
} }
pp_printf("%s --- qua\n", __func__); if (!(triggers[tidx].flags & ENTRY_FLAG_VALID))
for (k = tlist_count - 1; k >= index; --k) return; /* nothing to do is a valid trigger */
ord_tlist[k + 1] = ord_tlist[k];
ord_tlist[index] = &triggers[trig_idx]; hidx = wrtd_out_hash_table_free(&triggers[tidx].id);
if (hidx < 0)
goto out;
if (hidx >= FD_HASH_ENTRIES)
return -1;
tlist_count++; tlist_count++;
pp_printf("%s <<< qua trig %d\n", __func__, trig_idx); ht[hidx] = &triggers[tidx];
out:
rt_send_ack(hin, pin, hout, pout);
// print_hash_table();
return 0;
} }
/** static int wrtd_out_hash_table_remove(struct wrnc_proto_header *hin, void *pin,
* It order the triggers by ID struct wrnc_proto_header *hout, void *pout)
*/
static int wrtd_out_trigger_order(struct wrnc_proto_header *hin, void *pin,
struct wrnc_proto_header *hout, void *pout)
{ {
uint32_t *trig_idx = pin; uint32_t tidx = *(uint32_t *)pin;
int hidx;
pp_printf("%s >>> qua\n", __func__); if (tlist_count <= 0) {
if (hin->len != 1) { pp_printf("No trigger to remove %d/%d\n",
pp_printf("%s: command does not have payload, got %d bytes\n", tlist_count, FD_HASH_ENTRIES);
__func__, hin->len * 4);
return -1; return -1;
} }
wrtd_out_trigger_order_remove(); if (triggers[tidx].flags & ENTRY_FLAG_VALID)
wrtd_out_trigger_order_insert(*trig_idx); return; /* nothing to do is a valid trigger */
hidx = wrtd_out_hash_table_find(&triggers[tidx].id);
if (hidx < 0)
return -1;
tlist_count--;
ht[hidx] = NULL;
rt_send_ack(hin, pin, hout, pout);
// print_hash_table();
pp_printf("%s <<< qua\n", __func__);
rt_send_ack(hin, pin, hout, NULL);
return 0; return 0;
} }
...@@ -754,9 +749,9 @@ static int wrtd_out_trigger_index(struct wrnc_proto_header *hin, void *pin, ...@@ -754,9 +749,9 @@ static int wrtd_out_trigger_index(struct wrnc_proto_header *hin, void *pin,
{ {
struct wrtd_trig_id *id = pin; struct wrtd_trig_id *id = pin;
uint32_t *index = pout; uint32_t *index = pout;
int hidx;
int ret; int ret;
pp_printf("%s --- qua\n", __func__);
/* Verify that the size is correct */ /* Verify that the size is correct */
if (hin->len * 4 != sizeof(struct wrtd_trig_id)) { if (hin->len * 4 != sizeof(struct wrtd_trig_id)) {
pp_printf("%s: wrong incoming message size %d (expected %d)\n", pp_printf("%s: wrong incoming message size %d (expected %d)\n",
...@@ -769,15 +764,24 @@ static int wrtd_out_trigger_index(struct wrnc_proto_header *hin, void *pin, ...@@ -769,15 +764,24 @@ static int wrtd_out_trigger_index(struct wrnc_proto_header *hin, void *pin,
} }
ret = trigger_search(ord_tlist, id, 0, tlist_count, hidx = wrtd_out_hash_table_find(id);
(unsigned int *) index); if (hidx >= 0) {
pp_printf("%s --- qua -- %d:%d:%d %d %d\n", __func__, *index = ((int)ht[hidx] - (int)triggers) / sizeof(struct wrtd_out_trigger);
id->system, id->source_port, id->trigger, ret, *index); } else {
if (ret) { /* Get first free */
/* hout.msg_id = TODO ; */ for (*index = 0; *index < FD_HASH_ENTRIES; ++(*index)) {
hout->len = 1; if (!(triggers[*index].flags & ENTRY_FLAG_VALID)) {
return 0; hout->msg_id = WRTD_OUT_ACTION_TRIG_FRE;
break;
}
}
if ((*index) == FD_HASH_ENTRIES)
return -1;
} }
hout->len = 1;
return 0;
err: err:
return -1; return -1;
} }
...@@ -817,7 +821,8 @@ static action_t *wrtd_out_actions[] = { ...@@ -817,7 +821,8 @@ static action_t *wrtd_out_actions[] = {
[RT_ACTION_RECV_STRUCT_GET] = rt_structure_getter, [RT_ACTION_RECV_STRUCT_GET] = rt_structure_getter,
[WRTD_OUT_ACTION_SW_TRIG] = wrtd_out_trigger_sw, [WRTD_OUT_ACTION_SW_TRIG] = wrtd_out_trigger_sw,
[WRTD_OUT_ACTION_TRIG_IDX] = wrtd_out_trigger_index, [WRTD_OUT_ACTION_TRIG_IDX] = wrtd_out_trigger_index,
[WRTD_OUT_ACTION_TRIG_ORD] = wrtd_out_trigger_order, [WRTD_OUT_ACTION_TRIG_ADD] = wrtd_out_hash_table_insert,
[WRTD_OUT_ACTION_TRIG_DEL] = wrtd_out_hash_table_remove,
}; };
enum rt_slot_name { enum rt_slot_name {
...@@ -900,7 +905,7 @@ void init(void) ...@@ -900,7 +905,7 @@ void init(void)
/* Triggers */ /* Triggers */
for (i = 0; i < FD_HASH_ENTRIES; i++) { for (i = 0; i < FD_HASH_ENTRIES; i++) {
memset(&triggers[i], 0, sizeof(struct wrtd_out_trigger)); memset(&triggers[i], 0, sizeof(struct wrtd_out_trigger));
ord_tlist[i] = NULL; ht[i] = NULL;
} }
/* librt: dynamically add structures */ /* librt: dynamically add structures */
......
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