mbox.c File Reference

#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
#include "create.h"
#include "mbox.h"
Include dependency graph for mbox.c:

Go to the source code of this file.

Functions

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)

Function Documentation

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 
)

Definition at line 112 of file mbox.c.

References _base_spe_open_if_closed(), spe_context::base_private, FD_WBOX, FD_WBOX_NB, spe_context_base_priv::flags, SPE_MAP_PS, SPE_MBOX_ALL_BLOCKING, SPE_MBOX_ANY_BLOCKING, and SPE_MBOX_ANY_NONBLOCKING.

00116 {
00117         int rc;
00118         int total;
00119         unsigned int *aux;
00120         struct pollfd fds;
00121 
00122         if (mbox_data == NULL || count < 1){
00123                 errno = EINVAL;
00124                 return -1;
00125         }
00126 
00127         switch (behavior_flag) {
00128         case SPE_MBOX_ALL_BLOCKING: // write all, even if blocking
00129                 total = rc = 0;
00130                 if (spectx->base_private->flags & SPE_MAP_PS) {
00131                         do {
00132                                 aux = mbox_data + total;
00133                                 total += _base_spe_in_mbox_write_ps(spectx, aux, count - total);
00134                                 if (total < count) { // we could not write everything, wait for space
00135                                         fds.fd = _base_spe_open_if_closed(spectx, FD_WBOX, 0);
00136                                         fds.events = POLLOUT;
00137                                         rc = poll(&fds, 1, -1);
00138                                         if (rc == -1 ) 
00139                                                 return -1;
00140                                 }
00141                         } while (total < count);
00142                 } else {
00143                         while (total < 4*count) {
00144                                 rc = write(_base_spe_open_if_closed(spectx,FD_WBOX, 0),
00145                                            (const char *)mbox_data + total, 4*count - total);
00146                                 if (rc == -1) {
00147                                         break;
00148                                 }
00149                                 total += rc;
00150                         }
00151                         total /=4;
00152                 }
00153                 break;
00154 
00155         case  SPE_MBOX_ANY_BLOCKING: // write at least one, even if blocking
00156                 total = rc = 0;
00157                 if (spectx->base_private->flags & SPE_MAP_PS) {
00158                         do {
00159                                 total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
00160                                 if (total == 0) { // we could not anything, wait for space
00161                                         fds.fd = _base_spe_open_if_closed(spectx, FD_WBOX, 0);
00162                                         fds.events = POLLOUT;
00163                                         rc = poll(&fds, 1, -1);
00164                                         if (rc == -1 ) 
00165                                                 return -1;
00166                                 }
00167                         } while (total == 0);
00168                 } else {
00169                         rc = write(_base_spe_open_if_closed(spectx,FD_WBOX, 0), mbox_data, 4*count);
00170                         total = rc/4;
00171                 }
00172                 break;
00173 
00174         case  SPE_MBOX_ANY_NONBLOCKING: // only write, if non blocking
00175                 total = rc = 0;
00176                 // write directly if we map the PS else write via spufs
00177                 if (spectx->base_private->flags & SPE_MAP_PS) {
00178                         total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
00179                 } else { 
00180                         rc = write(_base_spe_open_if_closed(spectx,FD_WBOX_NB, 0), mbox_data, 4*count);
00181                         if (rc == -1 && errno == EAGAIN) {
00182                                 rc = 0;
00183                                 errno = 0;
00184                         }
00185                         total = rc/4;
00186                 }
00187                 break;
00188 
00189         default:
00190                 errno = EINVAL;
00191                 return -1;
00192         }
00193 
00194         if (rc == -1) {
00195                 errno = EIO;
00196                 return -1;
00197         }
00198 
00199         return total;
00200 }

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_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:


Generated by  doxygen 1.6.2