00001 /** 00002 * @file byzantinegeneralthread.h 00003 * @author Reshen Amin <reshen@zensrc.com> 00004 * 00005 * @brief Contains the class definition for the @ref ByzantineGeneralThread 00006 * 00007 * @license Byzantine Generals Problem Coding Sample.<br> 00008 * Copyright (C) 2010 Reshen Amin.<br> 00009 * See @ref license_sec for details.<br> 00010 * 00011 */ 00012 00013 #ifndef SRC_BYZANTINEGENERALTHREAD_H_ 00014 #define SRC_BYZANTINEGENERALTHREAD_H_ 00015 00016 #include <boost/thread/thread.hpp> 00017 #include <boost/shared_ptr.hpp> 00018 #include <boost/interprocess/managed_shared_memory.hpp> 00019 00020 #include <log4cpp/Category.hh> 00021 #include <list> 00022 00023 #include "order.h" 00024 #include "ordertree.h" 00025 #include "sharedmemtypes.h" 00026 00027 /** 00028 * @brief Every instance of this class operates as a thread, in one of two 00029 * operational modes: 00030 * 00031 * 1. Commanding General - Kick off initial order to Lieutenant Generals, 00032 * and control when each of the Lieutenant Generals are allowed to begin their 00033 * rounds of communication. 00034 * 00035 * 2. Lieutenant General - Wait for orders from other generals, generate 00036 * orders to other generals, and coordinate with the Commanding General for 00037 * when messages may be sent or received (rounds). Upon reception of a 00038 * message (aka Order), this general will append his unique ID to the 00039 * received message and queue broadcasting that message to all other generals. 00040 * Prior to beginning each round, and upon completion of each round, this 00041 * thread will coordinate with the Commanding General thread to begin 00042 * subsequent rounds. 00043 */ 00044 class ByzantineGeneralThread { 00045 public: 00046 /** 00047 * @brief Create a thread that represents a single byzantine general, 00048 * eiher in Commanding General mode or in Lieutenant Genearl mode. 00049 * 00050 * @param kUniqueID Unique Identifier for this thread. When 0, this 00051 * thread will be the commanding general. When > 0, this thread will be 00052 * a Lieutenant General. 00053 * 00054 * @param kSharedMemName The shared memory area's name. 00055 * 00056 * @param kMailboxVectorName The name of the mailbox vector within the 00057 * shared memory area. 00058 * 00059 * @param kIsLoyal TRUE if this general is set to loyal, FALSE if 00060 * disloyal 00061 * 00062 * @param kTotalNumberGenerals The total number of generals involved in 00063 * this problem 00064 * 00065 * @param kTotalNumberMessages The total number of messages this general 00066 * should expect to receive during his lifetime. 00067 * 00068 * @param kBroadcastRoundsRequired The number of rounds this general 00069 * should broadcast for. 00070 * 00071 * @param kLogCategoryName The name of the logging category to use for 00072 * output. 00073 * 00074 * @param kGenerateGraph TRUE if this general should generate a DOT 00075 * output graph from the tree of received messages, FALSE otherwise. 00076 * 00077 * @param kTraitorSetName The set in which the unique identifiers of all 00078 * of the traitors are stored. 00079 */ 00080 ByzantineGeneralThread(const unsigned int kUniqueID, 00081 const char* kSharedMemName, 00082 const char* kMailboxVectorName, 00083 const bool kIsLoyal, 00084 const unsigned int kTotalNumberGenerals, 00085 const unsigned int kTotalNumberMessages, 00086 const unsigned int kBroadcastRoundsRequired, 00087 const char* kLogCategoryName, 00088 const bool kGenerateGraph, 00089 const char* kTraitorSetName); 00090 00091 /** 00092 * @brief Destructor 00093 */ 00094 ~ByzantineGeneralThread(void); 00095 00096 /** 00097 * @brief Request that this thread stop 00098 */ 00099 void Stop(); 00100 00101 /** 00102 * @brief Create and run this thread 00103 */ 00104 void Start(); 00105 00106 private: 00107 00108 /** 00109 * @brief List of orders that are generated within this instance 00110 */ 00111 typedef std::list<LocalOrder> LocalOrderList; 00112 00113 /** 00114 * @brief This general's unique identifer (ID). The Commanding General 00115 * is always 0, while the Lieutenant Generals are always > 0. 00116 */ 00117 const unsigned int kUniqueID_; 00118 00119 /** 00120 * @brief TRUE if this General is loyal, FALSE otherwise. A loyal 00121 * general will pass orders through unmolested, while a disloyal general 00122 * will randomly corrupt orders passed through. 00123 */ 00124 const bool kIsLoyal_; 00125 00126 /** 00127 * @brief The total number of generals on the battlefield. 00128 */ 00129 const unsigned int kTotalNumberGenerals_; 00130 00131 /** 00132 * @brief The total number of messages this general is expected to 00133 * receive during his lifetime. 00134 */ 00135 const unsigned int kTotalNumberMessages_; 00136 00137 /** 00138 * @brief The number of rounds to broadcast orders. Each round 00139 * consists of receiving an order, appending my unique id, and queueing 00140 * that order for transmission to the other generals during the next 00141 * round. 00142 */ 00143 const unsigned int kBroadcastRoundsRequired_; 00144 00145 /** 00146 * @brief TRUE to generate a DOT graph of the received messages, FALSE 00147 * otherwise. 00148 */ 00149 const bool kGenerateGraph_; 00150 00151 /** 00152 * @brief Begin executing this thread. 00153 */ 00154 void Run(); 00155 00156 /** 00157 * @brief Broadcast all queued orders from the previous round. 00158 */ 00159 void BroadcastOrders(); 00160 00161 /** 00162 * @brief The Lieutenant General operational mode's run routine. 00163 */ 00164 void LieutenantGeneralRun(); 00165 00166 /** 00167 * @brief The Commanding General operational mode's run routine. 00168 */ 00169 void CommandingGeneralRun(); 00170 00171 /** 00172 * @brief This instance's thread information 00173 */ 00174 boost::shared_ptr<boost::thread> thread_; 00175 00176 /** 00177 * @brief Shared memory segment reference. We communicate to the 00178 * other generals via this shared memory region. 00179 */ 00180 boost::interprocess::managed_shared_memory* segment_; 00181 00182 /** 00183 * @brief The Tree of received orders. Each received order's 00184 * communication path is used to determine its placement in the tree. 00185 * The Commanding Generals' initial order is always the root node. The 00186 * set of all nodes at a given depth (level) represent all of the 00187 * messages received in that round of communication. 00188 */ 00189 OrderTree* received_orders_; 00190 00191 /** 00192 * @brief Shared memory region's vector of mailboxes. Each mailbox 00193 * belongs to a single General where the index into the vector is the 00194 * owning General's Unique ID (@ref kUniqueID_). Other generals can 00195 * queue messages for the owning general by placing Orders for that 00196 * general into his mailbox. The owning general will read orders out of 00197 * his mailbox during rounds. 00198 */ 00199 SharedMemoryMailboxVector* mailbox_vector_; 00200 00201 /** 00202 * @brief The list of orders we want to transmit at the beginning of 00203 * the next round. 00204 */ 00205 LocalOrderList order_transmit_queue_; 00206 00207 /** 00208 * @brief Debug logger reference 00209 */ 00210 log4cpp::Category& log_; 00211 00212 /** 00213 * @brief Seed used in random number generator 00214 */ 00215 unsigned int rand_seed_; 00216 }; 00217 00218 #endif // SRC_BYZANTINEGENERALTHREAD_H_
1.6.3