Commit 6153f47e authored by Jonathan Jenkins's avatar Jonathan Jenkins
Browse files

fixed scheduler memory leak

parent ae0f71dd
...@@ -45,21 +45,24 @@ typedef struct model_net_sched_interface { ...@@ -45,21 +45,24 @@ typedef struct model_net_sched_interface {
void (*init)(struct model_net_method *method, void ** sched); void (*init)(struct model_net_method *method, void ** sched);
void (*destroy)(void * sched); void (*destroy)(void * sched);
void (*add)( void (*add)(
model_net_request *req, model_net_request *req,
int remote_event_size, int remote_event_size,
void * remote_event, void * remote_event,
int local_event_size, int local_event_size,
void * local_event, void * local_event,
void *sched, void *sched,
model_net_sched_rc *rc, model_net_sched_rc *rc,
tw_lp *lp); tw_lp *lp);
void (*add_rc)(void *sched, model_net_sched_rc *rc, tw_lp *lp); void (*add_rc)(void *sched, model_net_sched_rc *rc, tw_lp *lp);
int (*next)( int (*next)(
tw_stime *poffset, tw_stime *poffset,
void *sched, void *sched,
model_net_sched_rc *rc, // NOTE: copy here when deleting remote/local events for rc
void *rc_event_save,
model_net_sched_rc *rc,
tw_lp *lp); tw_lp *lp);
void (*next_rc)(void * sched, model_net_sched_rc *rc, tw_lp *lp); void (*next_rc)(void * sched, void *rc_event_save,
model_net_sched_rc *rc, tw_lp *lp);
} model_net_sched_interface; } model_net_sched_interface;
/// overall scheduler struct - type puns the actual data structure /// overall scheduler struct - type puns the actual data structure
...@@ -77,6 +80,7 @@ struct model_net_sched_s { ...@@ -77,6 +80,7 @@ struct model_net_sched_s {
struct model_net_sched_rc_s { struct model_net_sched_rc_s {
// NOTE: sched implementations may need different types, but for now they // NOTE: sched implementations may need different types, but for now they
// are equivalent // are equivalent
model_net_request req; // request gets deleted...
int rtn; // return code from a sched_next int rtn; // return code from a sched_next
}; };
...@@ -96,11 +100,13 @@ void model_net_sched_init( ...@@ -96,11 +100,13 @@ void model_net_sched_init(
int model_net_sched_next( int model_net_sched_next(
tw_stime *poffset, tw_stime *poffset,
model_net_sched *sched, model_net_sched *sched,
void *rc_event_save,
model_net_sched_rc *sched_rc, model_net_sched_rc *sched_rc,
tw_lp *lp); tw_lp *lp);
void model_net_sched_next_rc( void model_net_sched_next_rc(
model_net_sched *sched, model_net_sched *sched,
void *rc_event_save,
model_net_sched_rc *sched_rc, model_net_sched_rc *sched_rc,
tw_lp *lp); tw_lp *lp);
......
...@@ -255,7 +255,8 @@ void handle_sched_next( ...@@ -255,7 +255,8 @@ void handle_sched_next(
model_net_wrap_msg * m, model_net_wrap_msg * m,
tw_lp * lp){ tw_lp * lp){
tw_stime poffset; tw_stime poffset;
int ret = model_net_sched_next(&poffset, ns->sched, &m->msg.m_base.rc, lp); int ret = model_net_sched_next(&poffset, ns->sched, m+1,
&m->msg.m_base.rc, lp);
// we only need to know whether scheduling is finished or not - if not, // we only need to know whether scheduling is finished or not - if not,
// go to the 'next iteration' of the loop // go to the 'next iteration' of the loop
if (ret == -1){ if (ret == -1){
...@@ -278,7 +279,7 @@ void handle_sched_next_rc( ...@@ -278,7 +279,7 @@ void handle_sched_next_rc(
tw_bf *b, tw_bf *b,
model_net_wrap_msg * m, model_net_wrap_msg * m,
tw_lp * lp){ tw_lp * lp){
model_net_sched_next_rc(ns->sched, &m->msg.m_base.rc, lp); model_net_sched_next_rc(ns->sched, m+1, &m->msg.m_base.rc, lp);
if (b->c0){ if (b->c0){
ns->in_sched_loop = 1; ns->in_sched_loop = 1;
......
...@@ -20,10 +20,6 @@ typedef struct mn_sched { ...@@ -20,10 +20,6 @@ typedef struct mn_sched {
// method containing packet event to call // method containing packet event to call
struct model_net_method *method; struct model_net_method *method;
struct qlist_head reqs; // of type mn_sched_qitem struct qlist_head reqs; // of type mn_sched_qitem
// this is an unfortunate result - we have to basically not free anything
// in order to keep around the remote and local events
// we desperately need GVT hooks to run our own garbage collection
struct qlist_head free_reqs;
} mn_sched; } mn_sched;
typedef struct mn_sched_qitem { typedef struct mn_sched_qitem {
...@@ -53,8 +49,10 @@ static void fcfs_add ( ...@@ -53,8 +49,10 @@ static void fcfs_add (
model_net_sched_rc *rc, model_net_sched_rc *rc,
tw_lp *lp); tw_lp *lp);
static void fcfs_add_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp); static void fcfs_add_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp);
static int fcfs_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp); static int fcfs_next(tw_stime *poffset, void *sched, void *rc_event_save,
static void fcfs_next_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp); model_net_sched_rc *rc, tw_lp *lp);
static void fcfs_next_rc(void *sched, void *rc_event_save,
model_net_sched_rc *rc, tw_lp *lp);
static void rr_init (struct model_net_method *method, void ** sched); static void rr_init (struct model_net_method *method, void ** sched);
static void rr_destroy (void *sched); static void rr_destroy (void *sched);
...@@ -68,8 +66,10 @@ static void rr_add ( ...@@ -68,8 +66,10 @@ static void rr_add (
model_net_sched_rc *rc, model_net_sched_rc *rc,
tw_lp *lp); tw_lp *lp);
static void rr_add_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp); static void rr_add_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp);
static int rr_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp); static int rr_next(tw_stime *poffset, void *sched, void *rc_event_save,
static void rr_next_rc (void *sched, model_net_sched_rc *rc, tw_lp *lp); model_net_sched_rc *rc, tw_lp *lp);
static void rr_next_rc (void *sched, void *rc_event_save,
model_net_sched_rc *rc, tw_lp *lp);
/// function tables (names defined by X macro in model-net-sched.h) /// function tables (names defined by X macro in model-net-sched.h)
static model_net_sched_interface fcfs_tab = static model_net_sched_interface fcfs_tab =
...@@ -90,7 +90,6 @@ void fcfs_init(struct model_net_method *method, void ** sched){ ...@@ -90,7 +90,6 @@ void fcfs_init(struct model_net_method *method, void ** sched){
mn_sched *ss = *sched; mn_sched *ss = *sched;
ss->method = method; ss->method = method;
INIT_QLIST_HEAD(&ss->reqs); INIT_QLIST_HEAD(&ss->reqs);
INIT_QLIST_HEAD(&ss->free_reqs);
} }
void fcfs_destroy(void *sched){ void fcfs_destroy(void *sched){
...@@ -112,17 +111,18 @@ void fcfs_add ( ...@@ -112,17 +111,18 @@ void fcfs_add (
// we'll figure out a better way to handle this. // we'll figure out a better way to handle this.
mn_sched_qitem *q = malloc(sizeof(mn_sched_qitem)); mn_sched_qitem *q = malloc(sizeof(mn_sched_qitem));
assert(q); assert(q);
memset(q, 0, sizeof(*q));
q->req = *req; q->req = *req;
q->rem = req->is_pull ? PULL_MSG_SIZE : req->msg_size; q->rem = req->is_pull ? PULL_MSG_SIZE : req->msg_size;
if (remote_event_size > 0){ if (remote_event_size > 0){
q->remote_event = malloc(remote_event_size); q->remote_event = malloc(remote_event_size);
memcpy(q->remote_event, remote_event, remote_event_size); memcpy(q->remote_event, remote_event, remote_event_size);
} }
else { q->remote_event = NULL; }
if (local_event_size > 0){ if (local_event_size > 0){
q->local_event = malloc(local_event_size); q->local_event = malloc(local_event_size);
memcpy(q->local_event, local_event, local_event_size); memcpy(q->local_event, local_event, local_event_size);
} }
else { q->local_event = NULL; }
mn_sched *s = sched; mn_sched *s = sched;
qlist_add_tail(&q->ql, &s->reqs); qlist_add_tail(&q->ql, &s->reqs);
} }
...@@ -132,12 +132,14 @@ void fcfs_add_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp){ ...@@ -132,12 +132,14 @@ void fcfs_add_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp){
struct qlist_head *ent = qlist_pop_back(&s->reqs); struct qlist_head *ent = qlist_pop_back(&s->reqs);
assert(ent != NULL); assert(ent != NULL);
mn_sched_qitem *q = qlist_entry(ent, mn_sched_qitem, ql); mn_sched_qitem *q = qlist_entry(ent, mn_sched_qitem, ql);
if (q->remote_event) free(q->remote_event); // free'ing NULLs is a no-op
if (q->local_event) free(q->local_event); free(q->remote_event);
free(q->local_event);
free(q); free(q);
} }
int fcfs_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp){ int fcfs_next(tw_stime *poffset, void *sched, void *rc_event_save,
model_net_sched_rc *rc, tw_lp *lp){
mn_sched *s = sched; mn_sched *s = sched;
struct qlist_head *ent = s->reqs.next; struct qlist_head *ent = s->reqs.next;
if (ent == &s->reqs){ if (ent == &s->reqs){
...@@ -163,10 +165,21 @@ int fcfs_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp) ...@@ -163,10 +165,21 @@ int fcfs_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp)
q->req.remote_event_size, q->remote_event, q->req.self_event_size, q->req.remote_event_size, q->remote_event, q->req.self_event_size,
q->local_event, q->req.src_lp, lp, is_last_packet); q->local_event, q->req.src_lp, lp, is_last_packet);
// if last packet - remove from list, put into free list // if last packet - remove from list, free, save for rc
if (is_last_packet){ if (is_last_packet){
qlist_pop(&s->reqs); qlist_pop(&s->reqs);
qlist_add_tail(&q->ql, &s->free_reqs); rc->req = q->req;
void *e_dat = rc_event_save;
if (q->req.remote_event_size > 0){
memcpy(e_dat, q->remote_event, q->req.remote_event_size);
e_dat = (char*) e_dat + q->req.remote_event_size;
free(q->remote_event);
}
if (q->req.self_event_size > 0){
memcpy(e_dat, q->local_event, q->req.self_event_size);
free(q->local_event);
}
free(q);
rc->rtn = 1; rc->rtn = 1;
} }
else{ else{
...@@ -176,7 +189,8 @@ int fcfs_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp) ...@@ -176,7 +189,8 @@ int fcfs_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp)
return rc->rtn; return rc->rtn;
} }
void fcfs_next_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp){ void fcfs_next_rc(void *sched, void *rc_event_save, model_net_sched_rc *rc,
tw_lp *lp){
mn_sched *s = sched; mn_sched *s = sched;
if (rc->rtn == -1){ if (rc->rtn == -1){
// no op // no op
...@@ -190,7 +204,26 @@ void fcfs_next_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp){ ...@@ -190,7 +204,26 @@ void fcfs_next_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp){
q->rem += q->req.packet_size; q->rem += q->req.packet_size;
} }
else if (rc->rtn == 1){ else if (rc->rtn == 1){
qlist_add(qlist_pop_back(&s->free_reqs), &s->reqs); // re-create the q item
mn_sched_qitem *q = malloc(sizeof(mn_sched_qitem));
assert(q);
q->req = rc->req;
q->rem = q->req.msg_size % q->req.packet_size;
if (q->rem == 0){ // processed exactly a packet's worth of data
q->rem = q->req.packet_size;
}
void * e_dat = rc_event_save;
if (q->req.remote_event_size > 0){
q->remote_event = malloc(q->req.remote_event_size);
memcpy(q->remote_event, e_dat, q->req.remote_event_size);
e_dat = (char*) e_dat + q->req.remote_event_size;
}
if (q->req.self_event_size > 0) {
q->local_event = malloc(q->req.self_event_size);
memcpy(q->local_event, e_dat, q->req.self_event_size);
}
// add back to front of list
qlist_add(&q->ql, &s->reqs);
} }
else { else {
assert(0); assert(0);
...@@ -203,7 +236,6 @@ void rr_init (struct model_net_method *method, void ** sched){ ...@@ -203,7 +236,6 @@ void rr_init (struct model_net_method *method, void ** sched){
mn_sched *ss = *sched; mn_sched *ss = *sched;
ss->method = method; ss->method = method;
INIT_QLIST_HEAD(&ss->reqs); INIT_QLIST_HEAD(&ss->reqs);
INIT_QLIST_HEAD(&ss->free_reqs);
} }
void rr_destroy (void *sched){ void rr_destroy (void *sched){
...@@ -247,7 +279,8 @@ void rr_add_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp){ ...@@ -247,7 +279,8 @@ void rr_add_rc(void *sched, model_net_sched_rc *rc, tw_lp *lp){
free(q); free(q);
} }
int rr_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp){ int rr_next(tw_stime *poffset, void *sched, void *rc_event_save,
model_net_sched_rc *rc, tw_lp *lp){
mn_sched *s = sched; mn_sched *s = sched;
struct qlist_head *ent = qlist_pop(&s->reqs); struct qlist_head *ent = qlist_pop(&s->reqs);
if (ent == NULL){ if (ent == NULL){
...@@ -273,9 +306,20 @@ int rr_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp){ ...@@ -273,9 +306,20 @@ int rr_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp){
q->req.remote_event_size, q->remote_event, q->req.self_event_size, q->req.remote_event_size, q->remote_event, q->req.self_event_size,
q->local_event, q->req.src_lp, lp, is_last_packet); q->local_event, q->req.src_lp, lp, is_last_packet);
// if last packet - remove from list, put into free list // if last packet - remove from list, free, save for rc
if (is_last_packet){ if (is_last_packet){
qlist_add_tail(&q->ql, &s->free_reqs); rc->req = q->req;
void *e_dat = rc_event_save;
if (q->req.remote_event_size > 0){
memcpy(e_dat, q->remote_event, q->req.remote_event_size);
e_dat = (char*) e_dat + q->req.remote_event_size;
free(q->remote_event);
}
if (q->req.self_event_size > 0){
memcpy(e_dat, q->local_event, q->req.self_event_size);
free(q->local_event);
}
free(q);
rc->rtn = 1; rc->rtn = 1;
} }
else{ else{
...@@ -286,7 +330,7 @@ int rr_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp){ ...@@ -286,7 +330,7 @@ int rr_next(tw_stime *poffset, void *sched, model_net_sched_rc *rc, tw_lp *lp){
return rc->rtn; return rc->rtn;
} }
void rr_next_rc (void *sched, model_net_sched_rc *rc, tw_lp *lp){ void rr_next_rc (void *sched, void *rc_event_save, model_net_sched_rc *rc, tw_lp *lp){
mn_sched *s = sched; mn_sched *s = sched;
if (rc->rtn == -1){ if (rc->rtn == -1){
// no op // no op
...@@ -301,9 +345,26 @@ void rr_next_rc (void *sched, model_net_sched_rc *rc, tw_lp *lp){ ...@@ -301,9 +345,26 @@ void rr_next_rc (void *sched, model_net_sched_rc *rc, tw_lp *lp){
q->rem += q->req.packet_size; q->rem += q->req.packet_size;
} }
else if (rc->rtn == 1){ else if (rc->rtn == 1){
// put back to *front* of list. We know it's the front because it was // re-create the q item
// in the front when it was deleted mn_sched_qitem *q = malloc(sizeof(mn_sched_qitem));
qlist_add(qlist_pop_back(&s->free_reqs), &s->reqs); assert(q);
q->req = rc->req;
q->rem = q->req.msg_size % q->req.packet_size;
if (q->rem == 0){ // processed exactly a packet's worth of data
q->rem = q->req.packet_size;
}
void * e_dat = rc_event_save;
if (q->req.remote_event_size > 0){
q->remote_event = malloc(q->req.remote_event_size);
memcpy(q->remote_event, e_dat, q->req.remote_event_size);
e_dat = (char*) e_dat + q->req.remote_event_size;
}
if (q->req.self_event_size > 0) {
q->local_event = malloc(q->req.self_event_size);
memcpy(q->local_event, e_dat, q->req.self_event_size);
}
// add back to front of list
qlist_add(&q->ql, &s->reqs);
} }
else { else {
assert(0); assert(0);
......
...@@ -42,16 +42,18 @@ void model_net_sched_init( ...@@ -42,16 +42,18 @@ void model_net_sched_init(
int model_net_sched_next( int model_net_sched_next(
tw_stime *poffset, tw_stime *poffset,
model_net_sched *sched, model_net_sched *sched,
void *rc_event_save,
model_net_sched_rc *sched_rc, model_net_sched_rc *sched_rc,
tw_lp *lp){ tw_lp *lp){
return sched->impl->next(poffset, sched->dat, sched_rc, lp); return sched->impl->next(poffset, sched->dat, rc_event_save, sched_rc, lp);
} }
void model_net_sched_next_rc( void model_net_sched_next_rc(
model_net_sched *sched, model_net_sched *sched,
void *rc_event_save,
model_net_sched_rc *sched_rc, model_net_sched_rc *sched_rc,
tw_lp *lp) { tw_lp *lp) {
sched->impl->next_rc(sched->dat, sched_rc, lp); sched->impl->next_rc(sched->dat, rc_event_save, sched_rc, lp);
} }
void model_net_sched_add( void model_net_sched_add(
......
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