#include #include #include /* mergetwo pid1 pid2 */ #define ERROREXIT(msg) ( fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,msg), exit(1) ) #define MAXBUF 100 static int mergerequest( const pid_t pid1, const MPAGEINFO info1, const pid_t pid2, const MPAGEINFO info2, MEQUALPAIR *const pagepairp) { if (info1.p_addr == info2.p_addr) { if (info1.p_addr == NULL) printf("Some p_addr == NULL\n"); return 1==2; } if (info1.count < info2.count) { pagepairp->spid = pid1; pagepairp->sv_addr = info1.v_addr; pagepairp->dpid = pid2; pagepairp->dv_addr = info2.v_addr; } else { pagepairp->spid = pid2; pagepairp->sv_addr = info2.v_addr; pagepairp->dpid = pid1; pagepairp->dv_addr = info1.v_addr; } return 1==1; } size_t getcompletepageinfos( const pid_t pid, const void *start, const void *end, MPAGEINFO * const pageinfos, const size_t nel, unsigned long (*hashfunction1)(const void* addr, size_t size), unsigned long (*hashfunction2)(const void* addr, size_t size) ) { const void *cont; size_t i, iel, hashed1, hashed2; MPAGEINFO * pageinfos2; printf("retrieving at most %d pages from process %d\n", nel, pid); if ( ( iel = m_getpageinfos( pid, start, end, pageinfos, nel, &cont ) ) == -1 ) ERROREXIT(strerror(errno)); printf("got %d pages from %d, cont == %p\n", iel, nel, cont); for ( i = 0; i < iel; i++) { if ( pageinfos[i].v_addr == NULL ) printf("pageinfos[%d] == NULL\n",i); if ( pageinfos[i].count == 0 ) printf("pageinfos[%d] == 0\n",i); if ( pageinfos[i].p_addr == 0 ) printf("pageinfos[%d] == 0\n",i); } printf("hashing with bip_hash...\n"); if ( ( hashed1 = m_hashpages( pid, pageinfos, iel, hashfunction1) ) == -1 ) ERROREXIT(strerror(errno)); pageinfos2 = calloc(iel, sizeof(MPAGEINFO)); if (pageinfos2 == NULL) ERROREXIT("cannot allocate space for pageinfos2"); for (i = 0 ; i < iel; i++) { pageinfos2[i].v_addr = pageinfos[i].v_addr; } printf("now hashing with the corresponding library function ...\n"); if ( ( hashed2 = m_hashpages( pid, pageinfos2, iel, hashfunction2) ) == - 1) ERROREXIT(strerror(errno)); if (hashed1 != hashed2) ERROREXIT("the hashes are differnt"); for ( i = 0; i < iel; i++) { /* printf("pageinfos[%d] = { %p, %p, %d, %lx }\n", i, pageinfos[i].v_addr, pageinfos[i].p_addr, pageinfos[i].count, pageinfos[i].hash ); */ if ( pageinfos[i].v_addr != pageinfos2[i].v_addr ) printf("pageinfos[%d]: v_addr not equal: %p vs %p\n", i, pageinfos[i].v_addr, pageinfos2[i].v_addr); if ( pageinfos[i].p_addr != pageinfos2[i].p_addr ) printf("pageinfos[%d]: p_addr not equal: %p vs %p\n", i, pageinfos[i].p_addr, pageinfos2[i].p_addr); if ( pageinfos[i].count != pageinfos2[i].count ) printf("pageinfos[%d]: count not equal: %d vs %d\n", i, pageinfos[i].count, pageinfos2[i].count); if ( pageinfos[i].hash != pageinfos2[i].hash ) printf("pageinfos[%d]: hash not equal: %lx vs %lx\n", i, pageinfos[i].hash, pageinfos2[i].hash); } return iel; } int main(const int argc, const char * const argv[]) { MPAGEINFO *pageinfos1, *pageinfos2; MEQUALPAIR *pagepairs; ssize_t nel, iel1, iel2, i1, i2, j, eq; pid_t pid1, pid2; const void *minp, *maxp; if (argc != 5) ERROREXIT("Usage: mergetwo nel hexaddr-hexaddr pid1 pid2"); nel = atol(argv[1]); if ( sscanf(argv[2],"%p-%p",&minp,&maxp) != 2) ERROREXIT("2nd argument should be hexaddr-hexaddr"); pid1 = atol(argv[3]); pid2 = atol(argv[4]); pageinfos1 = calloc(nel, sizeof(MPAGEINFO)); pageinfos2 = calloc(nel, sizeof(MPAGEINFO)); pagepairs = calloc(nel, sizeof(MEQUALPAIR)); printf("Space allocated\n"); if ( pageinfos1 == NULL || pageinfos2 == NULL || pagepairs == NULL ) ERROREXIT("No more memory"); printf("testing m_hash_const...\n"); iel1 = getcompletepageinfos( pid1, minp, maxp, pageinfos1, nel, m_hash_const, m_libhash_const ); iel2 = getcompletepageinfos( pid2, minp, maxp, pageinfos2, nel, m_hash_const, m_libhash_const); printf("testing m_hash_addrothalf...\n"); iel1 = getcompletepageinfos( pid1, minp, maxp, pageinfos1, nel, m_hash_addrothalf, m_libhash_addrothalf ); iel2 = getcompletepageinfos( pid2, minp, maxp, pageinfos2, nel, m_hash_addrothalf, m_libhash_addrothalf); j = 0; i1 = i2 = 0; eq = 0; while (i1 < iel1 && i2 < iel2 ) { if ( pageinfos1[i1].v_addr == pageinfos1[i2].v_addr ) { eq++; if (mergerequest(pid1, pageinfos1[i1], pid2, pageinfos2[i2], &pagepairs[j])) j++; i1++; i2++; } else if ( pageinfos1[i1].v_addr > pageinfos2[i2].v_addr ) i2++; else i1++; } printf("Prepared %d requests (%d were virtually equal), now merging ...\n",j,eq); j = m_merge(pagepairs, j); if ( j == -1 ) ERROREXIT(strerror(errno)); printf("mergetwo merged %d pages\n",j); return 0; }