aboutsummaryrefslogtreecommitdiff
path: root/core.c
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2016-07-05 22:45:35 -0400
committerPaul Selkirk <paul@psgd.org>2016-07-05 22:45:35 -0400
commit30f8e4e85b6a337291b09d55d8edc15e422b6341 (patch)
tree19199dd47bb98e18a96281d34e35d1971565fc72 /core.c
parente1c57eff41a57b8a3f16e5d652b5598d75887a21 (diff)
Attempt to add resource management, for multiple cores of the same type.
Find a suitable core, and mark it busy. Don't forget to release it as soon as you're done. This has a knock-on effect of un-const'ing core arguments and struct fields in a lot of places, and it moves some core checks around.
Diffstat (limited to 'core.c')
-rw-r--r--core.c70
1 files changed, 61 insertions, 9 deletions
diff --git a/core.c b/core.c
index ffe61e6..9488ab9 100644
--- a/core.c
+++ b/core.c
@@ -76,6 +76,7 @@
struct hal_core {
hal_core_info_t info;
+ uint32_t busy;
struct hal_core *next;
};
@@ -166,12 +167,12 @@ static hal_core_t *probe_cores(void)
return NULL;
}
-const hal_core_t * hal_core_iterate(const hal_core_t *core)
+hal_core_t * hal_core_iterate(hal_core_t *core)
{
return core == NULL ? probe_cores() : core->next;
}
-const hal_core_t *hal_core_find(const char *name, const hal_core_t *core)
+hal_core_t *hal_core_find(const char *name, hal_core_t *core)
{
for (core = hal_core_iterate(core); core != NULL; core = core->next)
if (name_matches(core, name))
@@ -179,18 +180,64 @@ const hal_core_t *hal_core_find(const char *name, const hal_core_t *core)
return NULL;
}
-hal_error_t hal_core_check_name(const hal_core_t **core, const char *name)
+__attribute__((weak)) void hal_critical_section_start(void)
{
- if (core == NULL || name == NULL)
+ return;
+}
+
+__attribute__((weak)) void hal_critical_section_end(void)
+{
+ return;
+}
+
+hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore)
+{
+ hal_core_t *core;
+ hal_error_t err = HAL_ERROR_CORE_NOT_FOUND;
+
+ if (name == NULL && (pcore == NULL || *pcore == NULL))
return HAL_ERROR_BAD_ARGUMENTS;
- if (*core == NULL && (*core = hal_core_find(name, NULL)) != NULL)
- return HAL_OK;
+ core = *pcore;
+ if (name == NULL)
+ name = core->info.name;
+
+ hal_critical_section_start();
+ if (core != NULL) {
+ /* if we can reallocate the same core, do it now */
+ if (!core->busy) {
+ core->busy = 1;
+ hal_critical_section_end();
+ return HAL_OK;
+ }
+ /* else fall through to search */
+ }
+ for (core = hal_core_iterate(NULL); core != NULL; core = core->next) {
+ if (name_matches(core, name)) {
+ if (core->busy) {
+ err = HAL_ERROR_CORE_BUSY;
+ continue;
+ }
+ else {
+ err = HAL_OK;
+ *pcore = core;
+ core->busy = 1;
+ break;
+ }
+ }
+ }
+ hal_critical_section_end();
- if (*core == NULL || !name_matches(*core, name))
- return HAL_ERROR_CORE_NOT_FOUND;
+ return err;
+}
- return HAL_OK;
+void hal_core_free(hal_core_t *core)
+{
+ if (core != NULL) {
+ hal_critical_section_start();
+ core->busy = 0;
+ hal_critical_section_end();
+ }
}
hal_addr_t hal_core_base(const hal_core_t *core)
@@ -203,6 +250,11 @@ const hal_core_info_t *hal_core_info(const hal_core_t *core)
return core == NULL ? NULL : &core->info;
}
+const int hal_core_busy(const hal_core_t *core)
+{
+ return (int)core->busy;
+}
+
/*
* Local variables:
* indent-tabs-mode: nil