浏览代码

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

Cyril Roelandt 12 年之前
父节点
当前提交
5c76f7cb8f
共有 3 个文件被更改,包括 66 次插入2 次删除
  1. 3 2
      src/core/perfmodel/perfmodel.c
  2. 2 0
      src/core/perfmodel/perfmodel.h
  3. 61 0
      src/core/perfmodel/perfmodel_history.c

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

@@ -155,14 +155,15 @@ void _starpu_load_perfmodel(struct starpu_perfmodel *model)
 	switch (model->type)
 	{
 		case STARPU_PER_ARCH:
+			_starpu_load_per_arch_based_model(model);
+			break;
 		case STARPU_COMMON:
+			_starpu_load_common_based_model(model);
 			break;
-
 		case STARPU_HISTORY_BASED:
 		case STARPU_NL_REGRESSION_BASED:
 			_starpu_load_history_based_model(model, 1);
 			break;
-
 		case STARPU_REGRESSION_BASED:
 			_starpu_load_history_based_model(model, 0);
 			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);
 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_perfmodel(struct starpu_perfmodel *model);
 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);
 }
 
+/*
+ * 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
  * 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