spebase.h File Reference

#include <pthread.h>
#include "libspe2-types.h"
Include dependency graph for spebase.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  spe_context_base_priv
struct  spe_gang_context_base_priv

Defines

#define __PRINTF(fmt, args...)   { fprintf(stderr,fmt , ## args); }
#define DEBUG_PRINTF(fmt, args...)
#define LS_SIZE   0x40000
#define PSMAP_SIZE   0x20000
#define MFC_SIZE   0x1000
#define MSS_SIZE   0x1000
#define CNTL_SIZE   0x1000
#define SIGNAL_SIZE   0x1000
#define MSSYNC_OFFSET   0x00000
#define MFC_OFFSET   0x03000
#define CNTL_OFFSET   0x04000
#define SIGNAL1_OFFSET   0x14000
#define SIGNAL2_OFFSET   0x1c000
#define SPE_EMULATE_PARAM_BUFFER   0x3e000
#define SPE_PROGRAM_NORMAL_END   0x2000
#define SPE_PROGRAM_LIBRARY_CALL   0x2100
#define SPE_PROGRAM_ISOLATED_STOP   0x2200
#define SPE_PROGRAM_ISO_LOAD_COMPLETE   0x2206

Enumerations

enum  fd_name {
  FD_MBOX, FD_MBOX_STAT, FD_IBOX, FD_IBOX_NB,
  FD_IBOX_STAT, FD_WBOX, FD_WBOX_NB, FD_WBOX_STAT,
  FD_SIG1, FD_SIG2, FD_MFC, FD_MSS,
  NUM_MBOX_FDS
}

Functions

spe_context_ptr_t _base_spe_context_create (unsigned int flags, spe_gang_context_ptr_t gctx, spe_context_ptr_t aff_spe)
spe_gang_context_ptr_t _base_spe_gang_context_create (unsigned int flags)
int _base_spe_program_load (spe_context_ptr_t spectx, spe_program_handle_t *program)
void _base_spe_program_load_complete (spe_context_ptr_t spectx)
int _base_spe_emulated_loader_present (void)
int _base_spe_context_destroy (spe_context_ptr_t spectx)
int _base_spe_gang_context_destroy (spe_gang_context_ptr_t gctx)
int _base_spe_context_run (spe_context_ptr_t spe, unsigned int *entry, unsigned int runflags, void *argp, void *envp, spe_stop_info_t *stopinfo)
int _base_spe_image_close (spe_program_handle_t *handle)
spe_program_handle_t_base_spe_image_open (const char *filename)
int _base_spe_mfcio_put (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int _base_spe_mfcio_putb (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int _base_spe_mfcio_putf (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int _base_spe_mfcio_get (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int _base_spe_mfcio_getb (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int _base_spe_mfcio_getf (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int _base_spe_out_mbox_read (spe_context_ptr_t spectx, unsigned int mbox_data[], int count)
int _base_spe_in_mbox_write (spe_context_ptr_t spectx, unsigned int mbox_data[], int count, int behavior_flag)
int _base_spe_in_mbox_status (spe_context_ptr_t spectx)
int _base_spe_out_mbox_status (spe_context_ptr_t spectx)
int _base_spe_out_intr_mbox_status (spe_context_ptr_t spectx)
int _base_spe_out_intr_mbox_read (spe_context_ptr_t spectx, unsigned int mbox_data[], int count, int behavior_flag)
int _base_spe_signal_write (spe_context_ptr_t spectx, unsigned int signal_reg, unsigned int data)
int _base_spe_callback_handler_register (void *handler, unsigned int callnum, unsigned int mode)
int _base_spe_callback_handler_deregister (unsigned int callnum)
void * _base_spe_callback_handler_query (unsigned int callnum)
int _base_spe_stop_reason_get (spe_context_ptr_t spectx)
int _base_spe_mfcio_tag_status_read (spe_context_ptr_t spectx, unsigned int mask, unsigned int behavior, unsigned int *tag_status)
int __base_spe_stop_event_source_get (spe_context_ptr_t spectx)
int __base_spe_stop_event_target_get (spe_context_ptr_t spectx)
int _base_spe_stop_status_get (spe_context_ptr_t spectx)
int __base_spe_event_source_acquire (struct spe_context *spectx, enum fd_name fdesc)
void __base_spe_event_source_release (struct spe_context *spectx, enum fd_name fdesc)
void * _base_spe_ps_area_get (struct spe_context *spectx, enum ps_area area)
int __base_spe_spe_dir_get (struct spe_context *spectx)
void * _base_spe_ls_area_get (struct spe_context *spectx)
int _base_spe_ls_size_get (spe_context_ptr_t spe)
void _base_spe_context_lock (spe_context_ptr_t spe, enum fd_name fd)
void _base_spe_context_unlock (spe_context_ptr_t spe, enum fd_name fd)
int _base_spe_cpu_info_get (int info_requested, int cpu_node)
void __spe_context_update_event (void)
int _base_spe_mssync_start (spe_context_ptr_t spectx)
int _base_spe_mssync_status (spe_context_ptr_t spectx)

Detailed Description

spebase.h contains the public API funtions

Definition in file spebase.h.


Define Documentation

#define __PRINTF ( fmt,
args...   )     { fprintf(stderr,fmt , ## args); }

Definition at line 34 of file spebase.h.

#define CNTL_OFFSET   0x04000

Definition at line 124 of file spebase.h.

Referenced by _base_spe_context_create().

#define CNTL_SIZE   0x1000

Definition at line 119 of file spebase.h.

Referenced by _base_spe_context_create().

#define DEBUG_PRINTF ( fmt,
args...   ) 

Definition at line 38 of file spebase.h.

#define LS_SIZE   0x40000

Definition at line 115 of file spebase.h.

#define MFC_OFFSET   0x03000

Definition at line 123 of file spebase.h.

Referenced by _base_spe_context_create().

#define MFC_SIZE   0x1000

Definition at line 117 of file spebase.h.

Referenced by _base_spe_context_create().

#define MSS_SIZE   0x1000

Definition at line 118 of file spebase.h.

Referenced by _base_spe_context_create().

#define MSSYNC_OFFSET   0x00000

Definition at line 122 of file spebase.h.

Referenced by _base_spe_context_create().

#define PSMAP_SIZE   0x20000

Definition at line 116 of file spebase.h.

Referenced by _base_spe_context_create().

#define SIGNAL1_OFFSET   0x14000

Definition at line 125 of file spebase.h.

Referenced by _base_spe_context_create().

#define SIGNAL2_OFFSET   0x1c000

Definition at line 126 of file spebase.h.

Referenced by _base_spe_context_create().

#define SIGNAL_SIZE   0x1000

Definition at line 120 of file spebase.h.

Referenced by _base_spe_context_create().

#define SPE_EMULATE_PARAM_BUFFER   0x3e000

Location of the PPE-assisted library call buffer for emulated isolation contexts.

Definition at line 132 of file spebase.h.

Referenced by _base_spe_handle_library_callback().

#define SPE_PROGRAM_ISO_LOAD_COMPLETE   0x2206

Definition at line 143 of file spebase.h.

Referenced by _base_spe_context_run().

#define SPE_PROGRAM_ISOLATED_STOP   0x2200

Isolated exit codes: 0x220x

Definition at line 142 of file spebase.h.

Referenced by _base_spe_context_run().

#define SPE_PROGRAM_LIBRARY_CALL   0x2100

Definition at line 137 of file spebase.h.

Referenced by _base_spe_context_run().

#define SPE_PROGRAM_NORMAL_END   0x2000

Definition at line 136 of file spebase.h.

Referenced by _base_spe_context_run().


Enumeration Type Documentation

enum fd_name

NOTE: NUM_MBOX_FDS must always be the last element in the enumeration

Enumerator:
FD_MBOX 
FD_MBOX_STAT 
FD_IBOX 
FD_IBOX_NB 
FD_IBOX_STAT 
FD_WBOX 
FD_WBOX_NB 
FD_WBOX_STAT 
FD_SIG1 
FD_SIG2 
FD_MFC 
FD_MSS 
NUM_MBOX_FDS 

Definition at line 42 of file spebase.h.

00042              {
00043         FD_MBOX,
00044         FD_MBOX_STAT,
00045         FD_IBOX,
00046         FD_IBOX_NB,
00047         FD_IBOX_STAT,
00048         FD_WBOX,
00049         FD_WBOX_NB,
00050         FD_WBOX_STAT,
00051         FD_SIG1,
00052         FD_SIG2,
00053         FD_MFC,
00054         FD_MSS,
00055         NUM_MBOX_FDS
00056 };


Function Documentation

int __base_spe_event_source_acquire ( struct spe_context spectx,
enum fd_name  fdesc 
)

__base_spe_event_source_acquire opens a file descriptor to the specified event source

Parameters:
spectx Specifies the SPE context
fdesc Specifies the event source
void __base_spe_event_source_release ( struct spe_context spectx,
enum fd_name  fdesc 
)

__base_spe_event_source_release releases the file descriptor to the specified event source

Parameters:
spectx Specifies the SPE context
fdesc Specifies the event source

Definition at line 79 of file accessors.c.

References _base_spe_close_if_open().

00080 {
00081         _base_spe_close_if_open(spe, fdesc);
00082 }

Here is the call graph for this function:

int __base_spe_spe_dir_get ( struct spe_context spectx  ) 

__base_spe_spe_dir_get return the file descriptor of the SPE directory in spufs

Parameters:
spectx Specifies the SPE context
int __base_spe_stop_event_source_get ( spe_context_ptr_t  spe  ) 

__base_spe_stop_event_source_get

Parameters:
spectx Specifies the SPE context

speevent users read from this end

Definition at line 92 of file accessors.c.

References spe_context::base_private, and spe_context_base_priv::ev_pipe.

00093 {
00094         return spe->base_private->ev_pipe[1];
00095 }

int __base_spe_stop_event_target_get ( spe_context_ptr_t  spe  ) 

__base_spe_stop_event_target_get

Parameters:
spectx Specifies the SPE context

speevent writes to this end

Definition at line 100 of file accessors.c.

References spe_context::base_private, and spe_context_base_priv::ev_pipe.

00101 {
00102         return spe->base_private->ev_pipe[0];
00103 }

void __spe_context_update_event ( void   ) 

__spe_context_update_event internal function for gdb notification.

Referenced by _base_spe_context_destroy(), and _base_spe_program_load_complete().

int _base_spe_callback_handler_deregister ( unsigned int  callnum  ) 

unregister a handler function for the specified number NOTE: unregistering a handler from call zero and one is ignored.

Definition at line 78 of file lib_builtin.c.

References MAX_CALLNUM, and RESERVED.

00079 {
00080         errno = 0;
00081         if (callnum > MAX_CALLNUM) {
00082                 errno = EINVAL;
00083                 return -1;
00084         }
00085         if (callnum < RESERVED) {
00086                 errno = EACCES;
00087                 return -1;
00088         }
00089         if (handlers[callnum] == NULL) {
00090                 errno = ESRCH;
00091                 return -1;
00092         }
00093 
00094         handlers[callnum] = NULL;
00095         return 0;
00096 }

void* _base_spe_callback_handler_query ( unsigned int  callnum  ) 

query a handler function for the specified number

Definition at line 98 of file lib_builtin.c.

References MAX_CALLNUM.

00099 {
00100         errno = 0;
00101 
00102         if (callnum > MAX_CALLNUM) {
00103                 errno = EINVAL;
00104                 return NULL;
00105         }
00106         if (handlers[callnum] == NULL) {
00107                 errno = ESRCH;
00108                 return NULL;
00109         }
00110         return handlers[callnum];
00111 }

int _base_spe_callback_handler_register ( void *  handler,
unsigned int  callnum,
unsigned int  mode 
)

register a handler function for the specified number NOTE: registering a handler to call zero and one is ignored.

Definition at line 40 of file lib_builtin.c.

References MAX_CALLNUM, RESERVED, SPE_CALLBACK_NEW, and SPE_CALLBACK_UPDATE.

00041 {
00042         errno = 0;
00043 
00044         if (callnum > MAX_CALLNUM) {
00045                 errno = EINVAL;
00046                 return -1;
00047         }
00048         
00049         switch(mode){
00050         case SPE_CALLBACK_NEW:
00051                 if (callnum < RESERVED) {
00052                         errno = EACCES;
00053                         return -1;
00054                 }
00055                 if (handlers[callnum] != NULL) {
00056                         errno = EACCES;
00057                         return -1;
00058                 }
00059                 handlers[callnum] = handler;
00060                 break;
00061 
00062         case SPE_CALLBACK_UPDATE:
00063                 if (handlers[callnum] == NULL) {
00064                         errno = ESRCH;
00065                         return -1;
00066                 }
00067                 handlers[callnum] = handler;
00068                 break;
00069         default:
00070                 errno = EINVAL;
00071                 return -1;
00072                 break;
00073         }
00074         return 0;
00075 
00076 }

spe_context_ptr_t _base_spe_context_create ( unsigned int  flags,
spe_gang_context_ptr_t  gctx,
spe_context_ptr_t  aff_spe 
)

_base_spe_context_create creates a single SPE context, i.e., the corresponding directory is created in SPUFS either as a subdirectory of a gang or individually (maybe this is best considered a gang of one)

Parameters:
flags 
gctx specify NULL if not belonging to a gang
aff_spe specify NULL to skip affinity information

Definition at line 183 of file create.c.

References _base_spe_emulated_loader_present(), spe_gang_context::base_private, spe_context::base_private, spe_context_base_priv::cntl_mmap_base, CNTL_OFFSET, CNTL_SIZE, DEBUG_PRINTF, spe_context_base_priv::fd_lock, spe_context_base_priv::fd_spe_dir, spe_context_base_priv::flags, spe_gang_context_base_priv::gangname, spe_context_base_priv::loaded_program, LS_SIZE, spe_context_base_priv::mem_mmap_base, spe_context_base_priv::mfc_mmap_base, MFC_OFFSET, MFC_SIZE, MSS_SIZE, spe_context_base_priv::mssync_mmap_base, MSSYNC_OFFSET, spe_context_base_priv::psmap_mmap_base, PSMAP_SIZE, spe_context_base_priv::signal1_mmap_base, SIGNAL1_OFFSET, spe_context_base_priv::signal2_mmap_base, SIGNAL2_OFFSET, SIGNAL_SIZE, SPE_AFFINITY_MEMORY, SPE_CFG_SIGNOTIFY1_OR, SPE_CFG_SIGNOTIFY2_OR, SPE_EVENTS_ENABLE, spe_context_base_priv::spe_fds_array, SPE_ISOLATE, SPE_ISOLATE_EMULATE, and SPE_MAP_PS.

00185 {
00186         char pathname[256];
00187         int i, aff_spe_fd = 0;
00188         unsigned int spu_createflags = 0;
00189         struct spe_context *spe = NULL;
00190         struct spe_context_base_priv *priv;
00191 
00192         /* We need a loader present to run in emulated isolated mode */
00193         if (flags & SPE_ISOLATE_EMULATE
00194                         && !_base_spe_emulated_loader_present()) {
00195                 errno = EINVAL;
00196                 return NULL;
00197         }
00198 
00199         /* Put some sane defaults into the SPE context */
00200         spe = malloc(sizeof(*spe));
00201         if (!spe) {
00202                 DEBUG_PRINTF("ERROR: Could not allocate spe context.\n");
00203                 return NULL;
00204         }
00205         memset(spe, 0, sizeof(*spe));
00206 
00207         spe->base_private = malloc(sizeof(*spe->base_private));
00208         if (!spe->base_private) {
00209                 DEBUG_PRINTF("ERROR: Could not allocate "
00210                                 "spe->base_private context.\n");
00211                 free(spe);
00212                 return NULL;
00213         }
00214 
00215         /* just a convenience variable */
00216         priv = spe->base_private;
00217 
00218         priv->fd_spe_dir = -1;
00219         priv->mem_mmap_base = MAP_FAILED;
00220         priv->psmap_mmap_base = MAP_FAILED;
00221         priv->mssync_mmap_base = MAP_FAILED;
00222         priv->mfc_mmap_base = MAP_FAILED;
00223         priv->cntl_mmap_base = MAP_FAILED;
00224         priv->signal1_mmap_base = MAP_FAILED;
00225         priv->signal2_mmap_base = MAP_FAILED;
00226         priv->loaded_program = NULL;
00227 
00228         for (i = 0; i < NUM_MBOX_FDS; i++) {
00229                 priv->spe_fds_array[i] = -1;
00230                 pthread_mutex_init(&priv->fd_lock[i], NULL);
00231         }
00232 
00233         /* initialise spu_createflags */
00234         if (flags & SPE_ISOLATE) {
00235                 flags |= SPE_MAP_PS;
00236                 spu_createflags |= SPU_CREATE_ISOLATE | SPU_CREATE_NOSCHED;
00237         }
00238 
00239         if (flags & SPE_EVENTS_ENABLE)
00240                 spu_createflags |= SPU_CREATE_EVENTS_ENABLED;
00241 
00242         if (aff_spe)
00243                 spu_createflags |= SPU_CREATE_AFFINITY_SPU;
00244 
00245         if (flags & SPE_AFFINITY_MEMORY)
00246                 spu_createflags |= SPU_CREATE_AFFINITY_MEM;
00247 
00248         /* Make the SPUFS directory for the SPE */
00249         if (gctx == NULL)
00250                 sprintf(pathname, "/spu/spethread-%i-%lu",
00251                         getpid(), (unsigned long)spe);
00252         else
00253                 sprintf(pathname, "/spu/%s/spethread-%i-%lu",
00254                         gctx->base_private->gangname, getpid(),
00255                         (unsigned long)spe);
00256 
00257         if (aff_spe)
00258                 aff_spe_fd = aff_spe->base_private->fd_spe_dir;
00259 
00260         priv->fd_spe_dir = spu_create(pathname, spu_createflags,
00261                         S_IRUSR | S_IWUSR | S_IXUSR, aff_spe_fd);
00262 
00263         if (priv->fd_spe_dir < 0) {
00264                 int errno_saved = errno; /* save errno to prevent being overwritten */
00265                 DEBUG_PRINTF("ERROR: Could not create SPE %s\n", pathname);
00266                 perror("spu_create()");
00267                 free_spe_context(spe);
00268                 /* we mask most errors, but leave ENODEV, etc */
00269                 switch (errno_saved) {
00270                 case ENOTSUP:
00271                 case EEXIST:
00272                 case EINVAL:
00273                 case EBUSY:
00274                 case EPERM:
00275                 case ENODEV:
00276                         errno = errno_saved; /* restore errno */
00277                         break;
00278                 default:
00279                         errno = EFAULT;
00280                         break;
00281                 }
00282                 return NULL;
00283         }
00284 
00285         priv->flags = flags;
00286 
00287         /* Map the required areas into process memory */
00288         priv->mem_mmap_base = mapfileat(priv->fd_spe_dir, "mem", LS_SIZE);
00289         if (priv->mem_mmap_base == MAP_FAILED) {
00290                 DEBUG_PRINTF("ERROR: Could not map SPE memory.\n");
00291                 free_spe_context(spe);
00292                 errno = ENOMEM;
00293                 return NULL;
00294         }
00295 
00296         if (flags & SPE_MAP_PS) {
00297                 /* It's possible to map the entire problem state area with
00298                  * one mmap - try this first */
00299                 priv->psmap_mmap_base =  mapfileat(priv->fd_spe_dir,
00300                                 "psmap", PSMAP_SIZE);
00301 
00302                 if (priv->psmap_mmap_base != MAP_FAILED) {
00303                         priv->mssync_mmap_base =
00304                                 priv->psmap_mmap_base + MSSYNC_OFFSET;
00305                         priv->mfc_mmap_base =
00306                                 priv->psmap_mmap_base + MFC_OFFSET;
00307                         priv->cntl_mmap_base =
00308                                 priv->psmap_mmap_base + CNTL_OFFSET;
00309                         priv->signal1_mmap_base =
00310                                 priv->psmap_mmap_base + SIGNAL1_OFFSET;
00311                         priv->signal2_mmap_base =
00312                                 priv->psmap_mmap_base + SIGNAL2_OFFSET;
00313 
00314                 } else {
00315                         /* map each region separately */
00316                         priv->mfc_mmap_base =
00317                                 mapfileat(priv->fd_spe_dir, "mfc", MFC_SIZE);
00318                         priv->mssync_mmap_base =
00319                                 mapfileat(priv->fd_spe_dir, "mss", MSS_SIZE);
00320                         priv->cntl_mmap_base =
00321                                 mapfileat(priv->fd_spe_dir, "cntl", CNTL_SIZE);
00322                         priv->signal1_mmap_base =
00323                                 mapfileat(priv->fd_spe_dir, "signal1",
00324                                                 SIGNAL_SIZE);
00325                         priv->signal2_mmap_base =
00326                                 mapfileat(priv->fd_spe_dir, "signal2",
00327                                                 SIGNAL_SIZE);
00328 
00329                         if (priv->mfc_mmap_base == MAP_FAILED ||
00330                                         priv->cntl_mmap_base == MAP_FAILED ||
00331                                         priv->signal1_mmap_base == MAP_FAILED ||
00332                                         priv->signal2_mmap_base == MAP_FAILED) {
00333                                 DEBUG_PRINTF("ERROR: Could not map SPE "
00334                                                 "PS memory.\n");
00335                                 free_spe_context(spe);
00336                                 errno = ENOMEM;
00337                                 return NULL;
00338                         }
00339                 }
00340         }
00341 
00342         if (flags & SPE_CFG_SIGNOTIFY1_OR) {
00343                 if (setsignotify(priv->fd_spe_dir, "signal1_type")) {
00344                         DEBUG_PRINTF("ERROR: Could not open SPE "
00345                                         "signal1_type file.\n");
00346                         free_spe_context(spe);
00347                         errno = EFAULT;
00348                         return NULL;
00349                 }
00350         }
00351 
00352         if (flags & SPE_CFG_SIGNOTIFY2_OR) {
00353                 if (setsignotify(priv->fd_spe_dir, "signal2_type")) {
00354                         DEBUG_PRINTF("ERROR: Could not open SPE "
00355                                         "signal2_type file.\n");
00356                         free_spe_context(spe);
00357                         errno = EFAULT;
00358                         return NULL;
00359                 }
00360         }
00361 
00362         return spe;
00363 }

Here is the call graph for this function:

int _base_spe_context_destroy ( spe_context_ptr_t  spectx  ) 

_base_spe_context_destroy cleans up what is left when an SPE executable has exited. Closes open file handles and unmaps memory areas.

Parameters:
spectx Specifies the SPE context

Definition at line 418 of file create.c.

References __spe_context_update_event().

00419 {
00420         int ret = free_spe_context(spe);
00421 
00422         __spe_context_update_event();
00423 
00424         return ret;
00425 }

Here is the call graph for this function:

void _base_spe_context_lock ( spe_context_ptr_t  spe,
enum fd_name  fd 
)

_base_spe_context_lock locks members of the SPE context

Parameters:
spectx Specifies the SPE context
fd Specifies the file

Definition at line 91 of file create.c.

References spe_context::base_private, and spe_context_base_priv::fd_lock.

Referenced by _base_spe_close_if_open(), and _base_spe_open_if_closed().

00092 {
00093         pthread_mutex_lock(&spe->base_private->fd_lock[fdesc]);
00094 }

int _base_spe_context_run ( spe_context_ptr_t  spe,
unsigned int *  entry,
unsigned int  runflags,
void *  argp,
void *  envp,
spe_stop_info_t stopinfo 
)

_base_spe_context_run starts execution of an SPE context with a loaded image

Parameters:
spectx Specifies the SPE context
entry entry point for the SPE programm. If set to 0, entry point is determined by the ELF loader.
runflags valid values are:
SPE_RUN_USER_REGS Specifies that the SPE setup registers r3, r4, and r5 are initialized with the 48 bytes pointed to by argp.
SPE_NO_CALLBACKS do not use built in library functions.
argp An (optional) pointer to application specific data, and is passed as the second parameter to the SPE program.
envp An (optional) pointer to environment specific data, and is passed as the third parameter to the SPE program.

Definition at line 99 of file run.c.

References __spe_current_active_context, _base_spe_handle_library_callback(), _base_spe_program_load_complete(), spe_context::base_private, DEBUG_PRINTF, spe_context_base_priv::emulated_entry, spe_context_base_priv::entry, spe_context_base_priv::fd_spe_dir, spe_context_base_priv::flags, LS_SIZE, spe_context_base_priv::mem_mmap_base, spe_context_info::npc, spe_context_info::prev, spe_stop_info::result, spe_stop_info::spe_callback_error, SPE_CALLBACK_ERROR, SPE_DEFAULT_ENTRY, SPE_EVENTS_ENABLE, SPE_EXIT, spe_stop_info::spe_exit_code, spe_context_info::spe_id, SPE_ISOLATE, SPE_ISOLATE_EMULATE, spe_stop_info::spe_isolation_error, SPE_ISOLATION_ERROR, SPE_NO_CALLBACKS, SPE_PROGRAM_ISO_LOAD_COMPLETE, SPE_PROGRAM_ISOLATED_STOP, SPE_PROGRAM_LIBRARY_CALL, SPE_PROGRAM_NORMAL_END, SPE_RUN_USER_REGS, spe_stop_info::spe_runtime_error, SPE_RUNTIME_ERROR, spe_stop_info::spe_runtime_exception, SPE_RUNTIME_EXCEPTION, spe_stop_info::spe_runtime_fatal, SPE_RUNTIME_FATAL, spe_stop_info::spe_signal_code, SPE_SPU_HALT, SPE_SPU_INVALID_CHANNEL, SPE_SPU_INVALID_INSTR, SPE_SPU_STOPPED_BY_STOP, SPE_SPU_WAITING_ON_CHANNEL, SPE_STOP_AND_SIGNAL, spe_stop_info::spu_status, spe_context_info::status, spe_stop_info::stop_reason, addr64::ui, and addr64::ull.

Referenced by _event_spe_context_run().

00102 {
00103         int retval = 0, run_rc;
00104         unsigned int run_status, tmp_entry;
00105         spe_stop_info_t stopinfo_buf;
00106         struct spe_context_info this_context_info __attribute__((cleanup(cleanupspeinfo)));
00107 
00108         /* If the caller hasn't set a stopinfo buffer, provide a buffer on the
00109          * stack instead. */
00110         if (!stopinfo)
00111                 stopinfo = &stopinfo_buf;
00112 
00113 
00114         /* In emulated isolated mode, the npc will always return as zero.
00115          * use our private entry point instead */
00116         if (spe->base_private->flags & SPE_ISOLATE_EMULATE)
00117                 tmp_entry = spe->base_private->emulated_entry;
00118 
00119         else if (*entry == SPE_DEFAULT_ENTRY)
00120                 tmp_entry = spe->base_private->entry;
00121         else 
00122                 tmp_entry = *entry;
00123 
00124         /* If we're starting the SPE binary from its original entry point,
00125          * setup the arguments to main() */
00126         if (tmp_entry == spe->base_private->entry &&
00127                         !(spe->base_private->flags &
00128                                 (SPE_ISOLATE | SPE_ISOLATE_EMULATE))) {
00129 
00130                 addr64 argp64, envp64, tid64, ls64;
00131                 unsigned int regs[128][4];
00132 
00133                 /* setup parameters */
00134                 argp64.ull = (uint64_t)(unsigned long)argp;
00135                 envp64.ull = (uint64_t)(unsigned long)envp;
00136                 tid64.ull = (uint64_t)(unsigned long)spe;
00137 
00138                 /* make sure the register values are 0 */
00139                 memset(regs, 0, sizeof(regs));
00140 
00141                 /* set sensible values for stack_ptr and stack_size */
00142                 regs[1][0] = (unsigned int) LS_SIZE - 16;       /* stack_ptr */
00143                 regs[2][0] = 0;                                                         /* stack_size ( 0 = default ) */
00144 
00145                 if (runflags & SPE_RUN_USER_REGS) {
00146                         /* When SPE_USER_REGS is set, argp points to an array
00147                          * of 3x128b registers to be passed directly to the SPE
00148                          * program.
00149                          */
00150                         memcpy(regs[3], argp, sizeof(unsigned int) * 12);
00151                 } else {
00152                         regs[3][0] = tid64.ui[0];
00153                         regs[3][1] = tid64.ui[1];
00154 
00155                         regs[4][0] = argp64.ui[0];
00156                         regs[4][1] = argp64.ui[1];
00157 
00158                         regs[5][0] = envp64.ui[0];
00159                         regs[5][1] = envp64.ui[1];
00160                 }
00161                 
00162                 /* Store the LS base address in R6 */
00163                 ls64.ull = (uint64_t)(unsigned long)spe->base_private->mem_mmap_base;
00164                 regs[6][0] = ls64.ui[0];
00165                 regs[6][1] = ls64.ui[1];
00166 
00167                 if (set_regs(spe, regs))
00168                         return -1;
00169         }
00170 
00171         /*Leave a trail of breadcrumbs for the debugger to follow */
00172         if (!__spe_current_active_context) {
00173                 __spe_current_active_context = &this_context_info;
00174                 if (!__spe_current_active_context)
00175                         return -1;
00176                 __spe_current_active_context->prev = NULL;
00177         } else {
00178                 struct spe_context_info *newinfo;
00179                 newinfo = &this_context_info;
00180                 if (!newinfo)
00181                         return -1;
00182                 newinfo->prev = __spe_current_active_context;
00183                 __spe_current_active_context = newinfo;
00184         }
00185         /*remember the ls-addr*/
00186         __spe_current_active_context->spe_id = spe->base_private->fd_spe_dir;
00187 
00188 do_run:
00189         /*Remember the npc value*/
00190         __spe_current_active_context->npc = tmp_entry;
00191 
00192         /* run SPE context */
00193         run_rc = spu_run(spe->base_private->fd_spe_dir,
00194                         &tmp_entry, &run_status);
00195 
00196         /*Remember the npc value*/
00197         __spe_current_active_context->npc = tmp_entry;
00198         __spe_current_active_context->status = run_status;
00199 
00200         DEBUG_PRINTF("spu_run returned run_rc=0x%08x, entry=0x%04x, "
00201                         "ext_status=0x%04x.\n", run_rc, tmp_entry, run_status);
00202 
00203         /* set up return values and stopinfo according to spu_run exit
00204          * conditions. This is overwritten on error.
00205          */
00206         stopinfo->spu_status = run_rc;
00207 
00208         if (spe->base_private->flags & SPE_ISOLATE_EMULATE) {
00209                 /* save the entry point, and pretend that the npc is zero */
00210                 spe->base_private->emulated_entry = tmp_entry;
00211                 *entry = 0;
00212         } else {
00213                 *entry = tmp_entry;
00214         }
00215 
00216         /* Return with stopinfo set on syscall error paths */
00217         if (run_rc == -1) {
00218                 DEBUG_PRINTF("spu_run returned error %d, errno=%d\n",
00219                                 run_rc, errno);
00220                 stopinfo->stop_reason = SPE_RUNTIME_FATAL;
00221                 stopinfo->result.spe_runtime_fatal = errno;
00222                 retval = -1;
00223 
00224                 /* For isolated contexts, pass EPERM up to the
00225                  * caller.
00226                  */
00227                 if (!(spe->base_private->flags & SPE_ISOLATE
00228                                 && errno == EPERM))
00229                         errno = EFAULT;
00230 
00231         } else if (run_rc & SPE_SPU_INVALID_INSTR) {
00232                 DEBUG_PRINTF("SPU has tried to execute an invalid "
00233                                 "instruction. %d\n", run_rc);
00234                 stopinfo->stop_reason = SPE_RUNTIME_ERROR;
00235                 stopinfo->result.spe_runtime_error = SPE_SPU_INVALID_INSTR;
00236                 errno = EFAULT;
00237                 retval = -1;
00238 
00239         } else if ((spe->base_private->flags & SPE_EVENTS_ENABLE) && run_status) {
00240                 /* Report asynchronous error if return val are set and
00241                  * SPU events are enabled.
00242                  */
00243                 stopinfo->stop_reason = SPE_RUNTIME_EXCEPTION;
00244                 stopinfo->result.spe_runtime_exception = run_status;
00245                 stopinfo->spu_status = -1;
00246                 errno = EIO;
00247                 retval = -1;
00248 
00249         } else if (run_rc & SPE_SPU_STOPPED_BY_STOP) {
00250                 /* Stop & signals are broken down into three groups
00251                  *  1. SPE library call
00252                  *  2. SPE user defined stop & signal
00253                  *  3. SPE program end.
00254                  *
00255                  * These groups are signified by the 14-bit stop code:
00256                  */
00257                 int stopcode = (run_rc >> 16) & 0x3fff;
00258 
00259                 /* Check if this is a library callback, and callbacks are
00260                  * allowed (ie, running without SPE_NO_CALLBACKS)
00261                  */
00262                 if ((stopcode & 0xff00) == SPE_PROGRAM_LIBRARY_CALL
00263                                 && !(runflags & SPE_NO_CALLBACKS)) {
00264 
00265                         int callback_rc, callback_number = stopcode & 0xff;
00266 
00267                         /* execute library callback */
00268                         DEBUG_PRINTF("SPE library call: %d\n", callback_number);
00269                         callback_rc = _base_spe_handle_library_callback(spe,
00270                                                                         callback_number, *entry);
00271 
00272                         if (callback_rc) {
00273                                 /* library callback failed; set errno and
00274                                  * return immediately */
00275                                 DEBUG_PRINTF("SPE library call failed: %d\n",
00276                                                 callback_rc);
00277                                 stopinfo->stop_reason = SPE_CALLBACK_ERROR;
00278                                 stopinfo->result.spe_callback_error =
00279                                         callback_rc;
00280                                 errno = EFAULT;
00281                                 retval = -1;
00282                         } else {
00283                                 /* successful library callback - restart the SPE
00284                                  * program at the next instruction */
00285                                 tmp_entry += 4;
00286                                 goto do_run;
00287                         }
00288 
00289                 } else if ((stopcode & 0xff00) == SPE_PROGRAM_NORMAL_END) {
00290                         /* The SPE program has exited by exit(X) */
00291                         stopinfo->stop_reason = SPE_EXIT;
00292                         stopinfo->result.spe_exit_code = stopcode & 0xff;
00293 
00294                         if (spe->base_private->flags & SPE_ISOLATE) {
00295                                 /* Issue an isolated exit, and re-run the SPE.
00296                                  * We should see a return value without the
00297                                  * 0x80 bit set. */
00298                                 if (!issue_isolated_exit(spe))
00299                                         goto do_run;
00300                                 retval = -1;
00301                         }
00302 
00303                 } else if ((stopcode & 0xfff0) == SPE_PROGRAM_ISOLATED_STOP) {
00304 
00305                         /* 0x2206: isolated app has been loaded by loader;
00306                          * provide a hook for the debugger to catch this,
00307                          * and restart
00308                          */
00309                         if (stopcode == SPE_PROGRAM_ISO_LOAD_COMPLETE) {
00310                                 _base_spe_program_load_complete(spe);
00311                                 goto do_run;
00312                         } else {
00313                                 stopinfo->stop_reason = SPE_ISOLATION_ERROR;
00314                                 stopinfo->result.spe_isolation_error =
00315                                         stopcode & 0xf;
00316                         }
00317 
00318                 } else if (spe->base_private->flags & SPE_ISOLATE &&
00319                                 !(run_rc & 0x80)) {
00320                         /* We've successfully exited isolated mode */
00321                         retval = 0;
00322 
00323                 } else {
00324                         /* User defined stop & signal, including
00325                          * callbacks when disabled */
00326                         stopinfo->stop_reason = SPE_STOP_AND_SIGNAL;
00327                         stopinfo->result.spe_signal_code = stopcode;
00328                         retval = stopcode;
00329                 }
00330 
00331         } else if (run_rc & SPE_SPU_HALT) {
00332                 DEBUG_PRINTF("SPU was stopped by halt. %d\n", run_rc);
00333                 stopinfo->stop_reason = SPE_RUNTIME_ERROR;
00334                 stopinfo->result.spe_runtime_error = SPE_SPU_HALT;
00335                 errno = EFAULT;
00336                 retval = -1;
00337 
00338         } else if (run_rc & SPE_SPU_WAITING_ON_CHANNEL) {
00339                 DEBUG_PRINTF("SPU is waiting on channel. %d\n", run_rc);
00340                 stopinfo->stop_reason = SPE_RUNTIME_EXCEPTION;
00341                 stopinfo->result.spe_runtime_exception = run_status;
00342                 stopinfo->spu_status = -1;
00343                 errno = EIO;
00344                 retval = -1;
00345 
00346         } else if (run_rc & SPE_SPU_INVALID_CHANNEL) {
00347                 DEBUG_PRINTF("SPU has tried to access an invalid "
00348                                 "channel. %d\n", run_rc);
00349                 stopinfo->stop_reason = SPE_RUNTIME_ERROR;
00350                 stopinfo->result.spe_runtime_error = SPE_SPU_INVALID_CHANNEL;
00351                 errno = EFAULT;
00352                 retval = -1;
00353 
00354         } else {
00355                 DEBUG_PRINTF("spu_run returned invalid data: 0x%04x\n", run_rc);
00356                 stopinfo->stop_reason = SPE_RUNTIME_FATAL;
00357                 stopinfo->result.spe_runtime_fatal = -1;
00358                 stopinfo->spu_status = -1;
00359                 errno = EFAULT;
00360                 retval = -1;
00361 
00362         }
00363 
00364         freespeinfo();
00365         return retval;
00366 }

Here is the call graph for this function:

void _base_spe_context_unlock ( spe_context_ptr_t  spe,
enum fd_name  fd 
)

_base_spe_context_unlock unlocks members of the SPE context

Parameters:
spectx Specifies the SPE context
fd Specifies the file

Definition at line 96 of file create.c.

References spe_context::base_private, and spe_context_base_priv::fd_lock.

Referenced by _base_spe_close_if_open(), and _base_spe_open_if_closed().

00097 {
00098         pthread_mutex_unlock(&spe->base_private->fd_lock[fdesc]);
00099 }

int _base_spe_cpu_info_get ( int  info_requested,
int  cpu_node 
)

_base_spe_info_get

Definition at line 105 of file info.c.

References _base_spe_count_physical_cpus(), _base_spe_count_physical_spes(), _base_spe_count_usable_spes(), SPE_COUNT_PHYSICAL_CPU_NODES, SPE_COUNT_PHYSICAL_SPES, and SPE_COUNT_USABLE_SPES.

00105                                                              {
00106         int ret = 0;
00107         errno = 0;
00108         
00109         switch (info_requested) {
00110         case  SPE_COUNT_PHYSICAL_CPU_NODES:
00111                 ret = _base_spe_count_physical_cpus(cpu_node);
00112                 break;
00113         case SPE_COUNT_PHYSICAL_SPES:
00114                 ret = _base_spe_count_physical_spes(cpu_node);
00115                 break;
00116         case SPE_COUNT_USABLE_SPES:
00117                 ret = _base_spe_count_usable_spes(cpu_node);
00118                 break;
00119         default:
00120                 errno = EINVAL;
00121                 ret = -1;
00122         }
00123         return ret;
00124 }

Here is the call graph for this function:

int _base_spe_emulated_loader_present ( void   ) 

Check if the emulated loader is present in the filesystem

Returns:
Non-zero if the loader is available, otherwise zero.

Definition at line 159 of file load.c.

References _base_spe_verify_spe_elf_image().

Referenced by _base_spe_context_create().

00160 {
00161         spe_program_handle_t *loader = emulated_loader_program();
00162 
00163         if (!loader)
00164                 return 0;
00165 
00166         return !_base_spe_verify_spe_elf_image(loader);
00167 }

Here is the call graph for this function:

spe_gang_context_ptr_t _base_spe_gang_context_create ( unsigned int  flags  ) 

creates the directory in SPUFS that will contain all SPEs that are considered a gang Note: I would like to generalize this to a "group" or "set" Additional attributes maintained at the group level should be used to define scheduling constraints such "temporal" (e.g., scheduled all at the same time, i.e., a gang) "topology" (e.g., "closeness" of SPEs for optimal communication)

Definition at line 376 of file create.c.

References spe_gang_context::base_private, DEBUG_PRINTF, and spe_gang_context_base_priv::gangname.

00377 {
00378         char pathname[256];
00379         struct spe_gang_context_base_priv *pgctx = NULL;
00380         struct spe_gang_context *gctx = NULL;
00381 
00382         gctx = malloc(sizeof(*gctx));
00383         if (!gctx) {
00384                 DEBUG_PRINTF("ERROR: Could not allocate spe context.\n");
00385                 return NULL;
00386         }
00387         memset(gctx, 0, sizeof(*gctx));
00388 
00389         pgctx = malloc(sizeof(*pgctx));
00390         if (!pgctx) {
00391                 DEBUG_PRINTF("ERROR: Could not allocate spe context.\n");
00392                 free(gctx);
00393                 return NULL;
00394         }
00395         memset(pgctx, 0, sizeof(*pgctx));
00396 
00397         gctx->base_private = pgctx;
00398 
00399         sprintf(gctx->base_private->gangname, "gang-%i-%lu", getpid(),
00400                         (unsigned long)gctx);
00401         sprintf(pathname, "/spu/%s", gctx->base_private->gangname);
00402 
00403         gctx->base_private->fd_gang_dir = spu_create(pathname, SPU_CREATE_GANG,
00404                                 S_IRUSR | S_IWUSR | S_IXUSR);
00405 
00406         if (gctx->base_private->fd_gang_dir < 0) {
00407                 DEBUG_PRINTF("ERROR: Could not create Gang %s\n", pathname);
00408                 free_spe_gang_context(gctx);
00409                 errno = EFAULT;
00410                 return NULL;
00411         }
00412 
00413         gctx->base_private->flags = flags;
00414 
00415         return gctx;
00416 }

int _base_spe_gang_context_destroy ( spe_gang_context_ptr_t  gctx  ) 

_base_spe_gang_context_destroy destroys a gang context and frees associated resources

Parameters:
gctx Specifies the SPE gang context

Definition at line 427 of file create.c.

00428 {
00429         return free_spe_gang_context(gctx);
00430 }

int _base_spe_image_close ( spe_program_handle_t handle  ) 

_base_spe_image_close unmaps an SPE ELF object that was previously mapped using spe_open_image.

Parameters:
handle handle to open file
Return values:
0 On success, spe_close_image returns 0.
-1 On failure, -1 is returned and errno is set appropriately.
Possible values for errno:
EINVAL From spe_close_image, this indicates that the file, specified by filename, was not previously mapped by a call to spe_open_image.

Definition at line 96 of file image.c.

References spe_program_handle::elf_image, image_handle::map_size, image_handle::speh, and spe_program_handle::toe_shadow.

00097 {
00098         int ret = 0;
00099         struct image_handle *ih;
00100 
00101         if (!handle) {
00102                 errno = EINVAL;
00103                 return -1;
00104         }
00105         
00106         ih = (struct image_handle *)handle;
00107 
00108         if (!ih->speh.elf_image || !ih->map_size) {
00109                 errno = EINVAL;
00110                 return -1;
00111         }
00112 
00113         if (ih->speh.toe_shadow)
00114                 free(ih->speh.toe_shadow);
00115 
00116         ret = munmap(ih->speh.elf_image, ih->map_size );
00117         free(handle);
00118 
00119         return ret;
00120 }

spe_program_handle_t* _base_spe_image_open ( const char *  filename  ) 

_base_spe_image_open maps an SPE ELF executable indicated by filename into system memory and returns the mapped address appropriate for use by the spe_create_thread API. It is often more convenient/appropriate to use the loading methodologies where SPE ELF objects are converted to PPE static or shared libraries with symbols which point to the SPE ELF objects after these special libraries are loaded. These libraries are then linked with the associated PPE code to provide a direct symbol reference to the SPE ELF object. The symbols in this scheme are equivalent to the address returned from the spe_open_image function. SPE ELF objects loaded using this function are not shared with other processes, but SPE ELF objects loaded using the other scheme, mentioned above, can be shared if so desired.

Parameters:
filename Specifies the filename of an SPE ELF executable to be loaded and mapped into system memory.
Returns:
On success, spe_open_image returns the address at which the specified SPE ELF object has been mapped. On failure, NULL is returned and errno is set appropriately.
Possible values for errno include:
EACCES The calling process does not have permission to access the specified file.
EFAULT The filename parameter points to an address that was not contained in the calling process`s address space.

A number of other errno values could be returned by the open(2), fstat(2), mmap(2), munmap(2), or close(2) system calls which may be utilized by the spe_open_image or spe_close_image functions.

See also:
spe_create_thread

Definition at line 37 of file image.c.

References _base_spe_toe_ear(), _base_spe_verify_spe_elf_image(), spe_program_handle::elf_image, spe_program_handle::handle_size, image_handle::map_size, image_handle::speh, and spe_program_handle::toe_shadow.

00038 {
00039         /* allocate an extra integer in the spe handle to keep the mapped size information */
00040         struct image_handle *ret;
00041         int binfd = -1, f_stat;
00042         struct stat statbuf;
00043         size_t ps = getpagesize ();
00044 
00045         ret = malloc(sizeof(struct image_handle));
00046         if (!ret)
00047                 return NULL;
00048 
00049         ret->speh.handle_size = sizeof(spe_program_handle_t);
00050         ret->speh.toe_shadow = NULL;
00051 
00052         binfd = open(filename, O_RDONLY);
00053         if (binfd < 0)
00054                 goto ret_err;
00055 
00056         f_stat = fstat(binfd, &statbuf);
00057         if (f_stat < 0)
00058                 goto ret_err;
00059 
00060         /* Sanity: is it executable ?
00061          */
00062         if(!(statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
00063                 errno=EACCES;
00064                 goto ret_err;
00065         }
00066         
00067         /* now store the size at the extra allocated space */
00068         ret->map_size = (statbuf.st_size + ps - 1) & ~(ps - 1);
00069 
00070         ret->speh.elf_image = mmap(NULL, ret->map_size,
00071                                                         PROT_WRITE | PROT_READ,
00072                                                         MAP_PRIVATE, binfd, 0);
00073         if (ret->speh.elf_image == MAP_FAILED)
00074                 goto ret_err;
00075 
00076         /*Verify that this is a valid SPE ELF object*/
00077         if((_base_spe_verify_spe_elf_image((spe_program_handle_t *)ret)))
00078                 goto ret_err;
00079 
00080         if (_base_spe_toe_ear(&ret->speh))
00081                 goto ret_err;
00082 
00083         /* ok */
00084         close(binfd);
00085         return (spe_program_handle_t *)ret;
00086 
00087         /* err & cleanup */
00088 ret_err:
00089         if (binfd >= 0)
00090                 close(binfd);
00091 
00092         free(ret);
00093         return NULL;
00094 }

Here is the call graph for this function:

int _base_spe_in_mbox_status ( spe_context_ptr_t  spectx  ) 

The _base_spe_in_mbox_status function fetches the status of the SPU inbound mailbox for the SPE thread specified by the speid parameter. A 0 value is return if the mailbox is full. A non-zero value specifies the number of available (32-bit) mailbox entries.

Parameters:
spectx Specifies the SPE context whose mailbox status is to be read.
Returns:
On success, returns the current status of the mailbox, respectively. On failure, -1 is returned.
See also:
spe_read_out_mbox, spe_write_in_mbox, read (2)

Definition at line 202 of file mbox.c.

References _base_spe_open_if_closed(), spe_context::base_private, spe_context_base_priv::cntl_mmap_base, FD_WBOX_STAT, spe_context_base_priv::flags, SPE_MAP_PS, and spe_spu_control_area::SPU_Mbox_Stat.

00203 {
00204         int rc, ret;
00205         volatile struct spe_spu_control_area *cntl_area =
00206                 spectx->base_private->cntl_mmap_base;
00207 
00208         if (spectx->base_private->flags & SPE_MAP_PS) {
00209                 ret = (cntl_area->SPU_Mbox_Stat >> 8) & 0xFF;
00210         } else {
00211                 rc = read(_base_spe_open_if_closed(spectx,FD_WBOX_STAT, 0), &ret, 4);
00212                 if (rc != 4)
00213                         ret = -1;
00214         }
00215 
00216         return ret;
00217         
00218 }

Here is the call graph for this function:

int _base_spe_in_mbox_write ( spe_context_ptr_t  spectx,
unsigned int  mbox_data[],
int  count,
int  behavior_flag 
)

The _base_spe_in_mbox_write function writes mbox_data to the SPE inbound mailbox for the SPE thread speid.

If the behavior flag indicates ALL_BLOCKING the call will try to write exactly count mailbox entries and block until the write request is satisfied, i.e., exactly count mailbox entries have been written. If the behavior flag indicates ANY_BLOCKING the call will try to write up to count mailbox entries, and block until the write request is satisfied, i.e., at least 1 mailbox entry has been written. If the behavior flag indicates ANY_NON_BLOCKING the call will not block until the write request is satisfied, but instead write whatever is immediately possible and return the number of mailbox entries written. spe_stat_in_mbox can be called to ensure that data can be written prior to calling the function.

Parameters:
spectx Specifies the SPE thread whose outbound mailbox is to be read.
mbox_data 
count 
behavior_flag ALL_BLOCKING
ANY_BLOCKING
ANY_NON_BLOCKING
Return values:
>=0 the number of 32-bit mailbox messages written
-1 error condition and errno is set
Possible values for errno:
EINVAL spectx is invalid
Exxxx what else do we need here??
void* _base_spe_ls_area_get ( struct spe_context spectx  ) 

_base_spe_ls_area_get returns a pointer to the start of the memory mapped local store area

Parameters:
spectx Specifies the SPE context
int _base_spe_ls_size_get ( spe_context_ptr_t  spe  ) 

_base_spe_ls_size_get returns the size of the local store area

Parameters:
spectx Specifies the SPE context

Definition at line 105 of file accessors.c.

References LS_SIZE.

00106 {
00107         return LS_SIZE;
00108 }

int _base_spe_mfcio_get ( spe_context_ptr_t  spectx,
unsigned int  ls,
void *  ea,
unsigned int  size,
unsigned int  tag,
unsigned int  tid,
unsigned int  rid 
)

The _base_spe_mfcio_get function places a get DMA command on the proxy command queue of the SPE thread specified by speid. The get command transfers size bytes of data starting at the effective address specified by ea to the local store address specified by ls. The DMA is identified by the tag id specified by tag and performed according to the transfer class and replacement class specified by tid and rid respectively.

Parameters:
spectx Specifies the SPE context
ls Specifies the starting local store destination address.
ea Specifies the starting effective address source address.
size Specifies the size, in bytes, to be transferred.
tag Specifies the tag id used to identify the DMA command.
tid Specifies the transfer class identifier of the DMA command.
rid Specifies the replacement class identifier of the DMA command.
Returns:
On success, return 0. On failure, -1 is returned.

Definition at line 160 of file dma.c.

References MFC_CMD_GET.

00167 {
00168         return spe_do_mfc_get(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_GET);
00169 }

int _base_spe_mfcio_getb ( spe_context_ptr_t  spectx,
unsigned int  ls,
void *  ea,
unsigned int  size,
unsigned int  tag,
unsigned int  tid,
unsigned int  rid 
)

The _base_spe_mfcio_getb function is identical to _base_spe_mfcio_get except that it places a getb (get with barrier) DMA command on the proxy command queue. The barrier form ensures that this command and all sequence commands with the same tag identifier as this command are locally ordered with respect to all previously issued commands with the same tag group and command queue.

Parameters:
spectx Specifies the SPE context
ls Specifies the starting local store destination address.
ea Specifies the starting effective address source address.
size Specifies the size, in bytes, to be transferred.
tag Specifies the tag id used to identify the DMA command.
tid Specifies the transfer class identifier of the DMA command.
rid Specifies the replacement class identifier of the DMA command.
Returns:
On success, return 0. On failure, -1 is returned.

Definition at line 171 of file dma.c.

References MFC_CMD_GETB.

00178 {
00179         return spe_do_mfc_get(spectx, ls, ea, size, tag, rid, rid, MFC_CMD_GETB);
00180 }

int _base_spe_mfcio_getf ( spe_context_ptr_t  spectx,
unsigned int  ls,
void *  ea,
unsigned int  size,
unsigned int  tag,
unsigned int  tid,
unsigned int  rid 
)

The _base_spe_mfcio_getf function is identical to _base_spe_mfcio_get except that it places a getf (get with fence) DMA command on the proxy command queue. The fence form ensure that this command is locally ordered with respect to all previously issued commands with the same tag group and command queue.

Parameters:
spectx Specifies the SPE context
ls Specifies the starting local store destination address.
ea Specifies the starting effective address source address.
size Specifies the size, in bytes, to be transferred.
tag Specifies the tag id used to identify the DMA command.
tid Specifies the transfer class identifier of the DMA command.
rid Specifies the replacement class identifier of the DMA command.
Returns:
On success, return 0. On failure, -1 is returned.

Definition at line 182 of file dma.c.

References MFC_CMD_GETF.

00189 {
00190         return spe_do_mfc_get(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_GETF);
00191 }

int _base_spe_mfcio_put ( spe_context_ptr_t  spectx,
unsigned int  ls,
void *  ea,
unsigned int  size,
unsigned int  tag,
unsigned int  tid,
unsigned int  rid 
)

The _base_spe_mfcio_put function places a put DMA command on the proxy command queue of the SPE thread specified by speid. The put command transfers size bytes of data starting at the local store address specified by ls to the effective address specified by ea. The DMA is identified by the tag id specified by tag and performed according transfer class and replacement class specified by tid and rid respectively.

Parameters:
spectx Specifies the SPE context
ls Specifies the starting local store destination address.
ea Specifies the starting effective address source address.
size Specifies the size, in bytes, to be transferred.
tag Specifies the tag id used to identify the DMA command.
tid Specifies the transfer class identifier of the DMA command.
rid Specifies the replacement class identifier of the DMA command.
Returns:
On success, return 0. On failure, -1 is returned.

Definition at line 126 of file dma.c.

References MFC_CMD_PUT.

00133 {
00134         return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUT);
00135 }

int _base_spe_mfcio_putb ( spe_context_ptr_t  spectx,
unsigned int  ls,
void *  ea,
unsigned int  size,
unsigned int  tag,
unsigned int  tid,
unsigned int  rid 
)

The _base_spe_mfcio_putb function is identical to _base_spe_mfcio_put except that it places a putb (put with barrier) DMA command on the proxy command queue. The barrier form ensures that this command and all sequence commands with the same tag identifier as this command are locally ordered with respect to all previously i ssued commands with the same tag group and command queue.

Parameters:
spectx Specifies the SPE context
ls Specifies the starting local store destination address.
ea Specifies the starting effective address source address.
size Specifies the size, in bytes, to be transferred.
tag Specifies the tag id used to identify the DMA command.
tid Specifies the transfer class identifier of the DMA command.
rid Specifies the replacement class identifier of the DMA command.
Returns:
On success, return 0. On failure, -1 is returned.

Definition at line 137 of file dma.c.

References MFC_CMD_PUTB.

00144 {
00145         return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUTB);
00146 }

int _base_spe_mfcio_putf ( spe_context_ptr_t  spectx,
unsigned int  ls,
void *  ea,
unsigned int  size,
unsigned int  tag,
unsigned int  tid,
unsigned int  rid 
)

The _base_spe_mfcio_putf function is identical to _base_spe_mfcio_put except that it places a putf (put with fence) DMA command on the proxy command queue. The fence form ensures that this command is locally ordered with respect to all previously issued commands with the same tag group and command queue.

Parameters:
spectx Specifies the SPE context
ls Specifies the starting local store destination address.
ea Specifies the starting effective address source address.
size Specifies the size, in bytes, to be transferred.
tag Specifies the tag id used to identify the DMA command.
tid Specifies the transfer class identifier of the DMA command.
rid Specifies the replacement class identifier of the DMA command.
Returns:
On success, return 0. On failure, -1 is returned.

Definition at line 148 of file dma.c.

References MFC_CMD_PUTF.

00155 {
00156         return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUTF);
00157 }

int _base_spe_mfcio_tag_status_read ( spe_context_ptr_t  spectx,
unsigned int  mask,
unsigned int  behavior,
unsigned int *  tag_status 
)

_base_spe_mfcio_tag_status_read

No Idea

Definition at line 307 of file dma.c.

References spe_context_base_priv::active_tagmask, spe_context::base_private, spe_context_base_priv::flags, SPE_MAP_PS, SPE_TAG_ALL, SPE_TAG_ANY, and SPE_TAG_IMMEDIATE.

00308 {
00309         if ( mask != 0 ) {
00310                 if (!(spectx->base_private->flags & SPE_MAP_PS)) 
00311                         mask = 0;
00312         } else {
00313                 if ((spectx->base_private->flags & SPE_MAP_PS))
00314                         mask = spectx->base_private->active_tagmask;
00315         }
00316 
00317         if (!tag_status) {
00318                 errno = EINVAL;
00319                 return -1;
00320         }
00321 
00322         switch (behavior) {
00323         case SPE_TAG_ALL:
00324                 return spe_mfcio_tag_status_read_all(spectx, mask, tag_status);
00325         case SPE_TAG_ANY:
00326                 return spe_mfcio_tag_status_read_any(spectx, mask, tag_status);
00327         case SPE_TAG_IMMEDIATE:
00328                 return spe_mfcio_tag_status_read_immediate(spectx, mask, tag_status);
00329         default:
00330                 errno = EINVAL;
00331                 return -1;
00332         }
00333 }

int _base_spe_mssync_start ( spe_context_ptr_t  spectx  ) 

_base_spe_mssync_start starts Multisource Synchronisation

Parameters:
spectx Specifies the SPE context

Definition at line 335 of file dma.c.

References _base_spe_open_if_closed(), spe_context::base_private, FD_MSS, spe_context_base_priv::flags, spe_mssync_area::MFC_MSSync, spe_context_base_priv::mssync_mmap_base, and SPE_MAP_PS.

00336 {
00337         int ret, fd;
00338         unsigned int data = 1; /* Any value can be written here */
00339 
00340         volatile struct spe_mssync_area *mss_area = 
00341                 spectx->base_private->mssync_mmap_base;
00342 
00343         if (spectx->base_private->flags & SPE_MAP_PS) {
00344                 mss_area->MFC_MSSync = data; 
00345                 return 0;
00346         } else {
00347                 fd = _base_spe_open_if_closed(spectx, FD_MSS, 0);
00348                 if (fd != -1) {
00349                         ret = write(fd, &data, sizeof (data));
00350                         if ((ret < 0) && (errno != EIO)) {
00351                                 perror("spe_mssync_start: internal error");
00352                         }
00353                         return ret < 0 ? -1 : 0;
00354                 } else 
00355                         return -1;
00356         }
00357 }

Here is the call graph for this function:

int _base_spe_mssync_status ( spe_context_ptr_t  spectx  ) 

_base_spe_mssync_status retrieves status of Multisource Synchronisation

Parameters:
spectx Specifies the SPE context

Definition at line 359 of file dma.c.

References _base_spe_open_if_closed(), spe_context::base_private, FD_MSS, spe_context_base_priv::flags, spe_mssync_area::MFC_MSSync, spe_context_base_priv::mssync_mmap_base, and SPE_MAP_PS.

00360 {
00361         int ret, fd;
00362         unsigned int data;
00363 
00364         volatile struct spe_mssync_area *mss_area = 
00365                 spectx->base_private->mssync_mmap_base;
00366 
00367         if (spectx->base_private->flags & SPE_MAP_PS) {
00368                 return  mss_area->MFC_MSSync;
00369         } else {
00370                 fd = _base_spe_open_if_closed(spectx, FD_MSS, 0);
00371                 if (fd != -1) {
00372                         ret = read(fd, &data, sizeof (data));
00373                         if ((ret < 0) && (errno != EIO)) {
00374                                 perror("spe_mssync_start: internal error");
00375                         }
00376                         return ret < 0 ? -1 : data;
00377                 } else 
00378                         return -1;
00379         }
00380 }

Here is the call graph for this function:

int _base_spe_out_intr_mbox_read ( spe_context_ptr_t  spectx,
unsigned int  mbox_data[],
int  count,
int  behavior_flag 
)

The _base_spe_out_intr_mbox_read function reads the contents of the SPE outbound interrupting mailbox for the SPE context.

Definition at line 255 of file mbox.c.

References _base_spe_open_if_closed(), FD_IBOX, FD_IBOX_NB, SPE_MBOX_ALL_BLOCKING, SPE_MBOX_ANY_BLOCKING, and SPE_MBOX_ANY_NONBLOCKING.

00259 {
00260         int rc;
00261         int total;
00262 
00263         if (mbox_data == NULL || count < 1){
00264                 errno = EINVAL;
00265                 return -1;
00266         }
00267 
00268         switch (behavior_flag) {
00269         case SPE_MBOX_ALL_BLOCKING: // read all, even if blocking
00270                 total = rc = 0;
00271                 while (total < 4*count) {
00272                         rc = read(_base_spe_open_if_closed(spectx,FD_IBOX, 0),
00273                                   (char *)mbox_data + total, 4*count - total);
00274                         if (rc == -1) {
00275                                 break;
00276                         }
00277                         total += rc;
00278                 }
00279                 break;
00280 
00281         case  SPE_MBOX_ANY_BLOCKING: // read at least one, even if blocking
00282                 total = rc = read(_base_spe_open_if_closed(spectx,FD_IBOX, 0), mbox_data, 4*count);
00283                 break;
00284 
00285         case  SPE_MBOX_ANY_NONBLOCKING: // only reaad, if non blocking
00286                 rc = read(_base_spe_open_if_closed(spectx,FD_IBOX_NB, 0), mbox_data, 4*count);
00287                 if (rc == -1 && errno == EAGAIN) {
00288                         rc = 0;
00289                         errno = 0;
00290                 }
00291                 total = rc;
00292                 break;
00293 
00294         default:
00295                 errno = EINVAL;
00296                 return -1;
00297         }
00298 
00299         if (rc == -1) {
00300                 errno = EIO;
00301                 return -1;
00302         }
00303 
00304         return rc / 4;
00305 }

Here is the call graph for this function:

int _base_spe_out_intr_mbox_status ( spe_context_ptr_t  spectx  ) 

The _base_spe_out_intr_mbox_status function fetches the status of the SPU outbound interrupt mailbox for the SPE thread specified by the speid parameter. A 0 value is return if the mailbox is empty. A non-zero value specifies the number of 32-bit unread mailbox entries.

Parameters:
spectx Specifies the SPE context whose mailbox status is to be read.
Returns:
On success, returns the current status of the mailbox, respectively. On failure, -1 is returned.
See also:
spe_read_out_mbox, spe_write_in_mbox, read (2)

Definition at line 238 of file mbox.c.

References _base_spe_open_if_closed(), spe_context::base_private, spe_context_base_priv::cntl_mmap_base, FD_IBOX_STAT, spe_context_base_priv::flags, SPE_MAP_PS, and spe_spu_control_area::SPU_Mbox_Stat.

00239 {
00240         int rc, ret;
00241         volatile struct spe_spu_control_area *cntl_area =
00242                 spectx->base_private->cntl_mmap_base;
00243 
00244         if (spectx->base_private->flags & SPE_MAP_PS) {
00245                 ret = (cntl_area->SPU_Mbox_Stat >> 16) & 0xFF;
00246         } else {
00247                 rc = read(_base_spe_open_if_closed(spectx,FD_IBOX_STAT, 0), &ret, 4);
00248                 if (rc != 4)
00249                         ret = -1;
00250 
00251         }
00252         return ret;
00253 }

Here is the call graph for this function:

int _base_spe_out_mbox_read ( spe_context_ptr_t  spectx,
unsigned int  mbox_data[],
int  count 
)

The _base_spe_out_mbox_read function reads the contents of the SPE outbound interrupting mailbox for the SPE thread speid.

The call will not block until the read request is satisfied, but instead return up to count currently available mailbox entries.

spe_stat_out_intr_mbox can be called to ensure that data is available prior to reading the outbound interrupting mailbox.

Parameters:
spectx Specifies the SPE thread whose outbound mailbox is to be read.
mbox_data 
count 
Return values:
>0 the number of 32-bit mailbox messages read
=0 no data available
-1 error condition and errno is set
Possible values for errno:
EINVAL speid is invalid
Exxxx what else do we need here??

Definition at line 58 of file mbox.c.

References _base_spe_open_if_closed(), spe_context::base_private, DEBUG_PRINTF, FD_MBOX, spe_context_base_priv::flags, and SPE_MAP_PS.

00061 {
00062         int rc;
00063 
00064         if (mbox_data == NULL || count < 1){
00065                 errno = EINVAL;
00066                 return -1;
00067         }
00068 
00069         if (spectx->base_private->flags & SPE_MAP_PS) {
00070                 rc = _base_spe_out_mbox_read_ps(spectx, mbox_data, count);
00071         } else {
00072                 rc = read(_base_spe_open_if_closed(spectx,FD_MBOX, 0), mbox_data, count*4);
00073                 DEBUG_PRINTF("%s read rc: %d\n", __FUNCTION__, rc);
00074                 if (rc != -1) {
00075                         rc /= 4;
00076                 } else {
00077                         if (errno == EAGAIN ) { // no data ready to be read
00078                                 errno = 0;
00079                                 rc = 0;
00080                         }
00081                 }
00082         }
00083         return rc;
00084 }

Here is the call graph for this function:

int _base_spe_out_mbox_status ( spe_context_ptr_t  spectx  ) 

The _base_spe_out_mbox_status function fetches the status of the SPU outbound mailbox for the SPE thread specified by the speid parameter. A 0 value is return if the mailbox is empty. A non-zero value specifies the number of 32-bit unread mailbox entries.

Parameters:
spectx Specifies the SPE context whose mailbox status is to be read.
Returns:
On success, returns the current status of the mailbox, respectively. On failure, -1 is returned.
See also:
spe_read_out_mbox, spe_write_in_mbox, read (2)

Definition at line 220 of file mbox.c.

References _base_spe_open_if_closed(), spe_context::base_private, spe_context_base_priv::cntl_mmap_base, FD_MBOX_STAT, spe_context_base_priv::flags, SPE_MAP_PS, and spe_spu_control_area::SPU_Mbox_Stat.

00221 {
00222         int rc, ret;
00223         volatile struct spe_spu_control_area *cntl_area =
00224                 spectx->base_private->cntl_mmap_base;
00225 
00226         if (spectx->base_private->flags & SPE_MAP_PS) {
00227                 ret = cntl_area->SPU_Mbox_Stat & 0xFF;
00228         } else {
00229                 rc = read(_base_spe_open_if_closed(spectx,FD_MBOX_STAT, 0), &ret, 4);
00230                 if (rc != 4)
00231                         ret = -1;
00232         }
00233 
00234         return ret;
00235         
00236 }

Here is the call graph for this function:

int _base_spe_program_load ( spe_context_ptr_t  spectx,
spe_program_handle_t program 
)

_base_spe_program_load loads an ELF image into a context

Parameters:
spectx Specifies the SPE context
program handle to the ELF image

Definition at line 203 of file load.c.

References _base_spe_load_spe_elf(), _base_spe_program_load_complete(), spe_context::base_private, DEBUG_PRINTF, spe_context_base_priv::emulated_entry, spe_ld_info::entry, spe_context_base_priv::entry, spe_context_base_priv::flags, spe_context_base_priv::loaded_program, spe_context_base_priv::mem_mmap_base, SPE_ISOLATE, and SPE_ISOLATE_EMULATE.

00204 {
00205         int rc = 0;
00206         struct spe_ld_info ld_info;
00207 
00208         spe->base_private->loaded_program = program;
00209 
00210         if (spe->base_private->flags & SPE_ISOLATE) {
00211                 rc = spe_start_isolated_app(spe, program);
00212 
00213         } else if (spe->base_private->flags & SPE_ISOLATE_EMULATE) {
00214                 rc = spe_start_emulated_isolated_app(spe, program, &ld_info);
00215 
00216         } else {
00217                 rc = _base_spe_load_spe_elf(program,
00218                                 spe->base_private->mem_mmap_base, &ld_info);
00219                 if (!rc)
00220                         _base_spe_program_load_complete(spe);
00221         }
00222 
00223         if (rc != 0) {
00224                 DEBUG_PRINTF ("Load SPE ELF failed..\n");
00225                 return -1;
00226         }
00227 
00228         spe->base_private->entry = ld_info.entry;
00229         spe->base_private->emulated_entry = ld_info.entry;
00230 
00231         return 0;
00232 }

Here is the call graph for this function:

void _base_spe_program_load_complete ( spe_context_ptr_t  spectx  ) 

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

Precondition:
spe->base_priv->loaded_program is a valid SPE program
Parameters:
spectx The spe context that has been loaded.

Register the SPE program's start address with the oprofile and gdb, by writing to the object-id file.

Definition at line 38 of file load.c.

References __spe_context_update_event(), spe_context::base_private, DEBUG_PRINTF, spe_program_handle::elf_image, spe_context_base_priv::fd_spe_dir, and spe_context_base_priv::loaded_program.

Referenced by _base_spe_context_run(), and _base_spe_program_load().

00039 {
00040         int objfd, len;
00041         char buf[20];
00042         spe_program_handle_t *program;
00043 
00044         program = spectx->base_private->loaded_program;
00045 
00046         if (!program || !program->elf_image) {
00047                 DEBUG_PRINTF("%s called, but no program loaded\n", __func__);
00048                 return;
00049         }
00050 
00051         objfd = openat(spectx->base_private->fd_spe_dir, "object-id", O_RDWR);
00052         if (objfd < 0)
00053                 return;
00054 
00055         len = sprintf(buf, "%p", program->elf_image);
00056         write(objfd, buf, len + 1);
00057         close(objfd);
00058 
00059         __spe_context_update_event();
00060 }

Here is the call graph for this function:

void* _base_spe_ps_area_get ( struct spe_context spectx,
enum ps_area  area 
)

_base_spe_ps_area_get returns a pointer to the start of memory mapped problem state area

Parameters:
spectx Specifies the SPE context
area specifes the area to map
int _base_spe_signal_write ( spe_context_ptr_t  spectx,
unsigned int  signal_reg,
unsigned int  data 
)

The _base_spe_signal_write function writes data to the signal notification register specified by signal_reg for the SPE thread specified by the speid parameter.

Parameters:
spectx Specifies the SPE context whose signal register is to be written to.
signal_reg Specified the signal notification register to be written. Valid signal notification registers are:
SPE_SIG_NOTIFY_REG_1 SPE signal notification register 1
SPE_SIG_NOTIFY_REG_2 SPE signal notification register 2
data The 32-bit data to be written to the specified signal notification register.
Returns:
On success, spe_write_signal returns 0. On failure, -1 is returned.
See also:
spe_get_ps_area, spe_write_in_mbox

Definition at line 307 of file mbox.c.

References _base_spe_close_if_open(), _base_spe_open_if_closed(), spe_context::base_private, FD_SIG1, FD_SIG2, spe_context_base_priv::flags, spe_context_base_priv::signal1_mmap_base, spe_context_base_priv::signal2_mmap_base, SPE_MAP_PS, SPE_SIG_NOTIFY_REG_1, SPE_SIG_NOTIFY_REG_2, spe_sig_notify_1_area::SPU_Sig_Notify_1, and spe_sig_notify_2_area::SPU_Sig_Notify_2.

00310 {
00311         int rc;
00312 
00313         if (spectx->base_private->flags & SPE_MAP_PS) {
00314                 if (signal_reg == SPE_SIG_NOTIFY_REG_1) {
00315                         spe_sig_notify_1_area_t *sig = spectx->base_private->signal1_mmap_base;
00316 
00317                         sig->SPU_Sig_Notify_1 = data;
00318                 } else if (signal_reg == SPE_SIG_NOTIFY_REG_2) {
00319                         spe_sig_notify_2_area_t *sig = spectx->base_private->signal2_mmap_base;
00320 
00321                         sig->SPU_Sig_Notify_2 = data;
00322                 } else {
00323                         errno = EINVAL;
00324                         return -1;
00325                 }
00326                 rc = 0;
00327         } else {
00328                 if (signal_reg == SPE_SIG_NOTIFY_REG_1)
00329                         rc = write(_base_spe_open_if_closed(spectx,FD_SIG1, 0), &data, 4);
00330                 else if (signal_reg == SPE_SIG_NOTIFY_REG_2)
00331                         rc = write(_base_spe_open_if_closed(spectx,FD_SIG2, 0), &data, 4);
00332                 else {
00333                         errno = EINVAL;
00334                         return -1;
00335                 }
00336                 
00337                 if (rc == 4)
00338                         rc = 0;
00339         
00340                 if (signal_reg == SPE_SIG_NOTIFY_REG_1)
00341                         _base_spe_close_if_open(spectx,FD_SIG1);
00342                 else if (signal_reg == SPE_SIG_NOTIFY_REG_2)
00343                         _base_spe_close_if_open(spectx,FD_SIG2);
00344         }
00345 
00346         return rc;
00347 }

Here is the call graph for this function:

int _base_spe_stop_reason_get ( spe_context_ptr_t  spectx  ) 

_base_spe_stop_reason_get

Parameters:
spectx one thread for which to check why it was stopped
Return values:
0 success - eventid and eventdata set appropriately
1 spe has not stopped after checking last, so no data was written to event
-1 an error has happened, event was not touched, errno gets set
Possible vales for errno:
EINVAL speid is invalid
Exxxx what else do we need here??
int _base_spe_stop_status_get ( spe_context_ptr_t  spectx  ) 

_base_spe_stop_status_get

Parameters:
spectx Specifies the SPE context

Generated by  doxygen 1.6.2