static void test_query_filter(TestCase *tc, void *data) { Searcher *searcher = (Searcher *)data; Query *bq; Filter *qf; Query *q = maq_new(); qf = qfilt_new_nr(tq_new(flipflop, "on")); TEST_TO_S("QueryFilter< flipflop:on >", qf); check_filtered_hits(tc, searcher, q, qf, NULL, "0,2,4,6,8", -1); filt_deref(qf); bq = bq_new(false); bq_add_query_nr(bq, tq_new(date, "20051101"), BC_SHOULD); bq_add_query_nr(bq, tq_new(date, "20041201"), BC_SHOULD); qf = qfilt_new_nr(bq); check_filtered_hits(tc, searcher, q, qf, NULL, "2,3,4,5", -1); TEST_TO_S("QueryFilter< date:20051101 date:20041201 >", qf); filt_deref(qf); q_deref(q); }
static void test_query_filter_hash(TestCase *tc, void *data) { Filter *f1, *f2; (void)data; f1 = qfilt_new_nr(tq_new(I("A"), "a")); f2 = qfilt_new_nr(tq_new(I("A"), "a")); Aiequal(filt_hash(f1), filt_hash(f2)); Assert(filt_eq(f1, f2), "Queries are equal"); Assert(filt_eq(f1, f1), "Queries are equal"); filt_deref(f2); f2 = qfilt_new_nr(tq_new(I("A"), "b")); Assert(filt_hash(f1) != filt_hash(f2), "texts differ"); Assert(!filt_eq(f1, f2), "texts differ"); filt_deref(f2); f2 = qfilt_new_nr(tq_new(I("B"), "a")); Assert(filt_hash(f1) != filt_hash(f2), "fields differ"); Assert(!filt_eq(f1, f2), "fields differ"); filt_deref(f2); filt_deref(f1); }
static INLINE void index_del_doc_with_key_i(Index *self, Document *doc, HashSet *key) { Query *q; TopDocs *td; DocField *df; HashSetEntry *hse; if (key->size == 1) { Symbol field = (Symbol)key->first->elem; ensure_writer_open(self); df = doc_get_field(doc, field); if (df) { iw_delete_term(self->iw, field, df->data[0]); } return; } q = bq_new(false); ensure_searcher_open(self); for (hse = key->first; hse; hse = hse->next) { Symbol field = (Symbol)hse->elem; df = doc_get_field(doc, field); if (!df) continue; bq_add_query(q, tq_new(field, df->data[0]), BC_MUST); } td = searcher_search(self->sea, q, 0, 1, NULL, NULL, NULL); if (td->total_hits > 1) { td_destroy(td); RAISE(ARG_ERROR, NON_UNIQUE_KEY_ERROR_MSG); } else if (td->total_hits == 1) { ir_delete_doc(self->ir, td->hits[0]->doc); } q_deref(q); td_destroy(td); }
/* We have only one thread that ever re-initialises GPUs, thus if any GPU * init command fails due to a completely wedged GPU, the thread will never * return, unable to harm other GPUs. If it does return, it means we only had * a soft failure and then the reinit_gpu thread is ready to tackle another * GPU */ void *reinit_gpu(void *userdata) { struct thr_info *mythr = userdata; struct cgpu_info *cgpu; struct thr_info *thr; struct timeval now; char name[256]; int thr_id; int gpu; pthread_detach(pthread_self()); select_cgpu: cgpu = tq_pop(mythr->q, NULL); if (!cgpu) goto out; if (clDevicesNum() != nDevs) { applog(LOG_WARNING, "Hardware not reporting same number of active devices, will not attempt to restart GPU"); goto out; } gpu = cgpu->device_id; for (thr_id = 0; thr_id < mining_threads; ++thr_id) { thr = &thr_info[thr_id]; cgpu = thr->cgpu; if (cgpu->api != &opencl_api) continue; if (dev_from_id(thr_id) != gpu) continue; thr = &thr_info[thr_id]; if (!thr) { applog(LOG_WARNING, "No reference to thread %d exists", thr_id); continue; } thr->rolling = thr->cgpu->rolling = 0; /* Reports the last time we tried to revive a sick GPU */ gettimeofday(&thr->sick, NULL); if (!pthread_cancel(thr->pth)) { applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id); } else applog(LOG_WARNING, "Thread %d no longer exists", thr_id); } for (thr_id = 0; thr_id < mining_threads; ++thr_id) { int virtual_gpu; thr = &thr_info[thr_id]; cgpu = thr->cgpu; if (cgpu->api != &opencl_api) continue; if (dev_from_id(thr_id) != gpu) continue; virtual_gpu = cgpu->virtual_gpu; /* Lose this ram cause we may get stuck here! */ //tq_freeze(thr->q); thr->q = tq_new(); if (!thr->q) quit(1, "Failed to tq_new in reinit_gpu"); /* Lose this ram cause we may dereference in the dying thread! */ //free(clState); applog(LOG_INFO, "Reinit GPU thread %d", thr_id); clStates[thr_id] = initCl(virtual_gpu, name, sizeof(name)); if (!clStates[thr_id]) { applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id); goto select_cgpu; } applog(LOG_INFO, "initCl() finished. Found %s", name); if (unlikely(thr_info_create(thr, NULL, miner_thread, thr))) { applog(LOG_ERR, "thread %d create failed", thr_id); return NULL; } applog(LOG_WARNING, "Thread %d restarted", thr_id); } gettimeofday(&now, NULL); get_datestamp(cgpu->init, &now); for (thr_id = 0; thr_id < mining_threads; ++thr_id) { thr = &thr_info[thr_id]; cgpu = thr->cgpu; if (cgpu->api != &opencl_api) continue; if (dev_from_id(thr_id) != gpu) continue; tq_push(thr->q, &ping); } goto select_cgpu; out: return NULL; }
/* We have only one thread that ever re-initialises GPUs, thus if any GPU * init command fails due to a completely wedged GPU, the thread will never * return, unable to harm other GPUs. If it does return, it means we only had * a soft failure and then the reinit_gpu thread is ready to tackle another * GPU */ void *reinit_gpu(void *userdata) { struct thr_info *mythr = (struct thr_info *)userdata; struct cgpu_info *cgpu; struct thr_info *thr; struct timeval now; char name[256]; int thr_id; int gpu; pthread_detach(pthread_self()); select_cgpu: cgpu = (struct cgpu_info *)tq_pop(mythr->q, NULL); if (!cgpu) goto out; if (clDevicesNum() != nDevs) { applog(LOG_WARNING, "Hardware not reporting same number of active devices, will not attempt to restart GPU"); goto out; } gpu = cgpu->device_id; rd_lock(&mining_thr_lock); for (thr_id = 0; thr_id < mining_threads; ++thr_id) { thr = mining_thr[thr_id]; cgpu = thr->cgpu; if (cgpu->drv->drv_id != DRIVER_opencl) continue; if (dev_from_id(thr_id) != gpu) continue; thr->rolling = thr->cgpu->rolling = 0; /* Reports the last time we tried to revive a sick GPU */ cgtime(&thr->sick); if (!pthread_kill(thr->pth, 0)) { applog(LOG_WARNING, "Thread %d still exists, killing it off", thr_id); cg_completion_timeout(&thr_info_cancel_join, thr, 5000); thr->cgpu->drv->thread_shutdown(thr); } else applog(LOG_WARNING, "Thread %d no longer exists", thr_id); } rd_unlock(&mining_thr_lock); rd_lock(&mining_thr_lock); for (thr_id = 0; thr_id < mining_threads; ++thr_id) { int virtual_gpu; thr = mining_thr[thr_id]; cgpu = thr->cgpu; if (cgpu->drv->drv_id != DRIVER_opencl) continue; if (dev_from_id(thr_id) != gpu) continue; virtual_gpu = cgpu->virtual_gpu; /* Lose this ram cause we may get stuck here! */ //tq_freeze(thr->q); thr->q = tq_new(); if (!thr->q) quit(1, "Failed to tq_new in reinit_gpu"); /* Lose this ram cause we may dereference in the dying thread! */ //free(clState); applog(LOG_INFO, "Reinit GPU thread %d", thr_id); clStates[thr_id] = initCl(virtual_gpu, name, sizeof(name), &cgpu->algorithm); if (!clStates[thr_id]) { applog(LOG_ERR, "Failed to reinit GPU thread %d", thr_id); goto select_cgpu; } applog(LOG_INFO, "initCl() finished. Found %s", name); if (unlikely(thr_info_create(thr, NULL, miner_thread, thr))) { applog(LOG_ERR, "thread %d create failed", thr_id); return NULL; } applog(LOG_WARNING, "Thread %d restarted", thr_id); } rd_unlock(&mining_thr_lock); cgtime(&now); get_datestamp(cgpu->init, sizeof(cgpu->init), &now); rd_lock(&mining_thr_lock); for (thr_id = 0; thr_id < mining_threads; ++thr_id) { thr = mining_thr[thr_id]; cgpu = thr->cgpu; if (cgpu->drv->drv_id != DRIVER_opencl) continue; if (dev_from_id(thr_id) != gpu) continue; cgsem_post(&thr->sem); } rd_unlock(&mining_thr_lock); goto select_cgpu; out: return NULL; }
static void test_sorts(TestCase *tc, void *data) { Searcher *sea = (Searcher *)data; Query *q; Sort *sort = NULL; q = tq_new(search, "findall"); do_test_top_docs(tc, sea, q, "8,7,5,3,1,0,2,4,6,9", NULL); sort = sort_new(); sort_add_sort_field(sort, sort_field_score_new(false)); do_test_top_docs(tc, sea, q, "8,7,5,3,1,0,2,4,6,9", sort); sort->sort_fields[0]->reverse = true; do_test_top_docs(tc, sea, q, "9,6,4,2,0,1,3,5,7,8", sort); sort_clear(sort); sort_add_sort_field(sort, sort_field_doc_new(false)); do_test_top_docs(tc, sea, q, "0,1,2,3,4,5,6,7,8,9", sort); sort->sort_fields[0]->reverse = true; do_test_top_docs(tc, sea, q, "9,8,7,6,5,4,3,2,1,0", sort); sort_clear(sort); sort_add_sort_field(sort, sort_field_int_new(integer, true)); do_test_top_docs(tc, sea, q, "0,1,6,5,9,4,8,2,7,3", sort); sort_add_sort_field(sort, sort_field_score_new(false)); do_test_top_docs(tc, sea, q, "0,1,6,5,9,8,4,7,2,3", sort); sort->size = 1; /* remove score sort_field */ sort->sort_fields[0]->reverse = false; do_test_top_docs(tc, sea, q, "3,2,7,4,8,5,9,1,6,0", sort); sort->size = 2; /* re-add score sort_field */ do_test_top_docs(tc, sea, q, "3,7,2,8,4,5,9,1,6,0", sort); sort_clear(sort); if (do_byte_test) { sort_add_sort_field(sort, sort_field_byte_new(integer, true)); do_test_top_docs(tc, sea, q, "0,1,6,5,9,4,8,2,7,3", sort); sort_add_sort_field(sort, sort_field_score_new(false)); do_test_top_docs(tc, sea, q, "0,1,6,5,9,8,4,7,2,3", sort); sort->size = 1; /* remove score sort_field */ sort->sort_fields[0]->reverse = false; do_test_top_docs(tc, sea, q, "3,2,7,4,8,5,9,1,6,0", sort); sort->size = 2; /* re-add score sort_field */ do_test_top_docs(tc, sea, q, "3,7,2,8,4,5,9,1,6,0", sort); sort_clear(sort); } sort_add_sort_field(sort, sort_field_float_new(flt, false)); do_test_top_docs(tc, sea, q, "9,6,4,2,0,1,3,5,7,8", sort); sort->sort_fields[0]->reverse = true; do_test_top_docs(tc, sea, q, "8,7,5,3,1,0,2,4,6,9", sort); sort_clear(sort); sort_add_sort_field(sort, sort_field_string_new(string, false)); do_test_top_docs(tc, sea, q, "0,9,1,8,2,7,3,6,4,5", sort); sort->sort_fields[0]->reverse = true; do_test_top_docs(tc, sea, q, "5,4,6,3,7,2,8,1,9,0", sort); sort_clear(sort); if (do_byte_test) { sort_add_sort_field(sort, sort_field_byte_new(string, false)); do_test_top_docs(tc, sea, q, "5,0,9,1,8,2,7,3,6,4", sort); sort->sort_fields[0]->reverse = true; do_test_top_docs(tc, sea, q, "4,6,3,7,2,8,1,9,0,5", sort); sort_clear(sort); } /* Test Auto Sort */ sort_add_sort_field(sort, sort_field_auto_new(string, false)); do_test_top_docs(tc, sea, q, "0,9,1,8,2,7,3,6,4,5", sort); sort_clear(sort); sort_add_sort_field(sort, sort_field_auto_new(integer, false)); do_test_top_docs(tc, sea, q, "3,2,7,4,8,5,9,1,6,0", sort); sort_clear(sort); sort_add_sort_field(sort, sort_field_auto_new(flt, false)); do_test_top_docs(tc, sea, q, "9,6,4,2,0,1,3,5,7,8", sort); sort->sort_fields[0]->reverse = true; do_test_top_docs(tc, sea, q, "8,7,5,3,1,0,2,4,6,9", sort); sort_clear(sort); sort_add_sort_field(sort, sort_field_auto_new(integer, false)); sort_add_sort_field(sort, sort_field_auto_new(string, false)); do_test_top_docs(tc, sea, q, "3,2,7,8,4,9,5,1,6,0", sort); sort_destroy(sort); q_deref(q); }
int main (int argc, char *argv[]) { struct thr_info *thr; int i; rpc_url = strdup(DEF_RPC_URL); /* parse command line */ parse_cmdline(argc, argv); if (!rpc_userpass) { if (!rpc_user || !rpc_pass) { applog(LOG_ERR, "No login credentials supplied"); return 1; } rpc_userpass = malloc(strlen(rpc_user) + strlen(rpc_pass) + 2); if (!rpc_userpass) return 1; sprintf(rpc_userpass, "%s:%s", rpc_user, rpc_pass); } pthread_mutex_init(&time_lock, NULL); #ifdef HAVE_SYSLOG_H if (use_syslog) openlog("cpuminer", LOG_PID, LOG_USER); #endif work_restart = calloc(opt_n_threads, sizeof(*work_restart)); if (!work_restart) return 1; thr_info = calloc(opt_n_threads + 2, sizeof(*thr)); if (!thr_info) return 1; /* init workio thread info */ work_thr_id = opt_n_threads; thr = &thr_info[work_thr_id]; thr->id = work_thr_id; thr->q = tq_new(); if (!thr->q) return 1; /* start work I/O thread */ if (pthread_create(&thr->pth, NULL, workio_thread, thr)) { applog(LOG_ERR, "workio thread create failed"); return 1; } /* init longpoll thread info */ if (want_longpoll) { longpoll_thr_id = opt_n_threads + 1; thr = &thr_info[longpoll_thr_id]; thr->id = longpoll_thr_id; thr->q = tq_new(); if (!thr->q) return 1; /* start longpoll thread */ if (unlikely(pthread_create(&thr->pth, NULL, longpoll_thread, thr))) { applog(LOG_ERR, "longpoll thread create failed"); return 1; } } else longpoll_thr_id = -1; /* start mining threads */ for (i = 0; i < opt_n_threads; i++) { thr = &thr_info[i]; thr->id = i; thr->q = tq_new(); if (!thr->q) return 1; if (unlikely(pthread_create(&thr->pth, NULL, miner_thread, thr))) { applog(LOG_ERR, "thread %d create failed", i); return 1; } sleep(1); /* don't pound RPC server all at once */ } applog(LOG_INFO, "%d miner threads started, " "using Momentum Proof-of-Work algorithm.", opt_n_threads); /* main loop - simply wait for workio thread to exit */ pthread_join(thr_info[work_thr_id].pth, NULL); applog(LOG_INFO, "workio thread dead, exiting."); return 0; }