From f2f0e68f9db76695d0c91dc109d0f59cfba56c1d Mon Sep 17 00:00:00 2001 From: Navid Nikaein Date: Tue, 5 Jan 2016 19:26:45 +0100 Subject: [PATCH] Fix the bug in the RB tree, and sanity test for the timer API --- common/utils/collection/tree.h | 231 ++++++++++++++++++++------- common/utils/itti/timer.c | 8 +- openair2/ENB_APP/enb_agent.c | 5 +- openair2/ENB_APP/enb_agent_common.c | 85 +++++----- openair2/ENB_APP/enb_agent_common.h | 9 +- openair2/ENB_APP/enb_agent_handler.c | 10 +- 6 files changed, 232 insertions(+), 116 deletions(-) diff --git a/common/utils/collection/tree.h b/common/utils/collection/tree.h index 8e4e35c408..c9df686fbb 100755 --- a/common/utils/collection/tree.h +++ b/common/utils/collection/tree.h @@ -1,4 +1,8 @@ -/* +/* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */ +/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ +/* $FreeBSD$ */ + +/*- * Copyright 2002 Niels Provos * All rights reserved. * @@ -26,6 +30,8 @@ #ifndef _SYS_TREE_H_ #define _SYS_TREE_H_ +#include + /* * This file defines data structures for different types of trees: * splay trees and red-black trees. @@ -63,7 +69,7 @@ struct name { \ #define SPLAY_INIT(root) do { \ (root)->sph_root = NULL; \ -} while (0) +} while (/*CONSTCOND*/ 0) #define SPLAY_ENTRY(type) \ struct { \ @@ -81,32 +87,32 @@ struct { \ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ -} while (0) +} while (/*CONSTCOND*/ 0) #define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ SPLAY_LEFT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ -} while (0) +} while (/*CONSTCOND*/ 0) #define SPLAY_LINKLEFT(head, tmp, field) do { \ SPLAY_LEFT(tmp, field) = (head)->sph_root; \ tmp = (head)->sph_root; \ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ -} while (0) +} while (/*CONSTCOND*/ 0) #define SPLAY_LINKRIGHT(head, tmp, field) do { \ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ tmp = (head)->sph_root; \ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ -} while (0) +} while (/*CONSTCOND*/ 0) #define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ -} while (0) +} while (/*CONSTCOND*/ 0) /* Generates prototypes and inline functions */ @@ -207,7 +213,7 @@ name##_SPLAY(struct name *head, struct type *elm) \ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ __left = __right = &__node; \ \ - while ((__comp = (cmp)(elm, (head)->sph_root))) { \ + while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ if (__comp < 0) { \ __tmp = SPLAY_LEFT((head)->sph_root, field); \ if (__tmp == NULL) \ @@ -286,7 +292,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \ (x) != NULL; \ (x) = SPLAY_NEXT(name, head, x)) -/* Macros that define a red-back tree */ +/* Macros that define a red-black tree */ #define RB_HEAD(name, type) \ struct name { \ struct type *rbh_root; /* root of the tree */ \ @@ -297,7 +303,7 @@ struct name { \ #define RB_INIT(root) do { \ (root)->rbh_root = NULL; \ -} while (0) +} while (/*CONSTCOND*/ 0) #define RB_BLACK 0 #define RB_RED 1 @@ -320,24 +326,24 @@ struct { \ RB_PARENT(elm, field) = parent; \ RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ RB_COLOR(elm, field) = RB_RED; \ -} while (0) +} while (/*CONSTCOND*/ 0) #define RB_SET_BLACKRED(black, red, field) do { \ RB_COLOR(black, field) = RB_BLACK; \ RB_COLOR(red, field) = RB_RED; \ -} while (0) +} while (/*CONSTCOND*/ 0) #ifndef RB_AUGMENT -#define RB_AUGMENT(x) +#define RB_AUGMENT(x) do {} while (0) #endif #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ (tmp) = RB_RIGHT(elm, field); \ - if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ } \ RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ else \ @@ -349,15 +355,15 @@ struct { \ RB_AUGMENT(tmp); \ if ((RB_PARENT(tmp, field))) \ RB_AUGMENT(RB_PARENT(tmp, field)); \ -} while (0) +} while (/*CONSTCOND*/ 0) #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ (tmp) = RB_LEFT(elm, field); \ - if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ } \ RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ else \ @@ -369,28 +375,66 @@ struct { \ RB_AUGMENT(tmp); \ if ((RB_PARENT(tmp, field))) \ RB_AUGMENT(RB_PARENT(tmp, field)); \ -} while (0) +} while (/*CONSTCOND*/ 0) /* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ -void name##_RB_INSERT_COLOR(struct name *, struct type *); \ -void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ -struct type *name##_RB_REMOVE(struct name *, struct type *); \ -struct type *name##_RB_INSERT(struct name *, struct type *); \ -struct type *name##_RB_FIND(struct name *, struct type *); \ -struct type *name##_RB_NEXT(struct type *); \ -struct type *name##_RB_MINMAX(struct name *, int); \ - \ +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ + RB_PROTOTYPE_INSERT_COLOR(name, type, attr); \ + RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \ + RB_PROTOTYPE_INSERT(name, type, attr); \ + RB_PROTOTYPE_REMOVE(name, type, attr); \ + RB_PROTOTYPE_FIND(name, type, attr); \ + RB_PROTOTYPE_NFIND(name, type, attr); \ + RB_PROTOTYPE_NEXT(name, type, attr); \ + RB_PROTOTYPE_PREV(name, type, attr); \ + RB_PROTOTYPE_MINMAX(name, type, attr); +#define RB_PROTOTYPE_INSERT_COLOR(name, type, attr) \ + attr void name##_RB_INSERT_COLOR(struct name *, struct type *) +#define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \ + attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *) +#define RB_PROTOTYPE_REMOVE(name, type, attr) \ + attr struct type *name##_RB_REMOVE(struct name *, struct type *) +#define RB_PROTOTYPE_INSERT(name, type, attr) \ + attr struct type *name##_RB_INSERT(struct name *, struct type *) +#define RB_PROTOTYPE_FIND(name, type, attr) \ + attr struct type *name##_RB_FIND(struct name *, struct type *) +#define RB_PROTOTYPE_NFIND(name, type, attr) \ + attr struct type *name##_RB_NFIND(struct name *, struct type *) +#define RB_PROTOTYPE_NEXT(name, type, attr) \ + attr struct type *name##_RB_NEXT(struct type *) +#define RB_PROTOTYPE_PREV(name, type, attr) \ + attr struct type *name##_RB_PREV(struct type *) +#define RB_PROTOTYPE_MINMAX(name, type, attr) \ + attr struct type *name##_RB_MINMAX(struct name *, int) /* Main rb operation. * Moves node close to the key of elm to top */ -#define RB_GENERATE(name, type, field, cmp) \ -void \ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ + RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ + RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ + RB_GENERATE_INSERT(name, type, field, cmp, attr) \ + RB_GENERATE_REMOVE(name, type, field, attr) \ + RB_GENERATE_FIND(name, type, field, cmp, attr) \ + RB_GENERATE_NFIND(name, type, field, cmp, attr) \ + RB_GENERATE_NEXT(name, type, field, attr) \ + RB_GENERATE_PREV(name, type, field, attr) \ + RB_GENERATE_MINMAX(name, type, field, attr) + +#define RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ +attr void \ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ { \ struct type *parent, *gparent, *tmp; \ - while ((parent = RB_PARENT(elm, field)) && \ + while ((parent = RB_PARENT(elm, field)) != NULL && \ RB_COLOR(parent, field) == RB_RED) { \ gparent = RB_PARENT(parent, field); \ if (parent == RB_LEFT(gparent, field)) { \ @@ -428,9 +472,10 @@ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ } \ } \ RB_COLOR(head->rbh_root, field) = RB_BLACK; \ -} \ - \ -void \ +} + +#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ +attr void \ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ { \ struct type *tmp; \ @@ -454,7 +499,8 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) if (RB_RIGHT(tmp, field) == NULL || \ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ struct type *oleft; \ - if ((oleft = RB_LEFT(tmp, field)))\ + if ((oleft = RB_LEFT(tmp, field)) \ + != NULL) \ RB_COLOR(oleft, field) = RB_BLACK;\ RB_COLOR(tmp, field) = RB_RED; \ RB_ROTATE_RIGHT(head, tmp, oleft, field);\ @@ -486,7 +532,8 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) if (RB_LEFT(tmp, field) == NULL || \ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ struct type *oright; \ - if ((oright = RB_RIGHT(tmp, field)))\ + if ((oright = RB_RIGHT(tmp, field)) \ + != NULL) \ RB_COLOR(oright, field) = RB_BLACK;\ RB_COLOR(tmp, field) = RB_RED; \ RB_ROTATE_LEFT(head, tmp, oright, field);\ @@ -504,9 +551,10 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) } \ if (elm) \ RB_COLOR(elm, field) = RB_BLACK; \ -} \ - \ -struct type * \ +} + +#define RB_GENERATE_REMOVE(name, type, field, attr) \ +attr struct type * \ name##_RB_REMOVE(struct name *head, struct type *elm) \ { \ struct type *child, *parent, *old = elm; \ @@ -518,7 +566,7 @@ name##_RB_REMOVE(struct name *head, struct type *elm) \ else { \ struct type *left; \ elm = RB_RIGHT(elm, field); \ - while ((left = RB_LEFT(elm, field))) \ + while ((left = RB_LEFT(elm, field)) != NULL) \ elm = left; \ child = RB_RIGHT(elm, field); \ parent = RB_PARENT(elm, field); \ @@ -551,7 +599,7 @@ name##_RB_REMOVE(struct name *head, struct type *elm) \ left = parent; \ do { \ RB_AUGMENT(left); \ - } while ((left = RB_PARENT(left, field))); \ + } while ((left = RB_PARENT(left, field)) != NULL); \ } \ goto color; \ } \ @@ -572,9 +620,10 @@ color: \ name##_RB_REMOVE_COLOR(head, parent, child); \ return (old); \ } \ - \ + +#define RB_GENERATE_INSERT(name, type, field, cmp, attr) \ /* Inserts a node into the RB tree */ \ -struct type * \ +attr struct type * \ name##_RB_INSERT(struct name *head, struct type *elm) \ { \ struct type *tmp; \ @@ -599,15 +648,14 @@ name##_RB_INSERT(struct name *head, struct type *elm) \ RB_RIGHT(parent, field) = elm; \ RB_AUGMENT(parent); \ } else \ - { \ RB_ROOT(head) = elm; \ - } \ name##_RB_INSERT_COLOR(head, elm); \ return (NULL); \ -} \ - \ +} + +#define RB_GENERATE_FIND(name, type, field, cmp, attr) \ /* Finds the node with the same key as elm */ \ -struct type * \ +attr struct type * \ name##_RB_FIND(struct name *head, struct type *elm) \ { \ struct type *tmp = RB_ROOT(head); \ @@ -622,9 +670,33 @@ name##_RB_FIND(struct name *head, struct type *elm) \ return (tmp); \ } \ return (NULL); \ -} \ - \ -struct type * \ +} + +#define RB_GENERATE_NFIND(name, type, field, cmp, attr) \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_RB_NFIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *res = NULL; \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = RB_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} + +#define RB_GENERATE_NEXT(name, type, field, attr) \ +/* ARGSUSED */ \ +attr struct type * \ name##_RB_NEXT(struct type *elm) \ { \ if (RB_RIGHT(elm, field)) { \ @@ -643,9 +715,33 @@ name##_RB_NEXT(struct type *elm) \ } \ } \ return (elm); \ -} \ - \ -struct type * \ +} + +#define RB_GENERATE_PREV(name, type, field, attr) \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_PREV(struct type *elm) \ +{ \ + if (RB_LEFT(elm, field)) { \ + elm = RB_LEFT(elm, field); \ + while (RB_RIGHT(elm, field)) \ + elm = RB_RIGHT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} + +#define RB_GENERATE_MINMAX(name, type, field, attr) \ +attr struct type * \ name##_RB_MINMAX(struct name *head, int val) \ { \ struct type *tmp = RB_ROOT(head); \ @@ -666,7 +762,9 @@ name##_RB_MINMAX(struct name *head, int val) \ #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) #define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) #define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) @@ -675,4 +773,29 @@ name##_RB_MINMAX(struct name *head, int val) \ (x) != NULL; \ (x) = name##_RB_NEXT(x)) +#define RB_FOREACH_FROM(x, name, y) \ + for ((x) = (y); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RB_MAX(name, head); \ + (x) != NULL; \ + (x) = name##_RB_PREV(x)) + +#define RB_FOREACH_REVERSE_FROM(x, name, y) \ + for ((x) = (y); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + (x) = (y)) + #endif /* _SYS_TREE_H_ */ diff --git a/common/utils/itti/timer.c b/common/utils/itti/timer.c index 683efd1279..9c742c19cc 100644 --- a/common/utils/itti/timer.c +++ b/common/utils/itti/timer.c @@ -95,8 +95,7 @@ int timer_handle_signal(siginfo_t *info) // LG: To many traces for msc timer: TMR_DEBUG("Timer with id 0x%lx has expired\n", (long)timer_p->timer); - printf("Timer with id 0x%lx has expired\n", (long)timer_p->timer); - + task_id = timer_p->task_id; instance = timer_p->instance; message_p = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED); @@ -210,11 +209,6 @@ int timer_setup( type == TIMER_PERIODIC ? "periodic" : "single shot", *timer_id, interval_sec, interval_us); - printf("Requesting new %s timer with id 0x%lx that expires within " - "%d sec and %d usec\n", - type == TIMER_PERIODIC ? "periodic" : "single shot", - *timer_id, interval_sec, interval_us); - timer_p->timer = timer; /* Lock the queue and insert the timer at the tail */ diff --git a/openair2/ENB_APP/enb_agent.c b/openair2/ENB_APP/enb_agent.c index 7003a2c638..01eb61fc0b 100644 --- a/openair2/ENB_APP/enb_agent.c +++ b/openair2/ENB_APP/enb_agent.c @@ -40,6 +40,7 @@ #include "assertions.h" +//#define TEST_TIMER enb_agent_instance_t enb_agent[NUM_MAX_ENB_AGENT]; msg_context_t shared_ctxt[NUM_MAX_ENB_AGENT]; @@ -327,8 +328,10 @@ int enb_agent_stop(mid_t mod_id){ err_code_t enb_agent_timeout(void* args){ + // enb_agent_timer_args_t *timer_args = calloc(1, sizeof(*timer_args)); + //memcpy (timer_args, args, sizeof(*timer_args)); enb_agent_timer_args_t *timer_args = (enb_agent_timer_args_t *) args; - + LOG_I(ENB_AGENT, "enb_agent %d timeout\n", timer_args->mod_id); LOG_I(ENB_AGENT, "eNB action %d ENB flags %d \n", timer_args->cc_actions,timer_args->cc_report_flags); LOG_I(ENB_AGENT, "UE action %d UE flags %d \n", timer_args->ue_actions,timer_args->ue_report_flags); diff --git a/openair2/ENB_APP/enb_agent_common.c b/openair2/ENB_APP/enb_agent_common.c index c2653f4c85..70f1092bdd 100644 --- a/openair2/ENB_APP/enb_agent_common.c +++ b/openair2/ENB_APP/enb_agent_common.c @@ -312,25 +312,12 @@ int get_ue_wcqi (mid_t mod_id, mid_t ue_id) { //struct enb_agent_map agent_map; - -/* The timer_id might not be the best choice for the comparison */ -int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b){ - - //if (a->timer_id) return 0; - //if (b->timer_id) return 0; - - if (a->timer_id < b->timer_id) return -1; - if (a->timer_id > b->timer_id) return 1; - - // equal timers - return 0; -} - -RB_GENERATE(enb_agent_map,enb_agent_timer_element_s, entry, enb_agent_compare_timer); - +enb_agent_timer_instance_t timer_instance; err_code_t enb_agent_init_timer(void){ + + LOG_I(ENB_AGENT, "init RB tree\n"); - RB_INIT(&enb_agent_head); + RB_INIT(&timer_instance.enb_agent_head); /* struct enb_agent_timer_element_s e; @@ -340,6 +327,18 @@ err_code_t enb_agent_init_timer(void){ return PROTOCOL__PROGRAN_ERR__NO_ERR; } +RB_GENERATE(enb_agent_map,enb_agent_timer_element_s, entry, enb_agent_compare_timer); + +/* The timer_id might not be the best choice for the comparison */ +int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b){ + + if (a->timer_id < b->timer_id) return -1; + if (a->timer_id > b->timer_id) return 1; + + // equal timers + return 0; +} + err_code_t enb_agent_create_timer(uint32_t interval_sec, uint32_t interval_usec, agent_id_t agent_id, @@ -349,7 +348,9 @@ err_code_t enb_agent_create_timer(uint32_t interval_sec, void* timer_args, long *timer_id){ - struct enb_agent_timer_element_s e; + struct enb_agent_timer_element_s *e = calloc(1, sizeof(*e)); + DevAssert(e != NULL); + //uint32_t timer_id; int ret=-1; @@ -368,7 +369,7 @@ err_code_t enb_agent_create_timer(uint32_t interval_sec, timer_args, timer_id); - e.type = TIMER_ONE_SHOT; + e->type = TIMER_ONE_SHOT; } else if (timer_type == ENB_AGENT_TIMER_TYPE_PERIODIC ){ ret = timer_setup(interval_sec, @@ -379,32 +380,25 @@ err_code_t enb_agent_create_timer(uint32_t interval_sec, timer_args, timer_id); - e.type = TIMER_PERIODIC; + e->type = TIMER_PERIODIC; } if (ret < 0 ) { return TIMER_SETUP_FAILED; } - e.agent_id = agent_id; - e.instance = instance; - e.state = ENB_AGENT_TIMER_STATE_ACTIVE; - e.timer_id = *timer_id; - e.timer_args = timer_args; - e.cb = cb; - - LOG_I(ENB_AGENT,"created a timer with id 0x%lx for agent %d, instance %d \n", - e.timer_id, e.agent_id, e.instance); - - RB_INSERT(enb_agent_map, &enb_agent_head, &e); + e->agent_id = agent_id; + e->instance = instance; + e->state = ENB_AGENT_TIMER_STATE_ACTIVE; + e->timer_id = *timer_id; + // e->timer_args = timer_args; + e->cb = cb; + /*element should be a real pointer*/ + RB_INSERT(enb_agent_map, &timer_instance.enb_agent_head, e); - - /* - struct enb_agent_timer_element_s search; - search.timer_id = *timer_id; - printf("search 1: %p (expected %p)\n", RB_FIND(enb_agent_map, &enb_agent_head, &search), &e); - printf("search 1: %p (expected %p)\n", get_timer_entry(e.timer_id), &e); - */ + LOG_I(ENB_AGENT,"Created a new timer with id 0x%lx for agent %d, instance %d \n", + e->timer_id, e->agent_id, e->instance); + return 0; } @@ -413,7 +407,7 @@ err_code_t enb_agent_destroy_timer(long timer_id){ struct enb_agent_timer_element_s *e = get_timer_entry(timer_id); if (e != NULL ) { - RB_REMOVE(enb_agent_map, &enb_agent_head, &e); + RB_REMOVE(enb_agent_map, &timer_instance.enb_agent_head, &e); free(e); } @@ -431,8 +425,8 @@ err_code_t enb_agent_destroy_timers(void){ struct enb_agent_timer_element_s *e = NULL; - RB_FOREACH(e, enb_agent_map, &enb_agent_head) { - RB_REMOVE(enb_agent_map, &enb_agent_head, e); + RB_FOREACH(e, enb_agent_map, &timer_instance.enb_agent_head) { + RB_REMOVE(enb_agent_map, &timer_instance.enb_agent_head, e); timer_remove(e->timer_id); free(e); } @@ -443,11 +437,10 @@ err_code_t enb_agent_destroy_timers(void){ struct enb_agent_timer_element_s * get_timer_entry(long timer_id) { - struct enb_agent_timer_element_s search, *e; - memset(&search, 0, sizeof(struct enb_agent_timer_element_s)); - search.timer_id = timer_id; - - return RB_FIND(enb_agent_map, &enb_agent_head, &search); + struct enb_agent_timer_element_s *search= calloc(1,sizeof(*search)); + search->timer_id = timer_id; + + return RB_FIND(enb_agent_map, &timer_instance.enb_agent_head, search); } /* diff --git a/openair2/ENB_APP/enb_agent_common.h b/openair2/ENB_APP/enb_agent_common.h index eb3de96145..662ea73ed7 100644 --- a/openair2/ENB_APP/enb_agent_common.h +++ b/openair2/ENB_APP/enb_agent_common.h @@ -189,10 +189,13 @@ typedef struct enb_agent_timer_element_s{ long timer_id; /* Timer id returned by the timer API*/ enb_agent_timer_callback_t cb; - void* timer_args; + // void* timer_args; } enb_agent_timer_element_t; +typedef struct enb_agent_timer_instance_s{ + RB_HEAD(enb_agent_map, enb_agent_timer_element_s) enb_agent_head; +}enb_agent_timer_instance_t; err_code_t enb_agent_init_timer(void); @@ -214,11 +217,11 @@ err_code_t enb_agent_restart_timer(long *timer_id); struct enb_agent_timer_element_s * get_timer_entry(long timer_id); -int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b); + err_code_t enb_agent_process_timeout(long timer_id, void* timer_args); -RB_HEAD(enb_agent_map, enb_agent_timer_element_s) enb_agent_head; +int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b); /* RB_PROTOTYPE is for .h files */ RB_PROTOTYPE(enb_agent_map, enb_agent_timer_element_s, entry, enb_agent_compare_timer); diff --git a/openair2/ENB_APP/enb_agent_handler.c b/openair2/ENB_APP/enb_agent_handler.c index 27536c8b7f..1b8457d474 100644 --- a/openair2/ENB_APP/enb_agent_handler.c +++ b/openair2/ENB_APP/enb_agent_handler.c @@ -141,15 +141,15 @@ void * enb_agent_send_message(xid_t xid, err_code_t enb_agent_process_timeout(long timer_id, void* timer_args){ - struct enb_agent_timer_element_s *e = get_timer_entry(timer_id); + struct enb_agent_timer_element_s *found = get_timer_entry(timer_id); + + if (found == NULL ) goto error; + LOG_I(ENB_AGENT, "Found the entry (%p): timer_id is 0x%lx 0x%lx\n", found, timer_id, found->timer_id); - LOG_I(ENB_AGENT, "element %p: timer_id is 0x%lx 0x%lx\n", e, timer_id, e->timer_id); - - if (e == NULL ) goto error; if (timer_args == NULL) LOG_W(ENB_AGENT,"null timer args\n"); - return e->cb(timer_args); + return found->cb(timer_args); error: