diff options
author | Tuukka Tikkanen <tuukka.tikkanen@linaro.org> | 2014-12-03 14:12:30 +0200 |
---|---|---|
committer | Tuukka Tikkanen <tuukka.tikkanen@linaro.org> | 2014-12-05 09:52:39 +0200 |
commit | 4b3a7cc81053c2ac93d9ea784d603ec56239fae7 (patch) | |
tree | 4685011f688175c150d3ebab073277961b10e560 | |
parent | 574c417a397b96e65d33ddf49dcf70293f56b53e (diff) |
idlestat: Return error from inter() and intersection() on alloc fail
This patch changes the return value of inter() and intersection()
on allocation fail to ptrerror(). Previously the return value was
NULL, which under normal conditions indicates no overlap between
the two sets. Further cascading changes are made to callers of
these functions and the callers of callers etc.
Signed-off-by: Tuukka Tikkanen <tuukka.tikkanen@linaro.org>
-rw-r--r-- | idlestat.c | 24 | ||||
-rw-r--r-- | topology.c | 17 |
2 files changed, 35 insertions, 6 deletions
@@ -204,7 +204,7 @@ static struct cpuidle_data *intersection(struct cpuidle_data *data1, data = calloc(sizeof(*data), 1); if (!data) - return NULL; + return ptrerror(__func__); data->begin = begin; data->end = end; @@ -230,7 +230,7 @@ static struct cpuidle_cstate *inter(struct cpuidle_cstate *c1, result = calloc(sizeof(*result), 1); if (!result) - return NULL; + return ptrerror(__func__); for (i = 0, index = 0; i < c1->nrdata; i++) { @@ -248,6 +248,11 @@ static struct cpuidle_cstate *inter(struct cpuidle_cstate *c1, interval = intersection(&c1->data[i], &c2->data[j]); if (!interval) continue; + if (is_err(interval)) { + free(data); + free(result); + return ptrerror(NULL); + } result->min_time = MIN(result->min_time, interval->duration); @@ -267,7 +272,7 @@ static struct cpuidle_cstate *inter(struct cpuidle_cstate *c1, if (!tmp) { free(data); free(result); - return NULL; + return ptrerror(__func__); } data = tmp; @@ -1129,6 +1134,11 @@ struct cpuidle_datas *cluster_data(struct cpuidle_datas *datas) cstates = inter(cstates, c1); if (!cstates) continue; + if (is_err(cstates)) { + release_cstate_info(result->cstates, 1); + free(result); + return ptrerror(NULL); + } } /* copy state names from the first cpu */ @@ -1169,6 +1179,10 @@ struct cpuidle_cstates *core_cluster_data(struct cpu_core *s_core) cstates = inter(cstates, c1); if (!cstates) continue; + if (is_err(cstates)) { + release_cstate_info(result, 1); + return ptrerror(NULL); + } } /* copy state name from first cpu */ s_cpu = list_first_entry(&s_core->cpu_head, struct cpu_cpu, @@ -1206,6 +1220,10 @@ struct cpuidle_cstates *physical_cluster_data(struct cpu_physical *s_phy) cstates = inter(cstates, c1); if (!cstates) continue; + if (is_err(cstates)) { + release_cstate_info(result, 1); + return ptrerror(NULL); + } } /* copy state name from first core (if any) */ s_core = list_first_entry(&s_phy->core_head, struct cpu_core, @@ -437,13 +437,24 @@ int establish_idledata_to_topo(struct cpuidle_datas *datas) return -1; list_for_each_entry(s_phy, &g_cpu_topo_list.physical_head, - list_physical) - list_for_each_entry(s_core, &s_phy->core_head, list_core) + list_physical) { + list_for_each_entry(s_core, &s_phy->core_head, list_core) { s_core->cstates = core_cluster_data(s_core); + if (is_err(s_core->cstates)) { + s_core->cstates = NULL; + return -1; + } + } + } list_for_each_entry(s_phy, &g_cpu_topo_list.physical_head, - list_physical) + list_physical) { s_phy->cstates = physical_cluster_data(s_phy); + if (is_err(s_phy->cstates)) { + s_phy->cstates = NULL; + return -1; + } + } return 0; } |