[Bf-blender-cvs] [d28431a] master: OpenNL: make the API thread safe by always passing context.

Brecht Van Lommel noreply at git.blender.org
Sun Nov 22 22:54:41 CET 2015


Commit: d28431a6481a7698105ad45fc68a410e3cd71939
Author: Brecht Van Lommel
Date:   Sun Nov 22 05:15:56 2015 +0100
Branches: master
https://developer.blender.org/rBd28431a6481a7698105ad45fc68a410e3cd71939

OpenNL: make the API thread safe by always passing context.

Previously two laplacian smooth or deform modifiers executing
simultaneously could crash.

===================================================================

M	intern/opennl/extern/ONL_opennl.h
M	intern/opennl/intern/opennl.cpp
M	source/blender/bmesh/operators/bmo_smooth_laplacian.c
M	source/blender/editors/armature/meshlaplacian.c
M	source/blender/editors/armature/meshlaplacian.h
M	source/blender/editors/armature/reeb.c
M	source/blender/editors/uvedit/uvedit_parametrizer.c
M	source/blender/modifiers/intern/MOD_laplaciandeform.c
M	source/blender/modifiers/intern/MOD_laplaciansmooth.c

===================================================================

diff --git a/intern/opennl/extern/ONL_opennl.h b/intern/opennl/extern/ONL_opennl.h
index 61a11fa..a414f40 100644
--- a/intern/opennl/extern/ONL_opennl.h
+++ b/intern/opennl/extern/ONL_opennl.h
@@ -77,35 +77,33 @@ typedef struct NLContext NLContext;
 
 NLContext *nlNewContext(void);
 void nlDeleteContext(NLContext *context);
-void nlMakeCurrent(NLContext *context);
-NLContext *nlGetCurrent(void);
 
 /* State get/set */
 
-void nlSolverParameteri(NLenum pname, NLint param);
+void nlSolverParameteri(NLContext *context, NLenum pname, NLint param);
 
 /* Variables */
 
-void nlSetVariable(NLuint rhsindex, NLuint index, NLdouble value);
-NLdouble nlGetVariable(NLuint rhsindex, NLuint index);
-void nlLockVariable(NLuint index);
-void nlUnlockVariable(NLuint index);
+void nlSetVariable(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value);
+NLdouble nlGetVariable(NLContext *context, NLuint rhsindex, NLuint index);
+void nlLockVariable(NLContext *context, NLuint index);
+void nlUnlockVariable(NLContext *context, NLuint index);
 
 /* Begin/End */
 
-void nlBegin(NLenum primitive);
-void nlEnd(NLenum primitive);
+void nlBegin(NLContext *context, NLenum primitive);
+void nlEnd(NLContext *context, NLenum primitive);
 
 /* Setting elements in matrix/vector */
 
-void nlMatrixAdd(NLuint row, NLuint col, NLdouble value);
-void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLdouble value);
-void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLdouble value);
+void nlMatrixAdd(NLContext *context, NLuint row, NLuint col, NLdouble value);
+void nlRightHandSideAdd(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value);
+void nlRightHandSideSet(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value);
 
 /* Solve */
 
-void nlPrintMatrix(void);
-NLboolean nlSolve(NLboolean solveAgain);
+void nlPrintMatrix(NLContext *context);
+NLboolean nlSolve(NLContext *context, NLboolean solveAgain);
 
 #ifdef __cplusplus
 }
diff --git a/intern/opennl/intern/opennl.cpp b/intern/opennl/intern/opennl.cpp
index de12805..076dce3 100644
--- a/intern/opennl/intern/opennl.cpp
+++ b/intern/opennl/intern/opennl.cpp
@@ -29,19 +29,20 @@
  *	 levy at loria.fr
  *
  *	 ISA Project
- *	 LORIA, INRIA Lorraine, 
+ *	 LORIA, INRIA Lorraine,
  *	 Campus Scientifique, BP 239
- *	 54506 VANDOEUVRE LES NANCY CEDEX 
+ *	 54506 VANDOEUVRE LES NANCY CEDEX
  *	 FRANCE
  *
  *  Note that the GNU General Public License does not permit incorporating
- *  the Software into proprietary programs. 
+ *  the Software into proprietary programs.
  */
 
 #include "ONL_opennl.h"
 
 #include <Eigen/Sparse>
 
+#include <algorithm>
 #include <cassert>
 #include <cstdlib>
 #include <iostream>
@@ -100,22 +101,16 @@ struct NLContext {
 	NLboolean solve_again;
 };
 
-static NLContext* __nlCurrentContext = NULL;
-
 NLContext *nlNewContext(void)
 {
 	NLContext* result = new NLContext();
 	result->state = NL_STATE_INITIAL;
 	result->nb_rhs = 1;
-	nlMakeCurrent(result);
 	return result;
 }
 
 void nlDeleteContext(NLContext *context)
 {
-	if(__nlCurrentContext == context)
-		__nlCurrentContext = NULL;
-
 	context->M.resize(0, 0);
 	context->MtM.resize(0, 0);
 	context->b.clear();
@@ -129,46 +124,36 @@ void nlDeleteContext(NLContext *context)
 	delete context;
 }
 
-void nlMakeCurrent(NLContext *context)
-{
-	__nlCurrentContext = context;
-}
-
-NLContext *nlGetCurrent(void)
-{
-	return __nlCurrentContext;
-}
-
-static void __nlCheckState(NLenum state)
+static void __nlCheckState(NLContext *context, NLenum state)
 {
-	assert(__nlCurrentContext->state == state);
+	assert(context->state == state);
 }
 
-static void __nlTransition(NLenum from_state, NLenum to_state)
+static void __nlTransition(NLContext *context, NLenum from_state, NLenum to_state)
 {
-	__nlCheckState(from_state);
-	__nlCurrentContext->state = to_state;
+	__nlCheckState(context, from_state);
+	context->state = to_state;
 }
 
 /* Get/Set parameters */
 
-void nlSolverParameteri(NLenum pname, NLint param)
+void nlSolverParameteri(NLContext *context, NLenum pname, NLint param)
 {
-	__nlCheckState(NL_STATE_INITIAL);
+	__nlCheckState(context, NL_STATE_INITIAL);
 	switch(pname) {
 	case NL_NB_VARIABLES: {
 		assert(param > 0);
-		__nlCurrentContext->nb_variables = (NLuint)param;
+		context->nb_variables = (NLuint)param;
 	} break;
 	case NL_NB_ROWS: {
 		assert(param > 0);
-		__nlCurrentContext->nb_rows = (NLuint)param;
+		context->nb_rows = (NLuint)param;
 	} break;
 	case NL_LEAST_SQUARES: {
-		__nlCurrentContext->least_squares = (NLboolean)param;
+		context->least_squares = (NLboolean)param;
 	} break;
 	case NL_NB_RIGHT_HAND_SIDES: {
-		__nlCurrentContext->nb_rhs = (NLuint)param;
+		context->nb_rhs = (NLuint)param;
 	} break;
 	default: {
 		assert(0);
@@ -178,35 +163,34 @@ void nlSolverParameteri(NLenum pname, NLint param)
 
 /* Get/Set Lock/Unlock variables */
 
-void nlSetVariable(NLuint rhsindex, NLuint index, NLdouble value)
+void nlSetVariable(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value)
 {
-	__nlCheckState(NL_STATE_SYSTEM);
-	__nlCurrentContext->variable[index].value[rhsindex] = value;	
+	__nlCheckState(context, NL_STATE_SYSTEM);
+	context->variable[index].value[rhsindex] = value;
 }
 
-NLdouble nlGetVariable(NLuint rhsindex, NLuint index)
+NLdouble nlGetVariable(NLContext *context, NLuint rhsindex, NLuint index)
 {
-	assert(__nlCurrentContext->state != NL_STATE_INITIAL);
-	return __nlCurrentContext->variable[index].value[rhsindex];
+	assert(context->state != NL_STATE_INITIAL);
+	return context->variable[index].value[rhsindex];
 }
 
-void nlLockVariable(NLuint index)
+void nlLockVariable(NLContext *context, NLuint index)
 {
-	__nlCheckState(NL_STATE_SYSTEM);
-	__nlCurrentContext->variable[index].locked = true;
+	__nlCheckState(context, NL_STATE_SYSTEM);
+	context->variable[index].locked = true;
 }
 
-void nlUnlockVariable(NLuint index)
+void nlUnlockVariable(NLContext *context, NLuint index)
 {
-	__nlCheckState(NL_STATE_SYSTEM);
-	__nlCurrentContext->variable[index].locked = false;
+	__nlCheckState(context, NL_STATE_SYSTEM);
+	context->variable[index].locked = false;
 }
 
 /* System construction */
 
-static void __nlVariablesToVector()
+static void __nlVariablesToVector(NLContext *context)
 {
-	NLContext *context = __nlCurrentContext;
 	NLuint i, j, nb_rhs;
 
 	nb_rhs= context->nb_rhs;
@@ -220,9 +204,8 @@ static void __nlVariablesToVector()
 	}
 }
 
-static void __nlVectorToVariables()
+static void __nlVectorToVariables(NLContext *context)
 {
-	NLContext *context = __nlCurrentContext;
 	NLuint i, j, nb_rhs;
 
 	nb_rhs= context->nb_rhs;
@@ -236,31 +219,30 @@ static void __nlVectorToVariables()
 	}
 }
 
-static void __nlBeginSystem()
+static void __nlBeginSystem(NLContext *context)
 {
-	assert(__nlCurrentContext->nb_variables > 0);
+	assert(context->nb_variables > 0);
 
-	if (__nlCurrentContext->solve_again)
-		__nlTransition(NL_STATE_SYSTEM_SOLVED, NL_STATE_SYSTEM);
+	if (context->solve_again)
+		__nlTransition(context, NL_STATE_SYSTEM_SOLVED, NL_STATE_SYSTEM);
 	else {
-		__nlTransition(NL_STATE_INITIAL, NL_STATE_SYSTEM);
+		__nlTransition(context, NL_STATE_INITIAL, NL_STATE_SYSTEM);
 
-		__nlCurrentContext->variable.resize(__nlCurrentContext->nb_variables);
+		context->variable.resize(context->nb_variables);
 	}
 }
 
-static void __nlEndSystem()
+static void __nlEndSystem(NLContext *context)
 {
-	__nlTransition(NL_STATE_MATRIX_CONSTRUCTED, NL_STATE_SYSTEM_CONSTRUCTED);	
+	__nlTransition(context, NL_STATE_MATRIX_CONSTRUCTED, NL_STATE_SYSTEM_CONSTRUCTED);
 }
 
-static void __nlBeginMatrix()
+static void __nlBeginMatrix(NLContext *context)
 {
 	NLuint i;
 	NLuint m = 0, n = 0;
-	NLContext *context = __nlCurrentContext;
 
-	__nlTransition(NL_STATE_SYSTEM, NL_STATE_MATRIX);
+	__nlTransition(context, NL_STATE_SYSTEM, NL_STATE_MATRIX);
 
 	if (!context->solve_again) {
 		for(i=0; i<context->nb_variables; i++) {
@@ -275,6 +257,10 @@ static void __nlBeginMatrix()
 		context->m = m;
 		context->n = n;
 
+		/* reserve reasonable estimate */
+		context->Mtriplets.clear();
+		context->Mtriplets.reserve(std::max(m, n)*3);
+
 		context->b.resize(context->nb_rhs);
 		context->x.resize(context->nb_rhs);
 
@@ -289,18 +275,17 @@ static void __nlBeginMatrix()
 			context->b[i].setZero(context->m);
 	}
 
-	__nlVariablesToVector();
+	__nlVariablesToVector(context);
 }
 
-static void __nlEndMatrixRHS(NLuint rhs)
+static void __nlEndMatrixRHS(NLContext *context, NLuint rhs)
 {
-	NLContext *context = __nlCurrentContext;
 	NLVariable *variable;
 	NLuint i, j;
 
 	EigenVectorX& b = context->b[rhs];
 
-	for(i=0; i<__nlCurrentContext->nb_variables; i++) {
+	for(i=0; i<context->nb_variables; i++) {
 		variable = &(context->variable[i]);
 
 		if(variable->locked) {
@@ -316,12 +301,10 @@ static void __nlEndMatrixRHS(NLuint rhs)
 		context->Mtb[rhs] = context->M.transpose() * b;
 }
 
-static void __nlEndMatrix()
+static void __nlEndMatrix(NLContext *context)
 {
-	NLContext *context = __nlCurrentContext;
+	__nlTransition(context, NL_STATE_MATRIX, NL_STATE_MATRIX_CONSTRUCTED);
 
-	__nlTransition(NL_STATE_MATRIX, NL_STATE_MATRIX_CONSTRUCTED);	
-	
 	if(!context->solve_again) {
 		context->M.resize(context->m, context->n);
 		context->M.setFromTriplets(context->Mtriplets.begin(), context->Mtriplets.end());
@@ -337,14 +320,12 @@ static void __nlEndMatrix()
 	}
 
 	for (NLuint rhs=0; rhs<context->nb_rhs; rhs++)
-		__nlEndMatrixRHS(rhs);
+		__nlEndMatrixRHS(context, rhs);
 }
 
-void nlMatrixAdd(NLuint row, NLuint col, NLdouble value)
+void nlMatrixAdd(NLContext *context, NLuint row, NLuint col, NLdouble value)
 {
-	NLContext *context = __nlCurrentContext;
-
-	__nlCheckState(NL_STATE_MATRIX);
+	__nlCheckState(context, NL_STATE_MATRIX);
 
 	if(context->solve_again)
 		return;
@@ -368,11 +349,9 @@ void nlMatrixAdd(NLuint row, NLuint col, NLdouble value)
 	}
 }
 
-void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLdouble value)
+void nlRightHandSideAdd(NLContext *context, NLuint rhsindex, NLuint index, NLdouble value)
 {
-	NLContext *context = __nlCurrentContext;
-
-	__nlCheckState(NL_STATE_MATRIX);
+	__nlCheckState(context, NL_STATE_MATRIX);
 
 	if(context->least_squares) {
 		context->b[rhsindex][index] += value;
@@ -385,11 +364,9 @@ v

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list