libspe2 0.9a
Functions
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:
spectxSpecifies 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.

{
        int rc, ret;
        volatile struct spe_spu_control_area *cntl_area =
                spectx->base_private->cntl_mmap_base;

        if (spectx->base_private->flags & SPE_MAP_PS) {
                ret = (cntl_area->SPU_Mbox_Stat >> 8) & 0xFF;
        } else {
                rc = read(_base_spe_open_if_closed(spectx,FD_WBOX_STAT, 0), &ret, 4);
                if (rc != 4)
                        ret = -1;
        }

        return ret;
        
}

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.

{
        int rc;
        int total;
        unsigned int *aux;
        struct pollfd fds;

        if (mbox_data == NULL || count < 1){
                errno = EINVAL;
                return -1;
        }

        switch (behavior_flag) {
        case SPE_MBOX_ALL_BLOCKING: // write all, even if blocking
                total = rc = 0;
                if (spectx->base_private->flags & SPE_MAP_PS) {
                        do {
                                aux = mbox_data + total;
                                total += _base_spe_in_mbox_write_ps(spectx, aux, count - total);
                                if (total < count) { // we could not write everything, wait for space
                                        fds.fd = _base_spe_open_if_closed(spectx, FD_WBOX, 0);
                                        fds.events = POLLOUT;
                                        rc = poll(&fds, 1, -1);
                                        if (rc == -1 ) 
                                                return -1;
                                }
                        } while (total < count);
                } else {
                        while (total < 4*count) {
                                rc = write(_base_spe_open_if_closed(spectx,FD_WBOX, 0),
                                           (const char *)mbox_data + total, 4*count - total);
                                if (rc == -1) {
                                        break;
                                }
                                total += rc;
                        }
                        total /=4;
                }
                break;

        case  SPE_MBOX_ANY_BLOCKING: // write at least one, even if blocking
                total = rc = 0;
                if (spectx->base_private->flags & SPE_MAP_PS) {
                        do {
                                total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
                                if (total == 0) { // we could not anything, wait for space
                                        fds.fd = _base_spe_open_if_closed(spectx, FD_WBOX, 0);
                                        fds.events = POLLOUT;
                                        rc = poll(&fds, 1, -1);
                                        if (rc == -1 ) 
                                                return -1;
                                }
                        } while (total == 0);
                } else {
                        rc = write(_base_spe_open_if_closed(spectx,FD_WBOX, 0), mbox_data, 4*count);
                        total = rc/4;
                }
                break;

        case  SPE_MBOX_ANY_NONBLOCKING: // only write, if non blocking
                total = rc = 0;
                // write directly if we map the PS else write via spufs
                if (spectx->base_private->flags & SPE_MAP_PS) {
                        total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
                } else { 
                        rc = write(_base_spe_open_if_closed(spectx,FD_WBOX_NB, 0), mbox_data, 4*count);
                        if (rc == -1 && errno == EAGAIN) {
                                rc = 0;
                                errno = 0;
                        }
                        total = rc/4;
                }
                break;

        default:
                errno = EINVAL;
                return -1;
        }

        if (rc == -1) {
                errno = EIO;
                return -1;
        }

        return total;
}

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.

{
        int rc;
        int total;

        if (mbox_data == NULL || count < 1){
                errno = EINVAL;
                return -1;
        }

        switch (behavior_flag) {
        case SPE_MBOX_ALL_BLOCKING: // read all, even if blocking
                total = rc = 0;
                while (total < 4*count) {
                        rc = read(_base_spe_open_if_closed(spectx,FD_IBOX, 0),
                                  (char *)mbox_data + total, 4*count - total);
                        if (rc == -1) {
                                break;
                        }
                        total += rc;
                }
                break;

        case  SPE_MBOX_ANY_BLOCKING: // read at least one, even if blocking
                total = rc = read(_base_spe_open_if_closed(spectx,FD_IBOX, 0), mbox_data, 4*count);
                break;

        case  SPE_MBOX_ANY_NONBLOCKING: // only reaad, if non blocking
                rc = read(_base_spe_open_if_closed(spectx,FD_IBOX_NB, 0), mbox_data, 4*count);
                if (rc == -1 && errno == EAGAIN) {
                        rc = 0;
                        errno = 0;
                }
                total = rc;
                break;

        default:
                errno = EINVAL;
                return -1;
        }

        if (rc == -1) {
                errno = EIO;
                return -1;
        }

        return rc / 4;
}

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:
spectxSpecifies 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.

{
        int rc, ret;
        volatile struct spe_spu_control_area *cntl_area =
                spectx->base_private->cntl_mmap_base;

        if (spectx->base_private->flags & SPE_MAP_PS) {
                ret = (cntl_area->SPU_Mbox_Stat >> 16) & 0xFF;
        } else {
                rc = read(_base_spe_open_if_closed(spectx,FD_IBOX_STAT, 0), &ret, 4);
                if (rc != 4)
                        ret = -1;

        }
        return ret;
}

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:
spectxSpecifies the SPE thread whose outbound mailbox is to be read.
mbox_data
count
Return values:
>0the number of 32-bit mailbox messages read
=0no data available
-1error 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.

{
        int rc;

        if (mbox_data == NULL || count < 1){
                errno = EINVAL;
                return -1;
        }

        if (spectx->base_private->flags & SPE_MAP_PS) {
                rc = _base_spe_out_mbox_read_ps(spectx, mbox_data, count);
        } else {
                rc = read(_base_spe_open_if_closed(spectx,FD_MBOX, 0), mbox_data, count*4);
                DEBUG_PRINTF("%s read rc: %d\n", __FUNCTION__, rc);
                if (rc != -1) {
                        rc /= 4;
                } else {
                        if (errno == EAGAIN ) { // no data ready to be read
                                errno = 0;
                                rc = 0;
                        }
                }
        }
        return rc;
}

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:
spectxSpecifies 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.

{
        int rc, ret;
        volatile struct spe_spu_control_area *cntl_area =
                spectx->base_private->cntl_mmap_base;

        if (spectx->base_private->flags & SPE_MAP_PS) {
                ret = cntl_area->SPU_Mbox_Stat & 0xFF;
        } else {
                rc = read(_base_spe_open_if_closed(spectx,FD_MBOX_STAT, 0), &ret, 4);
                if (rc != 4)
                        ret = -1;
        }

        return ret;
        
}

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:
spectxSpecifies the SPE context whose signal register is to be written to.
signal_regSpecified 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
dataThe 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.

{
        int rc;

        if (spectx->base_private->flags & SPE_MAP_PS) {
                if (signal_reg == SPE_SIG_NOTIFY_REG_1) {
                        spe_sig_notify_1_area_t *sig = spectx->base_private->signal1_mmap_base;

                        sig->SPU_Sig_Notify_1 = data;
                } else if (signal_reg == SPE_SIG_NOTIFY_REG_2) {
                        spe_sig_notify_2_area_t *sig = spectx->base_private->signal2_mmap_base;

                        sig->SPU_Sig_Notify_2 = data;
                } else {
                        errno = EINVAL;
                        return -1;
                }
                rc = 0;
        } else {
                if (signal_reg == SPE_SIG_NOTIFY_REG_1)
                        rc = write(_base_spe_open_if_closed(spectx,FD_SIG1, 0), &data, 4);
                else if (signal_reg == SPE_SIG_NOTIFY_REG_2)
                        rc = write(_base_spe_open_if_closed(spectx,FD_SIG2, 0), &data, 4);
                else {
                        errno = EINVAL;
                        return -1;
                }
                
                if (rc == 4)
                        rc = 0;
        
                if (signal_reg == SPE_SIG_NOTIFY_REG_1)
                        _base_spe_close_if_open(spectx,FD_SIG1);
                else if (signal_reg == SPE_SIG_NOTIFY_REG_2)
                        _base_spe_close_if_open(spectx,FD_SIG2);
        }

        return rc;
}

Here is the call graph for this function: