//------------------------------------------------------------------------ // File // merge-main.cpp // Description: // 1. Thus program sorts a sequence of N oisitive integer numbers by // a merge network. // 2. A master thread sends input to the merge network. After the data // is sent, a END_OD_DATA flag follows to indicate the end of // data stream. // 3. The merge network consists of a number of merge threads, each of // which has two input channel and one output channel. They connecte // together to form a merge network. // 4. A collector thread receives the output from the last merge thread // and displays the sorted list. //------------------------------------------------------------------------ #include #include #include #include "ThreadClass.h" #include "merge-thread.h" // global data variables int NumberOfData; // number of input data to be sorted, should be a power of 2 // variables needed to build sorting network MergeThread *ppMergeThread[MAX_THREADS]; AsynOneToOneChannel *ppChannel[MAX_CHANNELS]; //----------------------------------------------------------------------- // main program //----------------------------------------------------------------------- void main(int argc, char *argv[]) { MasterThread *masterThread; CollectorThread *collectorThread; int numberOfThreads; // number of merging thread int numberOfChannels; // number of channels int i; // read in the number of input values cout << "Please input the number of data (n = power(2)): " << endl; cin >> NumberOfData; // create the master thread, assign thread id 0 to it int masterThreadID = 0; masterThread = new MasterThread(0, NumberOfData); // create the collector thread, assign thread id N to it int collectorThreadID = NumberOfData; collectorThread = new CollectorThread(collectorThreadID); // create N - 1 merge threads numberOfThreads = NumberOfData - 1; int mergetThreadID; for (i = 1; i <= numberOfThreads; i++) { mergetThreadID = i; // thread id goes from 1 to N-1 ppMergeThread[i] = new MergeThread(mergetThreadID); } cout << "All merge threads have been activated" << endl; // create all the channels strstream channelName; int threadID1; // one end of the channel int threadID2; // the another end of the channel numberOfChannels = 2 * NumberOfData - 1; // 2*N-1 channels for (i = 0; i < numberOfChannels; i++) { if(i == 0) threadID1 = collectorThreadID; // the root merge thread connects to collectorThread else threadID1 = (i + 1) / 2; if (i <= (NumberOfData - 2)) threadID2 = i + 1; else threadID2 = masterThreadID; // first level channel, one end is the master channelName.seekp(0, ios::beg); channelName << "Channel" << threadID2 << "-" << threadID1 << '\0'; ppChannel[i] = new AsynOneToOneChannel(channelName.str(), threadID2, threadID1); cout << "Channel " << i << " has been created" << endl; } cout << "All channels have been activated" << endl; // fire up masterthread and all the merge threads masterThread->Begin(); collectorThread->Begin(); for (i = 1; i <= numberOfThreads; i++) ppMergeThread[i]->Begin(); // wait for child threads masterThread->Join(); for (i = 1; i <= numberOfThreads; i++) ppMergeThread[i]->Join(); // free the dynamic allocated memory for (i = 1; i <= numberOfThreads; i++) delete ppMergeThread[i]; for (i = 1; i <= numberOfChannels; i++) delete ppChannel[i]; delete masterThread; delete collectorThread; Exit(); }