diff --git a/examples/6_constraint_solve/main.c b/examples/6_constraint_solve/main.c index dfb5fff5279fd85a2ca37fe175d5d60fceb516b4..6084ffd933f6ca9beb1a665ce80787868127bdde 100644 --- a/examples/6_constraint_solve/main.c +++ b/examples/6_constraint_solve/main.c @@ -1,65 +1,103 @@ #include #include #include -#include +#include #include "../../reowolf.h" #include "../utility.c" +#define N 4 + +typedef struct PeerInfo { + int id; + bool puts; // true iff the channel to this peer is INCOMING. +} PeerInfo; + +// return the index of (i,j) in the lexicographic ordering of set {(i,j) : ij +int combination_index(int i, int j) { + if (i > j) { + // swap! + i ^= j; + j ^= i; + i ^= j; + } + assert(0 <= i); + assert(i < j); + assert(j < N); + + int idx_in_square = i*N + j; + int skipped = ((i+1) * (i+2)) / 2; + return idx_in_square - skipped; +} + +// initializes the given 3-element array, +// breaking symmetry with put-get direction. +void init_peer_infos(PeerInfo * peer_infos, int my_id) { + int i; + for (i = 0; i < 3; i++) { + PeerInfo * pi = &peer_infos[i]; + pi->puts = i < my_id; + pi->id = i < my_id ? i : i+1; + printf("info %d puts=%d id=%d\n", i, pi->puts, pi->id); + } +} + +const char* addrs[] = { + "127.0.0.1:7000", + "127.0.0.1:7001", + "127.0.0.1:7002", + "127.0.0.1:7003", + "127.0.0.1:7004", + "127.0.0.1:7005", +}; int main(int arg_c, char * argv[]) { - int index; + int my_id, peer_id, i; if (arg_c != 2) { printf("Expected one arg: which peer I am in 0..4"); return 1; } - index = atoi(argv[1]); - printf("I am peer %d\n", index); + my_id = atoi(argv[1]); + assert(0 <= my_id && my_id < N); + printf("I have id %d\n", my_id); - const char* addrs[] = { - "127.0.0.1:7000", - "127.0.0.1:7001", - "127.0.0.1:7002", - "127.0.0.1:7003", - "127.0.0.1:7004", - "127.0.0.1:7005", - }; - char * pdl = buffer_pdl("eg_protocols.pdl"); Connector* c = connector_new(); printf("configuring...\n"); - check("config ", connector_configure(c, pdl, "xor_three")); - int i, j; - int addr_index = 0; - int port = 0; - for (i = 0; i < 4; i++) { - for (j = i+1; j < 4; j++) { - if (i==index) { - printf("ports %d and %d are for a passive channel to peer %d over addr %s\n", port, port+1, j, addrs[addr_index]); - check("bind an ", connector_bind_native(c, port)); - port++; - check("bind a ", connector_bind_active(c, port, addrs[addr_index])); - port++; - } else if (j==index) { - printf("ports %d and %d are for an active channel to peer %d over addr %s\n", port, port+1, i, addrs[addr_index]); - check("bind p ", connector_bind_passive(c, port, addrs[addr_index])); - port++; - check("bind pn ", connector_bind_native(c, port)); - port++; - } - addr_index++; + + PeerInfo peer_infos[3]; + init_peer_infos(peer_infos, my_id); + + // for every native port, bind native and protocol port. + for (i = 0; i < 3; i++) { + PeerInfo * pi = &peer_infos[i]; + int addr_idx = combination_index(my_id, pi->id); + if (pi->puts) { + check("bind to putter ", + connector_bind_passive(c, i*2, addrs[addr_idx])); + check("bind native ", connector_bind_native(c, i*2 + 1)); + } else { + check("bind native ", connector_bind_native(c, i*2)); + check("bind to putter ", + connector_bind_active(c, i*2 + 1, addrs[addr_idx])); } } + printf("connecting...\n"); check("connect", connector_connect(c, 5000)); - for (i = 0; i < 4; i++) { - if (i == index) continue; - // another batch - for (j = 0; j < 4; j++) { - - } + // for every native port, create a singleton batch + for (i = 0; i < 3; i++) { + if (i > 0) check("next ", connector_next_batch(c)); + PeerInfo * pi = &peer_infos[i]; + check("op ", pi->puts? + connector_get(c, i): + connector_put(c, i, NULL, 0)); } - connector_sync(); + // solve! + int batch_idx = connector_sync(c, 3000); + if (batch_idx < 0) printf("Error code on sync! %d\n", batch_idx); + else printf("I was paired with peer %d\n", peer_infos[batch_idx].id); printf("destroying...\n"); connector_destroy(c);