[Cbe-oss-dev] [PATCH] libspe2: Initialise object-id on isolated program load
Jeremy Kerr
jk at ozlabs.org
Tue Aug 14 19:46:27 EST 2007
When performing an isolated program load, we don't update the object-id
file, used for debugging and profiling. This changes does the write for
both isolated and non-isolated cases.
In the case of isolated contexts, we need to defer this loading until we
have received the appropriate stop code from the loader.
Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
---
spebase/create.c | 1 +
spebase/load.c | 49 +++++++++++++++++++++++++++++++++++--------------
spebase/run.c | 2 +-
spebase/spebase.h | 17 +++++++++++++++++
4 files changed, 54 insertions(+), 15 deletions(-)
Index: libspe2/spebase/load.c
===================================================================
--- libspe2.orig/spebase/load.c
+++ libspe2/spebase/load.c
@@ -31,6 +31,34 @@
#endif
/**
+ * Register the SPE program's start address with the oprofile and gdb, by
+ * writing to the object-id file.
+ */
+void _base_spe_program_load_complete(spe_context_ptr_t spectx)
+{
+ int objfd, len;
+ char buf[20];
+ spe_program_handle_t *program;
+
+ program = spectx->base_private->loaded_program;
+
+ if (!program || !program->elf_image) {
+ DEBUG_PRINTF("%s called, but no program loaded\n", __func__);
+ return;
+ }
+
+ objfd = openat(spectx->base_private->fd_spe_dir, "object-id", O_RDWR);
+ if (objfd < 0)
+ return;
+
+ len = sprintf(buf, "%p", program->elf_image);
+ write(objfd, buf, len + 1);
+ close(objfd);
+
+ __spe_context_update_event();
+}
+
+/**
* Send data to a SPU in mbox when space is available.
*
* Helper function for internal libspe use.
@@ -160,9 +188,11 @@ static int spe_start_emulated_isolated_a
int _base_spe_program_load(spe_context_ptr_t spe, spe_program_handle_t *program)
{
- int rc = 0, objfd;
+ int rc = 0;
struct spe_ld_info ld_info;
+ spe->base_private->loaded_program = program;
+
if (spe->base_private->flags & SPE_ISOLATE) {
rc = spe_start_isolated_app(spe, program);
@@ -170,8 +200,10 @@ int _base_spe_program_load(spe_context_p
rc = spe_start_emulated_isolated_app(spe, program, &ld_info);
} else {
- rc = _base_spe_load_spe_elf(program, spe->base_private->mem_mmap_base,
- &ld_info);
+ rc = _base_spe_load_spe_elf(program,
+ spe->base_private->mem_mmap_base, &ld_info);
+ if (!rc)
+ _base_spe_program_load_complete(spe);
}
if (rc != 0) {
@@ -179,17 +211,6 @@ int _base_spe_program_load(spe_context_p
return -1;
}
- /* Register SPE image start address as "object-id" for oprofile. */
- objfd = openat (spe->base_private->fd_spe_dir,"object-id", O_RDWR);
- if (objfd >= 0) {
- char buf[100];
- sprintf (buf, "%p", program->elf_image);
- write (objfd, buf, strlen (buf) + 1);
- close (objfd);
- }
-
- __spe_context_update_event();
-
spe->base_private->entry = ld_info.entry;
spe->base_private->emulated_entry = ld_info.entry;
Index: libspe2/spebase/create.c
===================================================================
--- libspe2.orig/spebase/create.c
+++ libspe2/spebase/create.c
@@ -223,6 +223,7 @@ spe_context_ptr_t _base_spe_context_crea
priv->cntl_mmap_base = MAP_FAILED;
priv->signal1_mmap_base = MAP_FAILED;
priv->signal2_mmap_base = MAP_FAILED;
+ priv->loaded_program = NULL;
for (i = 0; i < NUM_MBOX_FDS; i++) {
priv->spe_fds_array[i] = -1;
Index: libspe2/spebase/run.c
===================================================================
--- libspe2.orig/spebase/run.c
+++ libspe2/spebase/run.c
@@ -306,7 +306,7 @@ do_run:
* and restart
*/
if (stopcode == SPE_PROGRAM_ISO_LOAD_COMPLETE) {
- __spe_context_update_event();
+ _base_spe_program_load_complete(spe);
goto do_run;
} else {
stopinfo->stop_reason = SPE_ISOLATION_ERROR;
Index: libspe2/spebase/spebase.h
===================================================================
--- libspe2.orig/spebase/spebase.h
+++ libspe2/spebase/spebase.h
@@ -92,6 +92,12 @@ struct spe_context_base_priv {
/* SPE program entry point generated by elf_load() */
int entry;
+ /* pointer to the program loaded/being loaded to the SPE. We need to
+ * store this to allow deferred updates to gdb, when loading is
+ * asynchronous (ie, isolated load, which is performed by the SPE).
+ */
+ spe_program_handle_t *loaded_program;
+
/* We need to keep the entry point for emulated isolated contexts,
* and ignore the value provided to spe_context_run */
int emulated_entry;
@@ -188,6 +194,17 @@ extern spe_gang_context_ptr_t _base_spe_
extern int _base_spe_program_load(spe_context_ptr_t spectx, spe_program_handle_t *program);
/**
+ * Signal that the program load has completed. For normal apps, this is called
+ * directly in the load path. For (emulated) isolated apps, the load is
+ * asynchronous, so this needs to be called when we know that the load has
+ * completed
+ *
+ * @pre spe->base_priv->loaded_program is a valid SPE program
+ * @param spectx The spe context that has been loaded.
+ */
+void _base_spe_program_load_complete(spe_context_ptr_t spectx);
+
+/**
* Check if the emulated loader is present in the filesystem
* @return Non-zero if the loader is available, otherwise zero.
*/
More information about the cbe-oss-dev
mailing list