Prechádzať zdrojové kódy

Always initialize model->rwlock. This fixes a crash on Darwin.

Cyril Roelandt 12 rokov pred
rodič
commit
5c76f7cb8f

+ 3 - 2
src/core/perfmodel/perfmodel.c

@@ -155,14 +155,15 @@ void _starpu_load_perfmodel(struct starpu_perfmodel *model)
 	switch (model->type)
 	switch (model->type)
 	{
 	{
 		case STARPU_PER_ARCH:
 		case STARPU_PER_ARCH:
+			_starpu_load_per_arch_based_model(model);
+			break;
 		case STARPU_COMMON:
 		case STARPU_COMMON:
+			_starpu_load_common_based_model(model);
 			break;
 			break;
-
 		case STARPU_HISTORY_BASED:
 		case STARPU_HISTORY_BASED:
 		case STARPU_NL_REGRESSION_BASED:
 		case STARPU_NL_REGRESSION_BASED:
 			_starpu_load_history_based_model(model, 1);
 			_starpu_load_history_based_model(model, 1);
 			break;
 			break;
-
 		case STARPU_REGRESSION_BASED:
 		case STARPU_REGRESSION_BASED:
 			_starpu_load_history_based_model(model, 0);
 			_starpu_load_history_based_model(model, 0);
 			break;
 			break;

+ 2 - 0
src/core/perfmodel/perfmodel.h

@@ -43,6 +43,8 @@ void _starpu_get_perf_model_dir_debug(char *path, size_t maxlen);
 
 
 double _starpu_history_based_job_expected_perf(struct starpu_perfmodel *model, enum starpu_perf_archtype arch, struct _starpu_job *j, unsigned nimpl);
 double _starpu_history_based_job_expected_perf(struct starpu_perfmodel *model, enum starpu_perf_archtype arch, struct _starpu_job *j, unsigned nimpl);
 int _starpu_register_model(struct starpu_perfmodel *model);
 int _starpu_register_model(struct starpu_perfmodel *model);
+void _starpu_load_per_arch_based_model(struct starpu_perfmodel *model);
+void _starpu_load_common_based_model(struct starpu_perfmodel *model);
 void _starpu_load_history_based_model(struct starpu_perfmodel *model, unsigned scan_history);
 void _starpu_load_history_based_model(struct starpu_perfmodel *model, unsigned scan_history);
 void _starpu_load_perfmodel(struct starpu_perfmodel *model);
 void _starpu_load_perfmodel(struct starpu_perfmodel *model);
 void _starpu_initialize_registered_performance_models(void);
 void _starpu_initialize_registered_performance_models(void);

+ 61 - 0
src/core/perfmodel/perfmodel_history.c

@@ -751,6 +751,67 @@ void _starpu_deinitialize_registered_performance_models(void)
 	_STARPU_PTHREAD_RWLOCK_DESTROY(&registered_models_rwlock);
 	_STARPU_PTHREAD_RWLOCK_DESTROY(&registered_models_rwlock);
 }
 }
 
 
+/*
+ * XXX: We should probably factorize the beginning of the _starpu_load_*_model
+ * functions. This is a bit tricky though, because we must be sure to unlock
+ * registered_models_rwlock at the right place.
+ */
+void _starpu_load_per_arch_based_model(struct starpu_perfmodel *model)
+{
+	STARPU_ASSERT(model && model->symbol);
+
+	int already_loaded;
+
+	_STARPU_PTHREAD_RWLOCK_RDLOCK(&registered_models_rwlock);
+	already_loaded = model->is_loaded;
+	_STARPU_PTHREAD_RWLOCK_UNLOCK(&registered_models_rwlock);
+
+	if (already_loaded)
+		return;
+
+	/* The model is still not loaded so we grab the lock in write mode, and
+	 * if it's not loaded once we have the lock, we do load it. */
+	_STARPU_PTHREAD_RWLOCK_WRLOCK(&registered_models_rwlock);
+
+	/* Was the model initialized since the previous test ? */
+	if (model->is_loaded)
+	{
+		_STARPU_PTHREAD_RWLOCK_UNLOCK(&registered_models_rwlock);
+		return;
+	}
+
+	_STARPU_PTHREAD_RWLOCK_INIT(&model->model_rwlock, NULL);
+	_STARPU_PTHREAD_RWLOCK_UNLOCK(&registered_models_rwlock);
+}
+
+void _starpu_load_common_based_model(struct starpu_perfmodel *model)
+{
+	STARPU_ASSERT(model && model->symbol);
+
+	int already_loaded;
+
+	_STARPU_PTHREAD_RWLOCK_RDLOCK(&registered_models_rwlock);
+	already_loaded = model->is_loaded;
+	_STARPU_PTHREAD_RWLOCK_UNLOCK(&registered_models_rwlock);
+
+	if (already_loaded)
+		return;
+
+	/* The model is still not loaded so we grab the lock in write mode, and
+	 * if it's not loaded once we have the lock, we do load it. */
+	_STARPU_PTHREAD_RWLOCK_WRLOCK(&registered_models_rwlock);
+
+	/* Was the model initialized since the previous test ? */
+	if (model->is_loaded)
+	{
+		_STARPU_PTHREAD_RWLOCK_UNLOCK(&registered_models_rwlock);
+		return;
+	}
+
+	_STARPU_PTHREAD_RWLOCK_INIT(&model->model_rwlock, NULL);
+	_STARPU_PTHREAD_RWLOCK_UNLOCK(&registered_models_rwlock);
+}
+
 /* We first try to grab the global lock in read mode to check whether the model
 /* We first try to grab the global lock in read mode to check whether the model
  * was loaded or not (this is very likely to have been already loaded). If the
  * was loaded or not (this is very likely to have been already loaded). If the
  * model was not loaded yet, we take the lock in write mode, and if the model
  * model was not loaded yet, we take the lock in write mode, and if the model