/** Starts and joins all threads performing a multi-threaded search, with or * without on-the-fly output, or performs a single-threaded search. */ static Int2 s_BlastThreadManager(BLAST_SequenceBlk* query, BlastQueryInfo* query_info, const BlastSeqSrc* seq_src, const SBlastOptions* options, LookupTableWrap* lookup_wrap, BlastScoreBlk* sbp, BlastHSPStream* hsp_stream, BlastRPSInfo* rps_info, BlastTabularFormatData* tf_data, BlastHSPResults **results, Blast_SummaryReturn* extra_returns) { Int2 status = 0; /* The options input cannot be NULL here. The program would have exited before entering this function if it was. */ const BlastInitialWordOptions* word_options = options->word_options; const BlastScoringOptions* score_options = options->score_options; const BlastExtensionOptions* ext_options = options->ext_options; const BlastHitSavingOptions* hit_options = options->hit_options; const BlastEffectiveLengthsOptions* eff_len_options = options->eff_len_options; const PSIBlastOptions* psi_options = options->psi_options; const BlastDatabaseOptions* db_options = options->db_options; TNlmThread format_thread = NULL; BlastDiagnostics* diagnostics = NULL; const EBlastProgramType kProgram = options->program; const int kNumCpus = options->num_cpus; /* Assert that all required inputs are not NULL. They must be - otherwise the program should have exited before entering this function. */ ASSERT(query && query_info && seq_src && lookup_wrap && sbp && hsp_stream && extra_returns); BlastSeqSrcResetChunkIterator((BlastSeqSrc*) seq_src); /* Start the formatting thread */ if(tf_data && NlmThreadsAvailable() && (format_thread = NlmThreadCreate(Blast_TabularFormatThread, (void*) tf_data)) == NULL_thread) { SBlastMessageWrite(&extra_returns->error, SEV_WARNING, "Cannot create thread for formatting tabular output\n", NULL, options->believe_query); return -1; } if (NlmThreadsAvailable() && kNumCpus > 1) { TNlmThread* thread_array = (TNlmThread*) calloc(kNumCpus, sizeof(TNlmThread)); BlastPrelimSearchThreadData* search_data = NULL; void* join_status = NULL; int index; diagnostics = Blast_DiagnosticsInitMT(Blast_MT_LOCKInit()); for (index = 0; index < kNumCpus; index++) { search_data = BlastPrelimSearchThreadDataInit(kProgram, query, query_info, seq_src, lookup_wrap, score_options, word_options, ext_options, hit_options, eff_len_options, psi_options, db_options, sbp, diagnostics, hsp_stream); thread_array[index] = NlmThreadCreate(Blast_PrelimSearchThreadRun, (void*) search_data); } for (index = 0; index < kNumCpus; index++) NlmThreadJoin(thread_array[index], &join_status); MemFree(thread_array); if (!tf_data) { SPHIPatternSearchBlk* pattern_blk = NULL; if (Blast_ProgramIsPhiBlast(kProgram)) { pattern_blk = (SPHIPatternSearchBlk*) lookup_wrap->lut; pattern_blk->num_patterns_db = (Int4)diagnostics->ungapped_stat->lookup_hits; } if ((status = Blast_RunTracebackSearch(kProgram, query, query_info, seq_src, score_options, ext_options, hit_options, eff_len_options, db_options, psi_options, sbp, hsp_stream, rps_info, pattern_blk, results)) != 0) { SBlastMessageWrite(&extra_returns->error, SEV_ERROR, "Traceback engine failed\n", NULL, options->believe_query); } } } else { diagnostics = Blast_DiagnosticsInit(); if (tf_data) { /* Single thread, tabular */ if ((status = Blast_RunPreliminarySearch(kProgram, query, query_info, seq_src, score_options, sbp, lookup_wrap, word_options, ext_options, hit_options, eff_len_options, psi_options, db_options, hsp_stream, diagnostics)) != 0) { SBlastMessageWrite(&extra_returns->error, SEV_ERROR, "Preliminary search engine failed\n", NULL, options->believe_query); } } else { /* Single thread, non-tabular */ if ((status=Blast_RunFullSearch(kProgram, query, query_info, seq_src, sbp, score_options, lookup_wrap, word_options, ext_options, hit_options, eff_len_options, psi_options, db_options, hsp_stream, rps_info, diagnostics, results, 0, 0)) != 0) { SBlastMessageWrite(&extra_returns->error, SEV_ERROR, "Blast_RunFullSearch failed\n", NULL, options->believe_query); } } } if (tf_data) { void* join_status = NULL; BlastHSPStreamClose(hsp_stream); NlmThreadJoin(format_thread, &join_status); /* Free the internally allocated structures used for tabular formatting. */ BlastTabularFormatDataClean(tf_data); } hsp_stream = BlastHSPStreamFree(hsp_stream); Blast_SummaryReturnFill(kProgram, score_options, sbp, options->lookup_options, word_options, ext_options, hit_options, eff_len_options, options->query_options, query_info, seq_src, &diagnostics, extra_returns); return status; }
static void Delete(BlastHSPStream* p) { BlastHSPStreamFree(p); }