#include "../../../include/sys/ac_sys.h"
#include "../../../include/cpu/i686/ac_i686_stack_mpmc.h"
int AC_APIDECL
ac_i686_prv_stack_mpmc_alloc
( ac_i686_prv_stack_mpmc_t *_this,
ac_i686_prv_stack_mpmc_shared_t *_shared )
{
int ret;
if ( ! _shared )
{
ac_i686_prv_stack_mpmc_shared_padded_t *_padded;
_padded = ac_malloc_aligned
( &_this->shared_mem,
sizeof( *_padded ),
AC_CPU_CACHE_LINE );
if ( ! _padded ) { return ac_sys_error( ENOMEM ); }
_shared = &_padded->_this;
}
else { _this->shared_mem = 0; }
ret = AC_SYS_IS_MEM_ALIGNED
( _shared,
AC_CPU_WORD_SIZE );
if ( ret )
{
ac_free( _this->shared_mem );
return ac_sys_error( ret );
}
ret = ac_eventcount_algo1_alloc
( &_this->wset,
&_shared->wset );
if ( ret )
{
ac_free( _this->shared_mem );
return ac_sys_error( ret );
}
_shared->queue.front = 0;
_this->shared = _shared;
return 0;
}
int AC_APIDECL
ac_i686_prv_stack_mpmc_free
( ac_i686_prv_stack_mpmc_t *_this )
{
int ret;
if ( _this->shared->queue.front )
{
return ac_sys_error( EBUSY );
}
ret = ac_eventcount_algo1_free
( &_this->wset );
if ( ret ) { return ac_sys_error( ret ); }
ac_free( _this->shared_mem );
return 0;
}
ac_i686_node_t* AC_APIDECL
ac_i686_prv_stack_mpmc_timedpop
( ac_i686_prv_stack_mpmc_t *_this,
ac_thread_t *_tls,
ac_lfgc_smr_hazard_t hazard,
ac_timeout_t timeout )
{
ac_i686_node_t *node;
ac_cpu_pause_yield();
node = np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas
( &_this->shared->queue,
hazard );
while ( ! node )
{
ac_eventcount_cmp_t cmp;
if ( ! timeout ) { return 0; }
cmp = ac_eventcount_algo1_get( &_this->wset );
ac_cpu_pause_yield();
node = np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas
( &_this->shared->queue,
hazard );
if ( ! node )
{
int ret = ac_eventcount_algo1_timedwait
( &_this->wset,
_tls,
cmp,
timeout );
if ( ret ) { ac_sys_error( ret ); return 0; }
node = np_ac_i686_lfgc_smr_stack_mpmc_pop_dwcas
( &_this->shared->queue,
hazard );
}
}
return node;
}