浏览代码

Fix safe access to model->state->per_arch

It may be reallocated, so we need to hold the rwlock at least in read
mode.
Samuel Thibault 4 年之前
父节点
当前提交
7cf3b9f52a
共有 1 个文件被更改,包括 25 次插入2 次删除
  1. 25 2
      src/core/perfmodel/perfmodel_history.c

+ 25 - 2
src/core/perfmodel/perfmodel_history.c

@@ -1591,11 +1591,17 @@ double _starpu_regression_based_job_expected_perf(struct starpu_perfmodel *model
 
 	if(comb == -1)
 		goto docal;
+
+	STARPU_PTHREAD_RWLOCK_RDLOCK(&model->state->model_rwlock);
 	if (model->state->per_arch[comb] == NULL)
+	{
 		// The model has not been executed on this combination
+		STARPU_PTHREAD_RWLOCK_UNLOCK(&model->state->model_rwlock);
 		goto docal;
+	}
 
 	regmodel = &model->state->per_arch[comb][nimpl].regression;
+	STARPU_PTHREAD_RWLOCK_UNLOCK(&model->state->model_rwlock);
 
 	if (regmodel->valid && size >= regmodel->minx * 0.9 && size <= regmodel->maxx * 1.1)
                 exp = regmodel->alpha*pow((double)size, regmodel->beta);
@@ -1627,21 +1633,28 @@ double _starpu_non_linear_regression_based_job_expected_perf(struct starpu_perfm
 	comb = starpu_perfmodel_arch_comb_get(arch->ndevices, arch->devices);
 	if(comb == -1)
 		goto docal;
+
+	STARPU_PTHREAD_RWLOCK_RDLOCK(&model->state->model_rwlock);
 	if (model->state->per_arch[comb] == NULL)
+	{
 		// The model has not been executed on this combination
+		STARPU_PTHREAD_RWLOCK_UNLOCK(&model->state->model_rwlock);
 		goto docal;
+	}
 
 	regmodel = &model->state->per_arch[comb][nimpl].regression;
 
 	if (regmodel->nl_valid && size >= regmodel->minx * 0.9 && size <= regmodel->maxx * 1.1)
+	{
+		STARPU_PTHREAD_RWLOCK_UNLOCK(&model->state->model_rwlock);
 		exp = regmodel->a*pow((double)size, regmodel->b) + regmodel->c;
+	}
 	else
 	{
 		uint32_t key = _starpu_compute_buffers_footprint(model, arch, nimpl, j);
 		struct starpu_perfmodel_per_arch *per_arch_model = &model->state->per_arch[comb][nimpl];
 		struct starpu_perfmodel_history_table *history;
 
-		STARPU_PTHREAD_RWLOCK_RDLOCK(&model->state->model_rwlock);
 		history = per_arch_model->history;
 		HASH_FIND_UINT32_T(history, &key, entry);
 		STARPU_PTHREAD_RWLOCK_UNLOCK(&model->state->model_rwlock);
@@ -1678,10 +1691,16 @@ double _starpu_multiple_regression_based_job_expected_perf(struct starpu_perfmod
 	comb = starpu_perfmodel_arch_comb_get(arch->ndevices, arch->devices);
 	if(comb == -1)
 		goto docal;
+
+	STARPU_PTHREAD_RWLOCK_RDLOCK(&model->state->model_rwlock);
 	if (model->state->per_arch[comb] == NULL)
+	{
 		// The model has not been executed on this combination
+		STARPU_PTHREAD_RWLOCK_UNLOCK(&model->state->model_rwlock);
 		goto docal;
+	}
 	reg_model = &model->state->per_arch[comb][nimpl].regression;
+	STARPU_PTHREAD_RWLOCK_UNLOCK(&model->state->model_rwlock);
 	if (reg_model->coeff == NULL)
 		goto docal;
 
@@ -1734,13 +1753,17 @@ double _starpu_history_based_job_expected_perf(struct starpu_perfmodel *model, s
 	key = _starpu_compute_buffers_footprint(model, arch, nimpl, j);
 	if(comb == -1)
 		goto docal;
+
+	STARPU_PTHREAD_RWLOCK_RDLOCK(&model->state->model_rwlock);
 	if (model->state->per_arch[comb] == NULL)
+	{
 		// The model has not been executed on this combination
+		STARPU_PTHREAD_RWLOCK_UNLOCK(&model->state->model_rwlock);
 		goto docal;
+	}
 
 	per_arch_model = &model->state->per_arch[comb][nimpl];
 
-	STARPU_PTHREAD_RWLOCK_RDLOCK(&model->state->model_rwlock);
 	history = per_arch_model->history;
 	HASH_FIND_UINT32_T(history, &key, elt);
 	entry = (elt == NULL) ? NULL : elt->history_entry;