[Cbe-oss-dev] [RFC/PATCH] libspe2: use mapped mailbox registers to speed up mailbox communication

Kazunori Asayama asayama at sm.sony.co.jp
Fri May 18 21:58:33 EST 2007


stenzel at de.ibm.com wrote:
> The following patch speeds up mailbox communication by
> accessing the mailbox registers directly via mapped problem
> state if the context was created with the SPE_MAP_PS flag.
> 
> Comments are appreciated.

A problem of this approach is that there is no guarantee that check of
mbox-stat and access to mbox are done atomically if both of syscall
and direct access are performed at the same time.

(snip)

> +static __inline__ int _base_spe_in_mbox_write_ps(spe_context_ptr_t spectx,
> +                        unsigned int *mbox_data, 
> +                        int count)
> +{
> +	volatile struct spe_spu_control_area *cntl_area =
> +        	spectx->base_private->cntl_mmap_base;
> +	int total = 0;
> +	unsigned int *aux;
> +
> +	_base_spe_context_lock(spectx, FD_WBOX);
> +	aux = mbox_data;
> +	while (total < count) {
> +		int space = (cntl_area->SPU_Mbox_Stat >> 8) & 0xFF;
> +		if (space) {
> +			cntl_area->SPU_In_Mbox = *aux++;
> +			total++;
> +		} else {
> +			break;
> +		}
> +	}
> +	_base_spe_context_unlock(spectx, FD_WBOX);
> +
> +	return total;
> +}
> +

Consider that one thread call the function above while another thread
is still calling write() for the same mbox. Such a situation seems
possible when two thread call spe_in_mbox_write() with
SPE_MBOX_ANY_BLOCKING at the same time.

>  int _base_spe_in_mbox_write(spe_context_ptr_t spectx, 
>                          unsigned int *mbox_data, 
>                          int count, 
> @@ -63,6 +115,7 @@ int _base_spe_in_mbox_write(spe_context_
>  {
>  	int rc;
>  	int total;
> +	unsigned int *aux;
>  
>  	if (mbox_data == NULL || count < 1){
>  		errno = EINVAL;
> @@ -72,27 +125,48 @@ int _base_spe_in_mbox_write(spe_context_
>  	switch (behavior_flag) {
>  	case SPE_MBOX_ALL_BLOCKING: // write all, even if blocking
>  		total = rc = 0;
> -		while (total < 4*count) {
> +
> +		// first try to write directly if we map the PS
> +		if (spectx->base_private->flags & SPE_MAP_PS) 
> +			total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
> +
> +		// now write the remaining via spufs
> +		while (total < count) {
> +			aux = mbox_data + total;
>  			rc = write(open_if_closed(spectx,FD_WBOX, 0),
> -					(const char *)mbox_data + total, 4*count - total);
> +				  aux, 4*(count - total));
>  			if (rc == -1) {
>  				break;
>  			}
> -			total += rc;
> +			total += (rc/4);
>  		}
>  		break;
>  
>  	case  SPE_MBOX_ANY_BLOCKING: // write at least one, even if blocking
> -		total = rc = write(open_if_closed(spectx,FD_WBOX, 0), mbox_data, 4*count);
> +		total = rc = 0;
> +		// first try to write directly if we map the PS
> +		if (spectx->base_private->flags & SPE_MAP_PS) 
> +			total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
> +		// if none was written write via spufs
> +		if (total == 0) {
> +			rc = write(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
> -		rc = write(open_if_closed(spectx,FD_WBOX_NB, 0), mbox_data, 4*count);
> -		if (rc == -1 && errno == EAGAIN) {
> -			rc = 0;
> -			errno = 0;
> +		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(open_if_closed(spectx,FD_WBOX_NB, 0), mbox_data, 4*count);
> +			if (rc == -1 && errno == EAGAIN) {
> +				rc = 0;
> +				errno = 0;
> +			}
> +			total = rc/4;
>  		}
> -		total = rc;
>  		break;
>  
>  	default:
> @@ -105,16 +179,24 @@ int _base_spe_in_mbox_write(spe_context_
>  		return -1;
>  	}
>  
> -	return total / 4;
> +	return total;
>  }
>  

--
(ASAYAMA Kazunori
  (asayama at sm.sony.co.jp))
t



More information about the cbe-oss-dev mailing list