libspe2 0.9a
|
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
#include "create.h"
#include "mbox.h"
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) |
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.
spectx | Specifies the SPE context whose mailbox status is to be read. |
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; }
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; }
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; }
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.
spectx | Specifies the SPE context whose mailbox status is to be read. |
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; }
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.
spectx | Specifies the SPE thread whose outbound mailbox is to be read. |
mbox_data | |
count |
>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.
{ 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; }
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.
spectx | Specifies the SPE context whose mailbox status is to be read. |
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; }
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.
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. |
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; }