void send_stats_from_thread(struct stats stats) { unsigned int sock_len; struct sockaddr_un ipc_socket; int s; // Create the socket to send the details back on s = socket( AF_UNIX, SOCK_DGRAM, 0); if ( s == INVALID_SOCKET ) { fprintf(stderr, "%s:%d socket() error (%d) %s\n", __FILE__, __LINE__, ERRNO, strerror(ERRNO) ); return; } if ( set_socket_timeout(s, IPC_TIMEOUT) ) { fprintf(stderr, "%s:%d set_socket_timeout() error (%d) %s\n", __FILE__, __LINE__, ERRNO, strerror(ERRNO) ); goto cleanup; } ipc_socket.sun_family = AF_UNIX; //strcpy(ipc_socket.sun_path, IPC_SOCK_NAME); sprintf(ipc_socket.sun_path , "%s", ipc_sock_name); sock_len = strlen(ipc_socket.sun_path) + sizeof(ipc_socket.sun_family); // Bind the IPC SOCKET if ( connect( s,(struct sockaddr *) &ipc_socket, sock_len) == SOCKET_ERROR) { fprintf(stderr, "%s:%d connect() error (%d) %s\n", __FILE__, __LINE__, ERRNO, strerror(ERRNO)); goto cleanup; } if ( send_results(s, &stats) ) { fprintf(stderr, "%s:%d send_results() error (%d) %s\n", __FILE__, __LINE__, ERRNO, strerror(ERRNO) ); goto cleanup; } cleanup: closesocket(s); }
static void process_SearchCmd(HMMD_COMMAND *cmd, WORKER_ENV *env) { int i; int cnt; int limit; int status; int blk_size; WORKER_INFO *info = NULL; ESL_ALPHABET *abc; ESL_STOPWATCH *w; ESL_THREADS *threadObj = NULL; pthread_mutex_t inx_mutex; int current_index; QUEUE_DATA *query = NULL; time_t date; char timestamp[32]; w = esl_stopwatch_Create(); abc = esl_alphabet_Create(eslAMINO); if (pthread_mutex_init(&inx_mutex, NULL) != 0) p7_Fail("mutex init failed"); ESL_ALLOC(info, sizeof(*info) * env->ncpus); /* Log the current time (at search start) */ date = time(NULL); ctime_r(&date, timestamp); printf("\n%s", timestamp); /* note that ctime_r() leaves \n on end of timestamp */ /* initialize thread data */ query = process_QueryCmd(cmd, env); esl_stopwatch_Start(w); info->range_list = NULL; if (esl_opt_IsUsed(query->opts, "--seqdb_ranges")) { ESL_ALLOC(info->range_list, sizeof(RANGE_LIST)); hmmpgmd_GetRanges(info->range_list, esl_opt_GetString(query->opts, "--seqdb_ranges")); } if (query->cmd_type == HMMD_CMD_SEARCH) threadObj = esl_threads_Create(&search_thread); else threadObj = esl_threads_Create(&scan_thread); if (query->query_type == HMMD_SEQUENCE) { fprintf(stdout, "Search seq %s [L=%ld]", query->seq->name, (long) query->seq->n); } else { fprintf(stdout, "Search hmm %s [M=%d]", query->hmm->name, query->hmm->M); } fprintf(stdout, " vs %s DB %d [%d - %d]", (query->cmd_type == HMMD_CMD_SEARCH) ? "SEQ" : "HMM", query->dbx, query->inx, query->inx + query->cnt - 1); if (info->range_list) fprintf(stdout, " in range(s) %s", esl_opt_GetString(query->opts, "--seqdb_ranges")); fprintf(stdout, "\n"); /* Create processing pipeline and hit list */ for (i = 0; i < env->ncpus; ++i) { info[i].abc = query->abc; info[i].hmm = query->hmm; info[i].seq = query->seq; info[i].opts = query->opts; info[i].range_list = info[0].range_list; info[i].th = NULL; info[i].pli = NULL; info[i].inx_mutex = &inx_mutex; info[i].inx = ¤t_index;/* this is confusing trickery - to share a single variable across all threads */ info[i].blk_size = &blk_size; /* ditto */ info[i].limit = &limit; /* ditto. TODO: come back and clean this up. */ if (query->cmd_type == HMMD_CMD_SEARCH) { HMMER_SEQ **list = env->seq_db->db[query->dbx].list; info[i].sq_list = &list[query->inx]; info[i].sq_cnt = query->cnt; info[i].db_Z = env->seq_db->db[query->dbx].K; info[i].om_list = NULL; info[i].om_cnt = 0; } else { info[i].sq_list = NULL; info[i].sq_cnt = 0; info[i].db_Z = 0; info[i].om_list = &env->hmm_db->list[query->inx]; info[i].om_cnt = query->cnt; } esl_threads_AddThread(threadObj, &info[i]); } /* try block size of 5000. we will need enough sequences for four * blocks per thread or better. */ blk_size = 5000; cnt = query->cnt / env->ncpus / blk_size; limit = query->cnt * 2 / 3; if (cnt < 4) { /* try block size of 1000 */ blk_size /= 5; cnt = query->cnt / env->ncpus / blk_size; if (cnt < 4) { /* still not enough. just divide it up into one block per thread */ blk_size = query->cnt / env->ncpus + 1; limit = query->cnt * 2; } } current_index = 0; esl_threads_WaitForStart(threadObj); esl_threads_WaitForFinish(threadObj); esl_stopwatch_Stop(w); #if 1 fprintf (stdout, " Sequences Residues Elapsed\n"); for (i = 0; i < env->ncpus; ++i) { print_timings(i, info[i].elapsed, info[i].pli); } #endif /* merge the results of the search results */ for (i = 1; i < env->ncpus; ++i) { p7_tophits_Merge(info[0].th, info[i].th); p7_pipeline_Merge(info[0].pli, info[i].pli); p7_pipeline_Destroy(info[i].pli); p7_tophits_Destroy(info[i].th); } print_timings(99, w->elapsed, info[0].pli); send_results(env->fd, w, info); /* free the last of the pipeline data */ p7_pipeline_Destroy(info->pli); p7_tophits_Destroy(info->th); free_QueueData(query); esl_threads_Destroy(threadObj); pthread_mutex_destroy(&inx_mutex); if (info->range_list) { if (info->range_list->starts) free(info->range_list->starts); if (info->range_list->ends) free(info->range_list->ends); free (info->range_list); } free(info); esl_stopwatch_Destroy(w); esl_alphabet_Destroy(abc); return; ERROR: LOG_FATAL_MSG("malloc", errno); }
/* aux message to worker thread to a message */ static int pull_message(int thrn, void *pullskt, void *resultskt){ uint8_t cmd, perms = 0, threadnum, table_n, **toggles = NULL; uint32_t nbframes, id = 0; void *hash = NULL, *data = NULL; int i, err; int64_t more; size_t msg_size, more_size = sizeof(int64_t); float cs = -1.0f; /* pull cmd msg part */ recieve_msg(pullskt, &msg_size, &more, &more_size, &data); if (msg_size != sizeof(uint8_t) || !more){ if (more) flushall_msg_parts(pullskt); free(data); return -1; } memcpy(&cmd, data, sizeof(uint8_t)); free(data); /* pull nbframes msg part */ recieve_msg(pullskt, &msg_size, &more, &more_size, &data); if (msg_size != sizeof(uint32_t) || !more){ if (more) flushall_msg_parts(pullskt); free(data); return -2; } memcpy(&nbframes, data, sizeof(uint32_t)); nbframes = nettohost32(nbframes); free(data); /* pull hash msg part */ recieve_msg(pullskt, &msg_size, &more, &more_size, &hash); if (msg_size != nbframes*sizeof(uint32_t) || !more){ syslog(LOG_DEBUG,"WORKER%d: inconsistent hash msg part size = %d", thrn, msg_size); if (more) flushall_msg_parts(pullskt); free(hash); return -3; } /* recieve threadnum (for cmd== 1) or table_num (for cmd == 2)*/ recieve_msg(pullskt, &msg_size, &more, &more_size, (void**)&data); if (msg_size != sizeof(uint8_t) || !more){ syslog(LOG_DEBUG,"WORKER%d: inconsistent threadnum msg size, %d", thrn, msg_size); if (more) flushall_msg_parts(pullskt); free(data); free(hash); return -4; } memcpy(&threadnum, data, sizeof(uint8_t)); free(data); recieve_msg(pullskt, &msg_size, &more, &more_size, &data); if (msg_size != sizeof(uint32_t)){ syslog(LOG_DEBUG,"WORKER%d: inconsistent uid msg size = %d", thrn, msg_size); free(data); free(hash); return -5; } memcpy(&id, data, sizeof(uint32_t)); id = nettohost32(id); free(data); /* de-serialization */ for (i=0;i<nbframes;i++){ ((uint32_t*)hash)[i] = nettohost32(((uint32_t*)hash)[i]); } if (more){ toggles = retrieve_extra(pullskt, nbframes, &perms); } err = execute_command(thrn, cmd, hash, toggles, perms,nbframes, threadnum, &id, &cs); if (err < 0){ syslog(LOG_DEBUG,"WORKER%d: unable to execute command, err=%d", err); } if (toggles) { for (i = 0;i<nbframes;i++){ free(toggles[i]); } free(toggles); toggles = NULL; } free(hash); hash = NULL; if (cs >= GlobalArgs.threshold){ syslog(LOG_DEBUG,"WORKER%d: %u threadnum, %f cs, %u id", thrn, threadnum, cs, id); id = hosttonet32(id); cs = hosttonetf(cs); send_results(resultskt, threadnum, id, cs); } return 0; }