aboutsummaryrefslogtreecommitdiff
path: root/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'core.c')
-rw-r--r--core.c89
1 files changed, 56 insertions, 33 deletions
diff --git a/core.c b/core.c
index 1c247f0..c604a15 100644
--- a/core.c
+++ b/core.c
@@ -4,7 +4,7 @@
* This module contains code to probe the FPGA for its installed cores.
*
* Author: Paul Selkirk, Rob Austein
- * Copyright (c) 2015-2016, NORDUnet A/S All rights reserved.
+ * Copyright (c) 2015-2017, NORDUnet A/S All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -97,7 +97,7 @@ static int name_matches(const hal_core_t *const core, const char * const name)
static const struct { const char *name; hal_addr_t extra; } gaps[] = {
{ "csprng", 11 * CORE_SIZE }, /* empty slots after csprng */
{ "modexps6", 3 * CORE_SIZE }, /* ModexpS6 uses four slots */
- { "modexpa7", 3 * CORE_SIZE }, /* ModexpA7 uses four slots */
+ { "modexpa7", 7 * CORE_SIZE }, /* ModexpA7 uses eight slots */
};
static hal_core_t *head = NULL;
@@ -135,7 +135,7 @@ static hal_core_t *probe_cores(void)
if (core->info.name[0] == 0x00 || core->info.name[0] == 0xff)
continue;
- for (int i = 0; i < sizeof(gaps)/sizeof(*gaps); i++) {
+ for (size_t i = 0; i < sizeof(gaps)/sizeof(*gaps); i++) {
if (name_matches(core, gaps[i].name)) {
addr += gaps[i].extra;
break;
@@ -201,17 +201,19 @@ hal_core_t *hal_core_find(const char *name, hal_core_t *core)
return NULL;
}
-hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore)
+static hal_error_t hal_core_alloc_no_wait(const char *name, hal_core_t **pcore)
{
- hal_core_t *core;
- hal_error_t err = HAL_ERROR_CORE_NOT_FOUND;
+ /*
+ * This used to allow name == NULL iff *core != NULL, but the
+ * semantics were fragile and in practice we always pass a name
+ * anyway, so simplify by requiring name != NULL, always.
+ */
- if (name == NULL && (pcore == NULL || *pcore == NULL))
+ if (name == NULL || pcore == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
- core = *pcore;
- if (name == NULL)
- name = core->info.name;
+ hal_error_t err = HAL_ERROR_CORE_NOT_FOUND;
+ hal_core_t *core = *pcore;
if (core != NULL) {
/* if we can reallocate the same core, do it now */
@@ -221,35 +223,56 @@ hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore)
hal_critical_section_end();
return HAL_OK;
}
- /* else fall through to search */
+ /* else forget that core and fall through to search */
+ *pcore = NULL;
}
- while (1) {
- hal_critical_section_start();
- 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_start();
+ for (core = hal_core_find(name, NULL); core != NULL; core = hal_core_find(name, core)) {
+ if (core->busy) {
+ err = HAL_ERROR_CORE_BUSY;
+ continue;
}
- hal_critical_section_end();
- if (err == HAL_ERROR_CORE_BUSY)
- hal_task_yield();
- else
- break;
- }
+ err = HAL_OK;
+ *pcore = core;
+ core->busy = 1;
+ break;
+ }
+ hal_critical_section_end();
return err;
}
+hal_error_t hal_core_alloc(const char *name, hal_core_t **pcore)
+{
+ hal_error_t err;
+
+ while ((err = hal_core_alloc_no_wait(name, pcore)) == HAL_ERROR_CORE_BUSY)
+ hal_task_yield();
+
+ return err;
+}
+
+hal_error_t hal_core_alloc2(const char *name1, hal_core_t **pcore1,
+ const char *name2, hal_core_t **pcore2)
+{
+ hal_error_t err;
+
+ while (1) {
+ if ((err = hal_core_alloc(name1, pcore1)) != HAL_OK)
+ return err;
+
+ if ((err = hal_core_alloc_no_wait(name2, pcore2)) == HAL_OK)
+ return HAL_OK;
+
+ hal_core_free(*pcore1);
+ /* hal_core_free does a yield, so we don't need to do another one */
+
+ if (err != HAL_ERROR_CORE_BUSY)
+ return err;
+ }
+}
+
void hal_core_free(hal_core_t *core)
{
if (core != NULL) {
@@ -270,7 +293,7 @@ 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)
+int hal_core_busy(const hal_core_t *core)
{
return (int)core->busy;
}