Переглянути джерело

Have the dpnode compute and send the DL to the controller

When a collision occurs, the dpnode now computes the desired DL
and sends it to the controller.  The controller currently doesn't know
what to do with it, however.

The dpnode also closes its connections to its workers at that point,
which seems to cause the worker threads to hang; investigation of this
is also needed.
Ian Goldberg 14 роки тому
батько
коміт
d82074b1b5
1 змінених файлів з 26 додано та 5 видалено
  1. 26 5
      dpnode.cc

+ 26 - 5
dpnode.cc

@@ -30,13 +30,15 @@ struct DPNodeConnInfo {
 };
 };
 
 
 static struct DPControllerState {
 static struct DPControllerState {
+    struct bufferevent *controller_bev;
     Subproblem *current_problem;
     Subproblem *current_problem;
     struct evconnlistener *listener;
     struct evconnlistener *listener;
     std::set<struct bufferevent *> workers;
     std::set<struct bufferevent *> workers;
     DTable table;
     DTable table;
     unsigned long long numdps;
     unsigned long long numdps;
 
 
-    DPControllerState() : current_problem(NULL), listener(NULL) {}
+    DPControllerState() : controller_bev(NULL), current_problem(NULL),
+			    listener(NULL) {}
 } dpctrlstate;
 } dpctrlstate;
 
 
 static void dpnode_event_cb(struct bufferevent *bev, short events,
 static void dpnode_event_cb(struct bufferevent *bev, short events,
@@ -50,11 +52,12 @@ static void dpnode_event_cb(struct bufferevent *bev, short events,
     }
     }
 }
 }
 
 
+static void stop_problem(void);
+
 static void dpnode_reader(struct bufferevent *bev, void *ctx)
 static void dpnode_reader(struct bufferevent *bev, void *ctx)
 {
 {
     struct evbuffer *input = bufferevent_get_input(bev);
     struct evbuffer *input = bufferevent_get_input(bev);
     unsigned int dp[WORDS+6];
     unsigned int dp[WORDS+6];
-    pair<DTable::iterator, bool> res;
 
 
     while(1) {
     while(1) {
 	size_t len = evbuffer_get_length(input);
 	size_t len = evbuffer_get_length(input);
@@ -71,14 +74,31 @@ static void dpnode_reader(struct bufferevent *bev, void *ctx)
 		3*sizeof(unsigned int));
 		3*sizeof(unsigned int));
 	string x((const char *)(dp), WORDS*sizeof(unsigned int));
 	string x((const char *)(dp), WORDS*sizeof(unsigned int));
 	pair<ZZ,ZZ> ab(zz_a,zz_b);
 	pair<ZZ,ZZ> ab(zz_a,zz_b);
-	res = dpctrlstate.table.insert(DTable::value_type(x,ab));
+	pair<DTable::iterator, bool> res =
+		dpctrlstate.table.insert(DTable::value_type(x,ab));
+
 	if (!res.second) {
 	if (!res.second) {
+	    const ZZ& order = dpctrlstate.current_problem->order;
 	    // Collision!
 	    // Collision!
-	    cerr << "Collision!\n";
+	    ZZ adiff = to_ZZ(res.first->second.first) - zz_a;
+	    ZZ bdiff = zz_b - to_ZZ(res.first->second.second);
+	    while (bdiff < 0) bdiff += order;
+	    while (bdiff >= order) bdiff -= order;
+	    while (adiff < 0) adiff += order;
+	    while (adiff >= order) adiff -= order;
+	    ZZ binv;
+	    if (InvModStatus(binv, bdiff, order) == 0) {
+		ZZ expon = MulMod(binv, adiff, order);
+		cerr << "Collision after " << dpctrlstate.numdps << " DPs\n";
+		unsigned char exponbytes[3*sizeof(unsigned int)];
+		BytesFromZZ(exponbytes, expon, 3*sizeof(unsigned int));
+		bufferevent_write(dpctrlstate.controller_bev, exponbytes,
+		    3*sizeof(unsigned int));
+		stop_problem();
+	    }
 	}
 	}
 	++dpctrlstate.numdps;
 	++dpctrlstate.numdps;
     }
     }
-    // cerr << num_read << " DPs read\n";
 }
 }
 
 
 static void dpnode_accept_cb(struct evconnlistener *listener,
 static void dpnode_accept_cb(struct evconnlistener *listener,
@@ -218,6 +238,7 @@ static void controllerconn_event_cb(struct bufferevent *bev, short events,
 	bufferevent_write(bev, id, 1);
 	bufferevent_write(bev, id, 1);
 	bufferevent_setcb(bev, controllerconn_reader, NULL,
 	bufferevent_setcb(bev, controllerconn_reader, NULL,
 		controllerconn_event_cb, new DPControllerConnInfo());
 		controllerconn_event_cb, new DPControllerConnInfo());
+	dpctrlstate.controller_bev = bev;
     } else if (events & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
     } else if (events & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
 	fprintf(stderr, "Closing connection to controller and exiting\n");
 	fprintf(stderr, "Closing connection to controller and exiting\n");
 	event_base_loopbreak(bufferevent_get_base(bev));
 	event_base_loopbreak(bufferevent_get_base(bev));