usermode/library/mcore/src/log/log_i.h

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 #ifndef _LOG_INTERNAL_H
00040 #define _LOG_INTERNAL_H
00041 
00042 #include <stdio.h>
00043 #include <pthread.h>
00044 #include <stdint.h>
00045 #include <result.h>
00046 #include <list.h>
00047 #include "hrtime.h"
00048 #include "../hal/pcm_i.h"
00049 
00050 #ifdef __cplusplus
00051 extern "C" {
00052 #endif
00053 
00054 
00055 /* 
00056  * Physical log size is power of 2 to implement arithmetic efficiently 
00057  * e.g. modulo using bitwise operations: x % 2^n == x & (2^n - 1) 
00058  */
00059 #define PHYSICAL_LOG_NUM_ENTRIES_LOG2 20
00060 #define PHYSICAL_LOG_NUM_ENTRIES      (1 << PHYSICAL_LOG_NUM_ENTRIES_LOG2)
00061 #define PHYSICAL_LOG_SIZE             (PHYSICAL_LOG_NUM_ENTRIES * sizeof(pcm_word_t)) /* in bytes */
00062 
00063 
00064 /* Masks for the 64-bit non-volatile generic_flags field. */
00065 
00066 #define LF_FLAGS_MASK     0xFFFFFFFFFFFF0000LLU      /* generic flags mask */
00067 #define LF_TYPE_MASK      0x000000000000FFFFLLU      /* log type mask */
00068 
00069 /* Generic non-volatile flags */
00070 #define LF_DIRTY          0x8000000000000000
00071 
00072 /* Log truncation and recovery */
00073 #define INV_LOG_ORDER     0xFFFFFFFFFFFFFFFF
00074 
00075 /* Volatile flags */
00076 #define LF_ASYNC_TRUNCATION 0x0000000000000001
00077 
00078 /* Hardwired log types known at compilation time (static) */
00079 enum {
00080         LF_TYPE_FREE  = 0,
00081         LF_TYPE_VALIDVALUES
00082 };
00083 
00084 
00085 typedef struct m_logmgr_s     m_logmgr_t;
00086 typedef struct m_log_s        m_log_t;
00087 typedef struct m_log_ops_s    m_log_ops_t;
00088 typedef struct m_log_dsc_s    m_log_dsc_t;
00089 typedef struct m_log_nvmd_s   m_log_nvmd_t;
00090 
00091 
00092 struct m_log_ops_s {
00093         m_result_t (*alloc)(m_log_dsc_t *log_dsc);
00094         m_result_t (*init)(pcm_storeset_t *set, m_log_t *log, m_log_dsc_t *log_dsc);
00095         m_result_t (*truncation_init)(pcm_storeset_t *set, m_log_dsc_t *log_dsc);
00096         m_result_t (*truncation_prepare_next)(pcm_storeset_t *set, m_log_dsc_t *log_dsc);
00097         m_result_t (*truncation_do)(pcm_storeset_t *set, m_log_dsc_t *log_dsc);
00098         m_result_t (*recovery_init)(pcm_storeset_t *set, m_log_dsc_t *log_dsc);
00099         m_result_t (*recovery_prepare_next)(pcm_storeset_t *set, m_log_dsc_t *log_dsc);
00100         m_result_t (*recovery_do)(pcm_storeset_t *set, m_log_dsc_t *log_dsc);
00101         m_result_t (*report_stats)(m_log_dsc_t *log_dsc);
00102 };
00103 
00104 
00109 struct m_log_nvmd_s {
00110         pcm_word_t generic_flags;
00111         pcm_word_t reserved2;                     
00112         pcm_word_t reserved3;                     
00113         pcm_word_t reserved4;                     
00114 };
00115 
00116 struct m_log_dsc_s {
00117         m_log_ops_t      *ops;             
00118         m_log_t          *log;             
00119         m_log_nvmd_t     *nvmd;            
00120         pcm_word_t       *nvphlog;         
00121         uint64_t         flags;            
00122         uint64_t         logorder;         
00123         struct list_head list;
00124 };
00125 
00126 extern m_log_ops_t *m_log_ops[];
00127 
00128 struct m_logmgr_s {
00129         pthread_mutex_t  mutex;                 
00130         struct list_head free_logs_list;        
00131         struct list_head pending_logs_list;     
00132         struct list_head active_logs_list;      
00133         struct list_head known_logtypes_list;   
00134         /* log truncation */
00135         pthread_cond_t   logtrunc_cond;
00136         pthread_t        logtrunc_thread;
00137         uint64_t         trunc_time;
00138         uint64_t         trunc_count;
00139 };
00140 
00141 
00142 m_result_t m_logmgr_init(pcm_storeset_t *set);
00143 m_result_t m_logmgr_fini(void);
00144 m_result_t m_logmgr_register_logtype(pcm_storeset_t *set, int type, m_log_ops_t *ops);
00145 m_result_t m_logmgr_alloc_log(pcm_storeset_t *set, int type, uint64_t flags, m_log_dsc_t **log_dscp);
00146 m_result_t m_logmgr_free_log(m_log_dsc_t *log_dsc);
00147 m_result_t m_logmgr_do_recovery(pcm_storeset_t *set);
00148 m_result_t m_logtrunc_truncate(pcm_storeset_t *set);
00149 void m_logmgr_stat_print();
00150 
00151 
00152 
00153 #define PHLOG_WRITE(logtype, set, phlog, val)                                 \
00154 do {                                                                          \
00155     int retries = 0;                                                          \
00156     while (m_phlog_##logtype##_write(set, (phlog), (val)) != M_R_SUCCESS) {   \
00157         if (retries++ > 1) {                                                  \
00158             M_INTERNALERROR("Cannot complete log write successfully.\n");     \
00159         }                                                                     \
00160         (phlog)->stat_wait_for_trunc++;                                       \
00161         m_logtrunc_truncate(set);                                             \
00162     }                                                                         \
00163 } while (0);
00164 
00165 
00166 #define PHLOG_FLUSH(logtype, set, phlog)                                      \
00167 do {                                                                          \
00168     int retries = 0;                                                          \
00169     while (m_phlog_##logtype##_flush(set, (phlog)) != M_R_SUCCESS) {          \
00170         if (retries++ > 1) {                                                  \
00171             M_INTERNALERROR("Cannot complete log write successfully.\n");     \
00172         }                                                                     \
00173         (phlog)->stat_wait_for_trunc++;                                       \
00174         m_logtrunc_truncate(set);                                             \
00175     }                                                                         \
00176 } while (0);
00177 
00178 
00179 #define PHLOG_WRITE_ASYNCTRUNC(logtype, set, phlog, val)                       \
00180 do {                                                                           \
00181         hrtime_t __start;                                                          \
00182         hrtime_t __end;                                                            \
00183     if (m_phlog_##logtype##_write(set, (phlog), (val)) != M_R_SUCCESS) {       \
00184         (phlog)->stat_wait_for_trunc++;                                        \
00185         __start = hrtime_cycles();                                             \
00186         while (m_phlog_##logtype##_write(set, (phlog), (val)) != M_R_SUCCESS); \
00187         __end = hrtime_cycles();                                               \
00188             phlog->stat_wait_time_for_trunc += (HRTIME_CYCLE2NS(__end - __start)); \
00189     }                                                                          \
00190 } while (0);
00191 
00192 
00193 #define PHLOG_FLUSH_ASYNCTRUNC(logtype, set, phlog)                            \
00194 do {                                                                           \
00195         hrtime_t __start;                                                          \
00196         hrtime_t __end;                                                            \
00197     if (m_phlog_##logtype##_flush(set, (phlog)) != M_R_SUCCESS) {              \
00198         (phlog)->stat_wait_for_trunc++;                                        \
00199         __start = hrtime_cycles();                                             \
00200         while (m_phlog_##logtype##_flush(set, (phlog)) != M_R_SUCCESS);        \
00201         __end = hrtime_cycles();                                               \
00202             phlog->stat_wait_time_for_trunc += (HRTIME_CYCLE2NS(__end - __start)); \
00203     }                                                                          \
00204 } while (0);
00205 
00206 
00207 #ifdef __cplusplus
00208 }
00209 #endif
00210 
00211 #endif /* _LOG_INTERNAL_H */

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