// --------------------------------------------------------------------- // is_correct // --------------------------------------------------------------------- int is_correct(rlist* in, rlist* out) { if (rlist_length(in) != rlist_length(out)) return 0; rnode* p; for (p = rlist_first(out); p != NULL; p = rlist_next(p)) if (rlist_next(p) != NULL && rlist_val(p) > rlist_val(rlist_next(p))) return 0; return 1; }
// --------------------------------------------------------------------- // rlist_rnd_batch_ins_rem_updates // --------------------------------------------------------------------- size_t rlist_rnd_batch_ins_rem_updates(rlist* list, size_t k, void (*callback)(void*), void* param) { int j; rnode* node; size_t num_changes = 0, num_updates = 0; dc_begin_at(); // cycles through list 3 times... for (j = 0; j < 3; j++) { // process list head if ((rand_pm() % 2)==0) rlist_insert_first(list, rand_pm()); else rlist_remove_first(list); num_changes++; // process list tail... for (node = rlist_first(list); node != NULL; node = rlist_next(node)) { if ((rand_pm() % 2)==0 || rlist_next(node) == 0) rlist_insert_next(list, node, rand_pm()); else rlist_remove_next(list, node); num_changes++; if (num_changes == k) { num_changes = 0; dc_end_at(); if (callback) callback(param); num_updates++; dc_begin_at(); } } } dc_end_at(); if (num_changes != 0) { if (callback) callback(param); num_updates++; } return num_updates; }
// --------------------------------------------------------------------- // mapper_delete // --------------------------------------------------------------------- void mapper_delete(mapper* m) { rnode* node; for (node = rlist_first(m->in); node != NULL; node = rlist_next(node)) { mnode* c = (mnode*)rlist_param(node); dc_del_cons(c->cons); free(c); } rlist_unsubscribe(m->in); free(m); }
// --------------------------------------------------------------------- // rlist_rem_ins_updates // --------------------------------------------------------------------- size_t rlist_rem_ins_updates(rlist* list, void (*callback)(void*), void* param) { rnode* node; size_t num_updates = 2; if (rlist_first(list) == NULL) return 0; int val = rlist_val(rlist_first(list)); rlist_remove_first(list); if (callback) callback(param); rlist_insert_first(list, val); if (callback) callback(param); for (node = rlist_first(list); node != NULL && rlist_next(node) != NULL; node = rlist_next(node)) { val = rlist_val(rlist_next(node)); rlist_remove_next(list, node); if (callback) callback(param); rlist_insert_next(list, node, val); if (callback) callback(param); num_updates += 2; } return num_updates; }
// --------------------------------------------------------------------- // rlist_rnd_change_updates // --------------------------------------------------------------------- size_t rlist_rnd_change_updates(rlist* list, void (*callback)(void*), void* param) { rnode* node; size_t num_updates = 0; for (node = rlist_first(list); node != NULL; node = rlist_next(node)) { int val = rlist_val(node); dc_begin_at(); rlist_set_val(node, rand_pm()); dc_end_at(); if (callback) callback(param); dc_begin_at(); rlist_set_val(node, val); dc_end_at(); if (callback) callback(param); num_updates += 2; } return num_updates; }
// --------------------------------------------------------------------- // rlist_incr_decr_updates // --------------------------------------------------------------------- size_t rlist_incr_decr_updates(rlist* list, int delta, void (*callback)(void*), void* param) { rnode* node; size_t num_updates = 0; for (node = rlist_first(list); node != NULL; node = rlist_next(node)) { int val = rlist_val(node); dc_begin_at(); rlist_set_val(node, val+delta); dc_end_at(); if (callback) callback(param); dc_begin_at(); rlist_set_val(node, val); dc_end_at(); if (callback) callback(param); num_updates += 2; } return num_updates; }
// --------------------------------------------------------------------- // mapper_new // --------------------------------------------------------------------- mapper* mapper_new(rlist* in, rlist* out, mapper_map_t map) { mapper* m = malloc(sizeof(mapper)); if (m == NULL) panic("out of memory"); m->in = in; m->out = out; m->map = map; rlist_remove_all(out); rlist_subscribe(in, m, (rlist_ins_t)ins, (rlist_rem_t)rem); dc_begin_at(); rnode *pred, *node; for (pred = NULL, node = rlist_first(in); node != NULL; node = rlist_next(node)) { ins(m, pred); pred = node; } dc_end_at(); return m; }
// --------------------------------------------------------------------- // test_large // --------------------------------------------------------------------- void test_large(unsigned long long* count) { dc_profile init, end; #if VERBOSE dc_profile start; #endif printf("--making initial list of %d items\n", N); rlist* in = rlist_new_rand(N, MAX_VAL); rlist* out = rlist_new(); puts("--making sorter"); dc_fetch_profile_info(&init); sorter* q = _sorter(new)(in, out); if (q == NULL) { printf("error: cannot initialize sorter\n"); exit(0); } dc_fetch_profile_info(&end); dc_dump_profile_diff(stdout, &init, &end); check_correctness(in, out); puts("\n--making ins/rem operations on input list"); size_t num_updates = 0; int val; dc_fetch_profile_info(&init); #if VERBOSE dc_fetch_profile_info(&start); #endif val = rlist_val(rlist_first(in)); #if VERBOSE printf("<r"); fflush(stdout); #endif #if INS_REM == 1 rlist_remove_first(in); #else rlist_set_val(rlist_first(in), UPDATE(val)); #endif #if VERBOSE printf("><i"); fflush(stdout); #endif #if INS_REM == 1 rlist_insert_first(in, val); #else rlist_set_val(rlist_first(in), val); #endif num_updates += 2; #if VERBOSE printf(">"); fflush(stdout); printf("\n"); dc_fetch_profile_info(&end); printf("last session report:\n"); dc_dump_profile_diff(stdout, &start, &end); printf("all sessions report:\n"); debugging_dump(q, 0, &init, &end); #endif check_correctness(in, out); rnode *prev; for (prev = rlist_first(in); prev != NULL && rlist_next(prev) != NULL; prev = rlist_next(prev)) { #if VERBOSE dc_fetch_profile_info(&start); #endif val = rlist_val(rlist_next(prev)); #if VERBOSE printf("<r"); fflush(stdout); #endif #if INS_REM == 1 rlist_remove_next(in, prev); #else rlist_set_val(rlist_next(prev), UPDATE(val)); #endif #if VERBOSE printf("><i"); fflush(stdout); #endif #if INS_REM == 1 rlist_insert_next(in, prev, val); #else rlist_set_val(rlist_next(prev), val); #endif #if VERBOSE printf(">"); fflush(stdout); printf("\n"); dc_fetch_profile_info(&end); printf("last session report:\n"); dc_dump_profile_diff(stdout, &start, &end); printf("all sessions report:\n"); debugging_dump(q, 0, &init, &end); #endif check_correctness(in, out); num_updates += 2; } #if VERBOSE == 0 dc_fetch_profile_info(&end); dc_dump_profile_diff(stdout, &init, &end); #endif puts("\n--deleting sorter"); dc_fetch_profile_info(&init); _sorter(delete)(q); dc_fetch_profile_info(&end); dc_dump_profile_diff(stdout, &init, &end); puts("\n--deleting lists"); dc_fetch_profile_info(&init); rlist_delete(in); rlist_delete(out); dc_fetch_profile_info(&end); dc_dump_profile_diff(stdout, &init, &end); }
// --------------------------------------------------------------------- // test_small 3 // --------------------------------------------------------------------- void test_small(unsigned long long* count) { dc_profile init, start, end; rlist* in = rlist_new_rand(N, MAX_VAL); rlist* out = rlist_new(); printf("list length=%d\n", rlist_length(in)); puts("--initial list in/out"); dump(in, out, count); puts("--making sorter"); sorter* h = _sorter(new)(in, out); if (h == NULL) { printf("error: cannot initialize sorter\n"); exit(0); } dump(in, out, count); #if DEBUG > 0 _sorter(dump)(h); #endif puts("\n--making rnd insert operations on input list"); dc_fetch_profile_info(&init); int val; rnode *prev; size_t num_update, i, j; int updates[UPD]; srand(17); for (i=0; i<UPD; i++) updates[i] = rand(); for (num_update=0; num_update<UPD; num_update++) { i = updates[num_update] % rlist_length(in); if (i==0) { val = rand() % MAX_VAL; printf("\n--update %u: insert value %u in position %u\n", num_update+1, val, i+1); dc_fetch_profile_info(&start); rlist_insert_first(in, val); dc_fetch_profile_info(&end); debugging_dump(h, 1, &start, &end); check_correctness(in, out); continue; } // i>0: update is not on the first item prev = rlist_first(in); for (j=1; j<i; j++) prev = rlist_next(prev); val = rand() % MAX_VAL; printf("\n--update %u: insert value %u in position %u\n", num_update+1, val, i+1); dc_fetch_profile_info(&start); rlist_insert_next(in, prev, val); dc_fetch_profile_info(&end); debugging_dump(h, 1, &start, &end); check_correctness(in, out); } dc_fetch_profile_info(&end); printf("\n--sequence report\n"); debugging_dump(h, 0, &init, &end); check_correctness(in, out); puts("\n--disposing of sorter"); _sorter(delete)(h); dump(in, out, count); puts("\n--deleting lists"); rlist_delete(in); rlist_delete(out); }
// --------------------------------------------------------------------- // test_small 1 // --------------------------------------------------------------------- void test_small(unsigned long long* count) { dc_profile init, start, end; rlist* in = rlist_new_rand(N, MAX_VAL); rlist* out = rlist_new(); printf("list length=%d\n", rlist_length(in)); puts("--initial list in/out"); dump(in, out, count); puts("--making sorter"); dc_fetch_profile_info(&init); sorter* h = _sorter(new)(in, out); if (h == NULL) { printf("error: cannot initialize sorter\n"); exit(0); } dump(in, out, count); dc_fetch_profile_info(&end); debugging_dump(h, 1, &init, &end); check_correctness(in, out); #if DEBUG > 0 _sorter(dump)(h); #endif puts("\n--making ins/rem operations on input list"); size_t num_updates = 0, i = 1; dc_fetch_profile_info(&init); int val; printf("\n--remove item %u of %u\n", i, N); dc_fetch_profile_info(&start); val = rlist_val(rlist_first(in)); rlist_remove_first(in); #if DUMP == 1 dump(in, out, count); #endif dc_fetch_profile_info(&end); debugging_dump(h, 1, &start, &end); check_correctness(in, out); printf("\n--re-insert %u of %u\n", i, N); dc_fetch_profile_info(&start); rlist_insert_first(in, val); #if DUMP == 1 dump(in, out, count); #endif dc_fetch_profile_info(&end); debugging_dump(h, 1, &start, &end); check_correctness(in, out); rnode *prev; i++; for (prev = rlist_first(in); prev != NULL && rlist_next(prev) != NULL; prev = rlist_next(prev), i++) { val = rlist_val(rlist_next(prev)); printf("\n--remove item %u of %u\n", i, N); dc_fetch_profile_info(&start); rlist_remove_next(in, prev); #if DUMP == 1 dump(in, out, count); #endif dc_fetch_profile_info(&end); debugging_dump(h, 1, &start, &end); check_correctness(in, out); printf("\n--re-insert %u of %u\n", i, N); dc_fetch_profile_info(&start); rlist_insert_next(in, prev, val); #if DUMP == 1 dump(in, out, count); #endif dc_fetch_profile_info(&end); debugging_dump(h, 1, &start, &end); check_correctness(in, out); num_updates += 2; } dc_fetch_profile_info(&end); printf("\n--sequence report\n"); debugging_dump(h, 0, &init, &end); check_correctness(in, out); puts("\n--disposing of sorter"); _sorter(delete)(h); dump(in, out, count); puts("\n--deleting lists"); rlist_delete(in); rlist_delete(out); }
int fdwatch_dispatch(FDWATCH_HANDLE handle, int timeout) { FDWATCH_ITEM* item; FDWATCH_ITEM* pool[FD_SETSIZE]; int count, ret, fdmax; fd_set rdfds, wrfds, erfds; assert(handle && handle->inuse); if(handle==NULL || (!handle->inuse)) return ERR_INVALID_HANDLE; // FD_ZERO(&rdfds); FD_ZERO(&wrfds); FD_ZERO(&erfds); fdmax = 0; count = 0; while(1) { os_sleep(10); os_mutex_lock(&handle->list_mtx); item = (FDWATCH_ITEM*)rlist_front(&handle->enable_list); while(!rlist_is_head(&handle->enable_list, &item->item) && count<FD_SETSIZE) { if((item->flags&FDWATCH_DISABLE)==0) { pool[count++] = item; if(item->flags&FDWATCH_READ) { FD_SET(item->fd, &rdfds); FD_SET(item->fd, &erfds); } if(item->flags&FDWATCH_WRITE) FD_SET(item->fd, &wrfds); if(fdmax<item->fd) fdmax = item->fd; } item = (FDWATCH_ITEM*)rlist_next(&item->item); } os_mutex_unlock(&handle->list_mtx); if(count>0) break; if(timeout!=FDWATCH_INFINITE) { os_sleep(timeout); return ERR_NOERROR; } os_sleep(50); } for(;;) { if(timeout!=FDWATCH_INFINITE) { struct timeval tv; tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout%1000)*1000; ret = select(fdmax+1, &rdfds, &wrfds, &erfds, &tv); } else { ret = select(fdmax+1, &rdfds, &wrfds, &erfds, NULL); } if(ret>=0) break; if(WSAGetLastError()!=WSAEINTR) { // SYSLOG(LOG_ERROR, MODULE_NAME, "fdwatch_loop(SELECT): Failed to select(), errno=%d", errno); return ERR_UNKNOWN; } } for(;count>0; count--) { int events = 0; if(pool[count-1]->flags&FDWATCH_READ && (FD_ISSET(pool[count-1]->fd, &rdfds) || FD_ISSET(pool[count-1]->fd, &erfds))) { events |= FDWATCH_READ; } if(pool[count-1]->flags&FDWATCH_WRITE && FD_ISSET(pool[count-1]->fd, &wrfds)) { events |= FDWATCH_WRITE; } if(events!=0) { if(pool[count-1]->flags&FDWATCH_ONCE) pool[count-1]->flags |= FDWATCH_DISABLE; pool[count-1]->event(pool[count-1], events); } } return ERR_NOERROR; }