Просмотр исходного кода

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 лет назад
Родитель
Сommit
d82074b1b5
1 измененных файлов с 26 добавлено и 5 удалено
  1. 26 5
      dpnode.cc

+ 26 - 5
dpnode.cc

@@ -30,13 +30,15 @@ struct DPNodeConnInfo {
 };
 
 static struct DPControllerState {
+    struct bufferevent *controller_bev;
     Subproblem *current_problem;
     struct evconnlistener *listener;
     std::set<struct bufferevent *> workers;
     DTable table;
     unsigned long long numdps;
 
-    DPControllerState() : current_problem(NULL), listener(NULL) {}
+    DPControllerState() : controller_bev(NULL), current_problem(NULL),
+			    listener(NULL) {}
 } dpctrlstate;
 
 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)
 {
     struct evbuffer *input = bufferevent_get_input(bev);
     unsigned int dp[WORDS+6];
-    pair<DTable::iterator, bool> res;
 
     while(1) {
 	size_t len = evbuffer_get_length(input);
@@ -71,14 +74,31 @@ static void dpnode_reader(struct bufferevent *bev, void *ctx)
 		3*sizeof(unsigned int));
 	string x((const char *)(dp), WORDS*sizeof(unsigned int));
 	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) {
+	    const ZZ& order = dpctrlstate.current_problem->order;
 	    // 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;
     }
-    // cerr << num_read << " DPs read\n";
 }
 
 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_setcb(bev, controllerconn_reader, NULL,
 		controllerconn_event_cb, new DPControllerConnInfo());
+	dpctrlstate.controller_bev = bev;
     } else if (events & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
 	fprintf(stderr, "Closing connection to controller and exiting\n");
 	event_base_loopbreak(bufferevent_get_base(bev));