MASA-Core
AbstractAlignerSafe.cpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2010-2015   Edans Sandes
00004  *
00005  * This file is part of MASA-Core.
00006  * 
00007  * MASA-Core is free software: you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation, either version 3 of the License, or
00010  * (at your option) any later version.
00011  * 
00012  * MASA-Core is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with MASA-Core.  If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  ******************************************************************************/
00021 
00022 #include "AbstractAlignerSafe.hpp"
00023 
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 
00027 AbstractAlignerSafe::AbstractAlignerSafe() {
00028     pthread_mutex_init(&mutex, NULL);
00029     dispatcherQueueActive = false;
00030 
00031 }
00032 
00033 AbstractAlignerSafe::~AbstractAlignerSafe() {
00034         destroyDispatcherQueue();
00035 }
00036 
00037 void AbstractAlignerSafe::dispatchColumn(int j, const cell_t* buffer, int len) {
00038         pthread_mutex_lock(&mutex);
00039         AbstractAligner::dispatchColumn(j, buffer, len);
00040         pthread_mutex_unlock(&mutex);
00041 }
00042 
00043 void AbstractAlignerSafe::dispatchRow(int i, const cell_t* buffer, int len) {
00044         pthread_mutex_lock(&mutex);
00045         AbstractAligner::dispatchRow(i, buffer, len);
00046         pthread_mutex_unlock(&mutex);
00047 }
00048 
00049 void AbstractAlignerSafe::dispatchScore(score_t score, int bx, int by) {
00050         pthread_mutex_lock(&mutex);
00051         if (dispatcherQueueActive) {
00052                 dispatch_job_t job;
00053                 job.type = dispatch_job_t::JOB_SCORE;
00054                 dispatch_job_t::dispatch_params_t::params_score_t params;
00055                 params.score = score;
00056                 params.bx = bx;
00057                 params.by = by;
00058                 job.dispatch_params.params_score = params;
00059                 dispatcherQueue.push(job);
00060                 pthread_cond_signal(&condition);
00061         } else {
00062                 AbstractAligner::dispatchScore(score, bx, by);
00063         }
00064         printf ("%p: DispatchScore(%d,%d,%d): %d %d\n", pthread_self(), score.score, score.i, score.j, dispatcherQueueActive, dispatcherQueue.size());
00065         pthread_mutex_unlock(&mutex);
00066 }
00067 
00068 
00069 
00070 void AbstractAlignerSafe::createDispatcherQueue() {
00071         if (dispatcherQueueActive) {
00072                 return;
00073         }
00074         dispatcherQueueActive = true;
00075     pthread_cond_init(&condition, NULL);
00076     int rc = pthread_create(&thread, NULL, staticFunctionThread, (void *)this);
00077     if (rc){
00078         fprintf(stderr, "setLogFile ERROR; return code from pthread_create() is %d\n", rc);
00079         exit(-1);
00080     }
00081 }
00082 
00083 void AbstractAlignerSafe::destroyDispatcherQueue() {
00084         if (!dispatcherQueueActive) {
00085                 return;
00086         }
00087 
00088         pthread_mutex_lock(&mutex);
00089         this->dispatcherQueueActive = false;
00090         pthread_cond_signal(&condition);
00091     pthread_mutex_unlock(&mutex);
00092 
00093     pthread_join(thread, NULL);
00094 }
00095 
00096 void *AbstractAlignerSafe::staticFunctionThread(void *arg) {
00097         AbstractAlignerSafe* obj = (AbstractAlignerSafe*)arg;
00098         obj->executeLoop();
00099     return NULL;
00100 }
00101 
00102 void AbstractAlignerSafe::executeLoop() {
00103         bool done = false;
00104         dispatch_job_t job;
00105         if (!dispatcherQueueActive) {
00106                 done = true;
00107         }
00108         while (!done) {
00109             pthread_mutex_lock(&mutex);
00110         while (dispatcherQueueActive && dispatcherQueue.size() == 0) {
00111                 printf ("%p: Before Cond Wait %d %d\n", pthread_self(), dispatcherQueueActive, dispatcherQueue.size());
00112                 pthread_cond_wait(&condition, &mutex);
00113         }
00114         printf ("%p: After Cond Wait %d %d\n", pthread_self(), dispatcherQueueActive, dispatcherQueue.size());
00115         if (!dispatcherQueueActive && dispatcherQueue.size() == 0) {
00116                 done = true;
00117         } else {
00118                 job = dispatcherQueue.front();
00119                 printf ("%p: Before queue::pop() %d\n", pthread_self(), dispatcherQueue.size());
00120                 dispatcherQueue.pop();
00121                 printf ("%p: After queue::pop() %d\n", pthread_self(), dispatcherQueue.size());
00122         }
00123         //pthread_cond_signal(&condition);
00124             pthread_mutex_unlock(&mutex);
00125 
00126             if (!done) {
00127                         if (job.type == dispatch_job_t::JOB_SCORE) {
00128                                 dispatch_job_t::dispatch_params_t::params_score_t params;
00129                                 params = job.dispatch_params.params_score;
00130                                 AbstractAligner::dispatchScore(params.score, params.bx, params.by);
00131                                 printf ("%p: AbstractAligner::dispatchScore() %d\n", pthread_self(), dispatcherQueue.size());
00132                         }
00133             }
00134         }
00135 }
00136