void MassSpringSystemMT::ComputeHelper(enum MassSpringSystemMT_computationTargetType computationTarget, double * u, double * uSecondary, void * target, bool addQuantity) { // launch threads int numParticles3 = 3*numParticles; struct MassSpringSystemMT_threadArg * threadArgv = (struct MassSpringSystemMT_threadArg*) malloc (sizeof(struct MassSpringSystemMT_threadArg) * numThreads); pthread_t * tid = (pthread_t*) malloc (sizeof(pthread_t) * numThreads); for(int i=0; i<numThreads; i++) { threadArgv[i].massSpringSystemMT = this; threadArgv[i].u = u; threadArgv[i].rank = i; threadArgv[i].computationTarget = computationTarget; } switch(computationTarget) { case FORCE: case DAMPINGFORCE: { for(int i=0; i<numThreads; i++) threadArgv[i].targetBuffer = (void*)(&internalForceBuffer[i * numParticles3]); memset(internalForceBuffer, 0, sizeof(double) * numParticles3 * numThreads); } break; case STIFFNESSMATRIX: case HESSIANAPPROXIMATION: { for(int i=0; i<numThreads; i++) { threadArgv[i].targetBuffer = (void*)(sparseMatrixBuffer[i]); sparseMatrixBuffer[i]->ResetToZero(); } } break; default: printf("Error: unknown computation type.\n"); exit(1); break; } for(int i=0; i<numThreads; i++) { if (pthread_create(&tid[i], NULL, MassSpringSystemMT_WorkerThread, &threadArgv[i]) != 0) { printf("Error: unable to launch thread %d.\n", i); exit(1); } } for(int i=0; i<numThreads; i++) { if (pthread_join(tid[i], NULL) != 0) { printf("Error: unable to join thread %d.\n", i); exit(1); } } free(threadArgv); free(tid); // assemble results switch(computationTarget) { case FORCE: case DAMPINGFORCE: { double * f = (double*) target; if (!addQuantity) memset(f, 0, sizeof(double) * numParticles3); for(int i=0; i<numThreads; i++) { double * source = &internalForceBuffer[i * numParticles3]; for(int j=0; j<numParticles3; j++) f[j] += source[j]; } if ((computationTarget == FORCE) && addGravity) ComputeGravity(f, true); } break; case STIFFNESSMATRIX: case HESSIANAPPROXIMATION: { SparseMatrix * targetK = (SparseMatrix*) target; if (!addQuantity) targetK->ResetToZero(); for(int i=0; i<numThreads; i++) { *targetK += *(sparseMatrixBuffer[i]); } } break; default: printf("Error: unknown computation type.\n"); exit(1); break; } }