+ vector<int> processIDS;
+ int process = 0;
+ vector<unsigned long long> positions;
+ vector<linePair> lines;
+ int numSeqs = 0;
+
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+ positions = m->divideFilePerLine(namefile, processors);
+ for (int i = 0; i < (positions.size()-1); i++) { lines.push_back(linePair(positions[i], positions[(i+1)])); }
+#else
+ if(processors == 1){ lines.push_back(linePair(0, 1000)); }
+ else {
+ int numSeqs = 0;
+ positions = m->setFilePosEachLine(namefile, numSeqs);
+ if (positions.size() < processors) { processors = positions.size(); }
+
+ //figure out how many sequences you have to process
+ int numSeqsPerProcessor = numSeqs / processors;
+ for (int i = 0; i < processors; i++) {
+ int startIndex = i * numSeqsPerProcessor;
+ if(i == (processors - 1)){ numSeqsPerProcessor = numSeqs - i * numSeqsPerProcessor; }
+ lines.push_back(linePair(positions[startIndex], numSeqsPerProcessor));
+ }
+ }
+#endif
+
+
+#if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
+
+ //loop through and create all the processes you want
+ while (process != processors-1) {
+ 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){
+ string filename = toString(getpid()) + ".temp";
+ numSeqs = driver(lines[process].start, lines[process].end, filename, groupMap);
+
+ string tempFile = toString(getpid()) + ".num.temp";
+ ofstream outTemp;
+ m->openOutputFile(tempFile, outTemp);
+
+ outTemp << numSeqs << endl;
+ outTemp.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);
+ }
+ }
+
+ string filename = toString(getpid()) + ".temp";
+ numSeqs = driver(lines[processors-1].start, lines[processors-1].end, filename, groupMap);
+
+ //force parent to wait until all the processes are done
+ for (int i=0;i<processIDS.size();i++) {
+ int temp = processIDS[i];
+ wait(&temp);
+ }
+
+ for (int i = 0; i < processIDS.size(); i++) {
+ string tempFile = toString(processIDS[i]) + ".num.temp";
+ ifstream intemp;
+ m->openInputFile(tempFile, intemp);
+
+ int num;
+ intemp >> num; intemp.close();
+ numSeqs += num;
+ m->mothurRemove(tempFile);
+ }
+#else
+ vector<countData*> pDataArray;
+ DWORD dwThreadIdArray[processors-1];
+ HANDLE hThreadArray[processors-1];
+ vector<GroupMap*> copies;
+
+ //Create processor worker threads.
+ for( int i=0; i<processors-1; i++ ){
+ string filename = toString(i) + ".temp";
+
+ GroupMap* copyGroup = new GroupMap();
+ copyGroup->getCopy(groupMap);
+ copies.push_back(copyGroup);
+ vector<string> cGroups = Groups;
+
+ countData* temp = new countData(filename, copyGroup, m, lines[i].start, lines[i].end, groupfile, namefile, cGroups);
+ pDataArray.push_back(temp);
+ processIDS.push_back(i);
+
+ hThreadArray[i] = CreateThread(NULL, 0, MyCountThreadFunction, pDataArray[i], 0, &dwThreadIdArray[i]);
+ }
+
+ string filename = toString(processors-1) + ".temp";
+ numSeqs = driver(lines[processors-1].start, lines[processors-1].end, filename, groupMap);
+
+ //Wait until all threads have terminated.
+ WaitForMultipleObjects(processors-1, hThreadArray, TRUE, INFINITE);
+
+ //Close all thread handles and free memory allocations.
+ for(int i=0; i < pDataArray.size(); i++){
+ numSeqs += pDataArray[i]->total;
+ delete copies[i];
+ CloseHandle(hThreadArray[i]);
+ delete pDataArray[i];
+ }
+#endif
+
+ //append output files
+ for(int i=0;i<processIDS.size();i++){
+ m->appendFiles((toString(processIDS[i]) + ".temp"), outputFileName);
+ m->mothurRemove((toString(processIDS[i]) + ".temp"));
+ }
+ m->appendFiles(filename, outputFileName);
+ m->mothurRemove(filename);
+
+
+ //sanity check
+ if (numSeqs != groupMap->getNumSeqs()) {
+ m->mothurOut("[ERROR]: processes reported processing " + toString(numSeqs) + " sequences, but group file indicates you have " + toString(groupMap->getNumSeqs()) + " sequences.");
+ if (processors == 1) { m->mothurOut(" Could you have a file mismatch?\n"); }
+ else { m->mothurOut(" Either you have a file mismatch or a process failed to complete the task assigned to it.\n"); m->control_pressed = true; }
+ }
+
+ return numSeqs;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "CountSeqsCommand", "createProcesses");
+ exit(1);
+ }
+}
+/**************************************************************************************************/
+int CountSeqsCommand::driver(unsigned long long start, unsigned long long end, string outputFileName, GroupMap*& groupMap) {
+ try {
+
+ ofstream out;
+ m->openOutputFile(outputFileName, out);
+
+ ifstream in;