+int FilterSeqsCommand::createProcessesCreateFilter(Filters& F, string filename) {
+ try {
+ int process = 1;
+ int num = 0;
+ processIDS.clear();
+
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+
+ //loop through and create all the processes you want
+ while (process != processors) {
+ int pid = fork();
+
+ if (pid > 0) {
+ processIDS.push_back(pid); //create map from line number to pid so you can append files in correct order later
+ process++;
+ }else if (pid == 0){
+ //reset child's filter counts to 0;
+ F.a.clear(); F.a.resize(alignmentLength, 0);
+ F.t.clear(); F.t.resize(alignmentLength, 0);
+ F.g.clear(); F.g.resize(alignmentLength, 0);
+ F.c.clear(); F.c.resize(alignmentLength, 0);
+ F.gap.clear(); F.gap.resize(alignmentLength, 0);
+
+ num = driverCreateFilter(F, filename, lines[process]);
+
+ //write out filter counts to file
+ filename += toString(getpid()) + "filterValues.temp";
+ ofstream out;
+ m->openOutputFile(filename, out);
+
+ out << num << endl;
+ out << F.getFilter() << endl;
+ for (int k = 0; k < alignmentLength; k++) { out << F.a[k] << '\t'; } out << endl;
+ for (int k = 0; k < alignmentLength; k++) { out << F.t[k] << '\t'; } out << endl;
+ for (int k = 0; k < alignmentLength; k++) { out << F.g[k] << '\t'; } out << endl;
+ for (int k = 0; k < alignmentLength; k++) { out << F.c[k] << '\t'; } out << endl;
+ for (int k = 0; k < alignmentLength; k++) { out << F.gap[k] << '\t'; } out << endl;
+
+ //cout << F.getFilter() << endl;
+ out.close();
+
+ exit(0);
+ }else {
+ m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine();
+ for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
+ exit(0);
+ }
+ }
+
+ //parent do your part
+ num = driverCreateFilter(F, filename, lines[0]);
+
+ //force parent to wait until all the processes are done
+ for (int i=0;i<(processors-1);i++) {
+ int temp = processIDS[i];
+ wait(&temp);
+ }
+
+ //parent reads in and combines Filter info
+ for (int i = 0; i < processIDS.size(); i++) {
+ string tempFilename = filename + toString(processIDS[i]) + "filterValues.temp";
+ ifstream in;
+ m->openInputFile(tempFilename, in);
+
+ int temp, tempNum;
+ string tempFilterString;
+
+ in >> tempNum; m->gobble(in); num += tempNum;
+
+ in >> tempFilterString;
+ F.mergeFilter(tempFilterString);
+
+ for (int k = 0; k < alignmentLength; k++) { in >> temp; F.a[k] += temp; } m->gobble(in);
+ for (int k = 0; k < alignmentLength; k++) { in >> temp; F.t[k] += temp; } m->gobble(in);
+ for (int k = 0; k < alignmentLength; k++) { in >> temp; F.g[k] += temp; } m->gobble(in);
+ for (int k = 0; k < alignmentLength; k++) { in >> temp; F.c[k] += temp; } m->gobble(in);
+ for (int k = 0; k < alignmentLength; k++) { in >> temp; F.gap[k] += temp; } m->gobble(in);
+
+ in.close();
+ m->mothurRemove(tempFilename);
+ }
+
+
+#else
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ //Windows version shared memory, so be careful when passing variables through the filterData struct.
+ //Above fork() will clone, so memory is separate, but that's not the case with windows,
+ //Taking advantage of shared memory to allow both threads to add info to F.
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ vector<filterData*> pDataArray;
+ DWORD dwThreadIdArray[processors];
+ HANDLE hThreadArray[processors];
+
+ //Create processor worker threads.
+ for( int i=0; i<processors; i++ ){
+
+ filterData* tempFilter = new filterData(filename, m, lines[i]->start, lines[i]->end, alignmentLength, trump, vertical, soft, hard, i);
+ pDataArray.push_back(tempFilter);
+ processIDS.push_back(i);
+
+ hThreadArray[i] = CreateThread(NULL, 0, MyCreateFilterThreadFunction, pDataArray[i], 0, &dwThreadIdArray[i]);
+ }
+
+ //Wait until all threads have terminated.
+ WaitForMultipleObjects(processors, hThreadArray, TRUE, INFINITE);
+
+ //Close all thread handles and free memory allocations.
+ for(int i=0; i < pDataArray.size(); i++){
+ num += pDataArray[i]->count;
+ F.mergeFilter(pDataArray[i]->F.getFilter());
+
+ for (int k = 0; k < alignmentLength; k++) { F.a[k] += pDataArray[i]->F.a[k]; }
+ for (int k = 0; k < alignmentLength; k++) { F.t[k] += pDataArray[i]->F.t[k]; }
+ for (int k = 0; k < alignmentLength; k++) { F.g[k] += pDataArray[i]->F.g[k]; }
+ for (int k = 0; k < alignmentLength; k++) { F.c[k] += pDataArray[i]->F.c[k]; }
+ for (int k = 0; k < alignmentLength; k++) { F.gap[k] += pDataArray[i]->F.gap[k]; }
+
+ CloseHandle(hThreadArray[i]);
+ delete pDataArray[i];
+ }
+
+#endif
+ return num;
+
+ }
+ catch(exception& e) {
+ m->errorOut(e, "FilterSeqsCommand", "createProcessesCreateFilter");
+ exit(1);
+ }
+}