usermode/library/mcore/src/log/logtrunc.c

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2011 Computer Sciences Department, 
00003     University of Wisconsin -- Madison
00004 
00005     ----------------------------------------------------------------------
00006 
00007     This file is part of Mnemosyne: Lightweight Persistent Memory, 
00008     originally developed at the University of Wisconsin -- Madison.
00009 
00010     Mnemosyne was originally developed primarily by Haris Volos
00011     with contributions from Andres Jaan Tack.
00012 
00013     ----------------------------------------------------------------------
00014 
00015     Mnemosyne is free software; you can redistribute it and/or
00016     modify it under the terms of the GNU General Public License
00017     as published by the Free Software Foundation, version 2
00018     of the License.
00019  
00020     Mnemosyne is distributed in the hope that it will be useful,
00021     but WITHOUT ANY WARRANTY; without even the implied warranty of
00022     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023     GNU General Public License for more details.
00024 
00025     You should have received a copy of the GNU General Public License
00026     along with this program; if not, write to the Free Software
00027     Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00028     Boston, MA  02110-1301, USA.
00029 
00030 ### END HEADER ###
00031 */
00032 
00039 #include <pthread.h>
00040 #include <sys/time.h>
00041 #include <stdio.h>
00042 #include <assert.h>
00043 #include <time.h>
00044 #include <sched.h>
00045 #include "log_i.h"
00046 #include "logtrunc.h"
00047 #include "hal/pcm_i.h"
00048 #include "phlog_tornbit.h"
00049 
00050 static m_logmgr_t *logmgr;
00051 
00052 static void *log_truncation_main (void *arg);
00053 
00054 m_result_t
00055 m_logtrunc_init(m_logmgr_t *mgr)
00056 {
00057         logmgr = mgr;
00058         pthread_cond_init(&(logmgr->logtrunc_cond), NULL);
00059         //FIXME: Don't create asynchronous trunc thread when doing synchronous truncations
00060         //FIXME: SYNC_TRUNCATION preprocessor flag is not passed here
00061 #if 1
00062         pthread_create (&(logmgr->logtrunc_thread), NULL, &log_truncation_main, (void *) 0);
00063 #endif
00064         return M_R_SUCCESS;
00065 }
00066 
00067 static 
00068 m_result_t
00069 truncate_logs (pcm_storeset_t *set, int lock)
00070 {
00071         m_log_dsc_t       *log_dsc;
00072         m_log_dsc_t       *log_dsc_to_truncate;
00073 
00074         if (lock) {
00075                 pthread_mutex_lock(&(logmgr->mutex));
00076         }       
00077 
00078         /* 
00079          * First prepare each log for truncation.
00080          * A log might then pass back a log truncation order number if it cares about 
00081          * the order the truncation is performed with respect to other logs.
00082          */
00083         list_for_each_entry(log_dsc, &(logmgr->active_logs_list), list) {
00084                 if (log_dsc->flags & LF_ASYNC_TRUNCATION) {
00085                         assert(log_dsc->ops);
00086                         assert(log_dsc->ops->truncation_init);
00087                         log_dsc->ops->truncation_init(set, log_dsc);
00088                 }
00089         }
00090         /* 
00091          * Find the next log to truncate, truncate it, update its truncation 
00092          * order, and repeat until there are no more logs to truncate.
00093          *
00094          * TODO: This process can be made more efficient.
00095          * TODO: This process should be performed per log type to allow coexistence 
00096          *       of logs of different types
00097          */
00098         do {
00099                 log_dsc_to_truncate = NULL; 
00100                 list_for_each_entry(log_dsc, &(logmgr->active_logs_list), list) {
00101                         if (!(log_dsc->flags & LF_ASYNC_TRUNCATION)) {
00102                                 continue;
00103                         }
00104                         if (log_dsc->logorder == INV_LOG_ORDER) {
00105                                 continue;
00106                         }
00107                         if (log_dsc_to_truncate == NULL) {
00108                                 log_dsc_to_truncate = log_dsc;
00109                         } else {
00110                                 if (log_dsc_to_truncate->logorder > log_dsc->logorder) {
00111                                         log_dsc_to_truncate = log_dsc;
00112                                 }
00113                         }
00114                 }
00115                 if (log_dsc_to_truncate) {
00116                         assert(log_dsc_to_truncate->ops);
00117                         assert(log_dsc_to_truncate->ops->truncation_do);
00118                         assert(log_dsc_to_truncate->ops->truncation_prepare_next);
00119                         log_dsc_to_truncate->ops->truncation_do(set, log_dsc_to_truncate);
00120                         log_dsc_to_truncate->ops->truncation_prepare_next(set, log_dsc_to_truncate);
00121                 }       
00122         } while(log_dsc_to_truncate);
00123 
00124         if (lock) {
00125                 pthread_mutex_unlock(&(logmgr->mutex));
00126         }       
00127 
00128         return M_R_SUCCESS;
00129 }
00130 
00131 
00136 static
00137 void *
00138 log_truncation_main (void *arg)
00139 {
00140         struct timeval     start_time;
00141         struct timeval     stop_time;
00142         struct timeval     tp;
00143         struct timespec    ts;
00144         pcm_storeset_t     *set;
00145         unsigned long long measured_time;
00146 
00147         set = pcm_storeset_get();
00148 
00149         cpu_set_t          cpu_set;
00150 
00151         CPU_ZERO(&cpu_set);
00152         CPU_SET(1 % 4, &cpu_set);
00153         sched_setaffinity(0, 4, &cpu_set);
00154 
00155 
00156 /*
00157  * In the past, we tried to periodically wake-up and truncate the logs
00158  * but for the workloads we tried this didn't work well. Instead, we
00159  * now continuously loop and check for logs to truncate 
00160  */
00161 
00162         /* reset trunc statistics */
00163         logmgr->trunc_count=0;                                                                   
00164         logmgr->trunc_time = 0;                                                                  
00165 #if 1
00166         pthread_mutex_lock(&(logmgr->mutex));
00167 
00168         while (1) {
00169                 gettimeofday(&tp, NULL);
00170                 ts.tv_sec = tp.tv_sec;
00171                 ts.tv_nsec = tp.tv_usec * 1000; 
00172                 ts.tv_sec += 10; // sleep time 
00173                 pthread_cond_timedwait(&logmgr->logtrunc_cond, &logmgr->mutex, &ts);
00174                 //pthread_mutex_unlock(&(logmgr->mutex));
00175                 //pthread_mutex_lock(&(logmgr->mutex));
00176 
00177                 gettimeofday(&start_time, NULL);
00178                 truncate_logs(set, 0);
00179                 gettimeofday(&stop_time, NULL);
00180                 measured_time = 1000000 * (stop_time.tv_sec - start_time.tv_sec) +
00181                                                      stop_time.tv_usec - start_time.tv_usec;
00182                 logmgr->trunc_count++;                                                                   
00183                 logmgr->trunc_time += measured_time;                                                                     
00184         }       
00185 
00186         pthread_mutex_unlock(&(logmgr->mutex));
00187 #endif
00188 
00189 #if 0
00190         while (1) {
00191                 pthread_mutex_lock(&(logmgr->mutex));
00192                 truncate_logs(set, 0);
00193                 pthread_mutex_unlock(&(logmgr->mutex));
00194         }       
00195 #endif
00196 
00197         return 0;
00198 }
00199 
00200 
00204 m_result_t
00205 m_logtrunc_truncate(pcm_storeset_t *set)
00206 {
00207         assert(0 && "m_logtrunc_truncate no longer used");
00208         //return truncate_logs(set, 1);
00209 }
00210 
00211 
00212 m_result_t
00213 m_logtrunc_signal()
00214 {
00215         // We don't worry about lost signals, as if the signal is lost, then 
00216         // the async trunc thread was already truncating the log 
00217         pthread_cond_signal(&logmgr->logtrunc_cond);
00218 }

Generated on Sat Apr 23 11:43:35 2011 for Mnemosyne by  doxygen 1.4.7