src/impls/atrshmlogimpl_read_fetch.c
atrshmlog_ret_t atrshmlog_read_fetch(volatile const void* const i_area,
				     atrshmlog_int32_t * const o_index_buffer,
				     void * const o_target,
				     atrshmlog_int32_t * const o_target_length,
				     atrshmlog_pid_t* const o_pid,
				     atrshmlog_tid_t* const o_tid,
				     atrshmlog_internal_time_t* const o_inittime,
				     atrshmlog_time_t* const o_inittimetsc_before,
				     atrshmlog_time_t* const o_inittimetsc_after,
				     atrshmlog_internal_time_t* const o_lasttime,
				     atrshmlog_time_t* const o_lasttimetsc_before,
				     atrshmlog_time_t* const o_lasttimetsc_after,
				     atrshmlog_time_t* const o_difftimetransfer,
				     atrshmlog_time_t* const o_starttransfer,
				     atrshmlog_time_t* const o_acquiretime,
				     atrshmlog_int32_t* const o_id,
				     atrshmlog_int32_t* const o_number_dispatched,
				     atrshmlog_int32_t* const o_counter_write0,
				     atrshmlog_int32_t* const o_counter_write0_discard,
				     atrshmlog_int32_t* const o_counter_write0_wait,
				     atrshmlog_int32_t* const o_counter_write0_adaptive,
				     atrshmlog_int32_t* const o_counter_write0_adaptive_fast,
				     atrshmlog_int32_t* const o_counter_write0_adaptive_very_fast,
				     atrshmlog_int32_t* const o_counter_write1,
				     atrshmlog_int32_t* const o_counter_write1_discard,
				     atrshmlog_int32_t* const o_counter_write1_wait,
				     atrshmlog_int32_t* const o_counter_write1_adaptive,
				     atrshmlog_int32_t* const o_counter_write1_adaptive_fast,
				     atrshmlog_int32_t* const o_counter_write1_adaptive_very_fast,
				     atrshmlog_int32_t* const o_counter_write2,
				     atrshmlog_int32_t* const o_counter_write2_discard,
				     atrshmlog_int32_t* const o_counter_write2_wait,
				     atrshmlog_int32_t* const o_counter_write2_adaptive,
				     atrshmlog_int32_t* const o_counter_write2_adaptive_fast,
				     atrshmlog_int32_t* const o_counter_write2_adaptive_very_fast
				     )
{
  ATRSHMLOGSTAT(atrshmlog_counter_read_fetch);

  *o_target_length = 0;

  atrshmlog_time_t start;
  atrshmlog_time_t end;
  
  int result = -1;

  if(i_area == 0)
    return atrshmlog_error_read_fetch_1;

  // we do here a terrible thing.
  // we cast const away.
  // but its ok here.
  volatile atrshmlog_area_t * restrict i_shm = (volatile atrshmlog_area_t*)i_area;

  /* Ok. We can now do the transfer */

  atrshmlog_g_tl_t* g  = (atrshmlog_g_tl_t* )atrshmlog_get_thread_locals_adress();
  
#if ATRSHMLOG_THREAD_LOCAL == 0

  // this can happen if thread specific is in
  if (g == NULL)
    return atrshmlog_error_read_fetch_6;

#endif
  
  if (g->atrshmlog_idnotok)
    {
      int tlret = atrshmlog_init_thread_local (g);
      
      /* From now on we are the not ok flag */
      if (tlret)
	return tlret;
    }
  
  if (i_shm->shmsafeguard != ATRSHMLOGSAFEGUARDVALUE)
    return atrshmlog_error_read_fetch_2;

  /* We pop from list */
  int isfull = atomic_load_explicit(&i_shm->shmf, memory_order_consume);

  if (isfull == -1)
    return atrshmlog_error_read_fetch_3; /* No buffer on list */

  while (isfull > -1
	 && !atomic_compare_exchange_weak_explicit(&i_shm->shmf,
						   &isfull,
						   i_shm->logbuffers[isfull].next_full,
						   memory_order_acq_rel,
						   memory_order_relaxed))
    ;

  if (isfull == -1)
    return atrshmlog_error_read_fetch_3; /* No buffer on list */
  
  volatile atrshmlog_buffer_t* restrict b = &(i_shm->logbuffers[isfull]);

  *o_index_buffer = isfull;

  if (atrshmlog_thread_fence_4)
    atomic_thread_fence(memory_order_acquire);

  
  int state = atomic_load_explicit(&(b->state), memory_order_acquire);


  size_t size = b->shmsize;

  // We must use here the theoretical maximum size. period.
  if (size > ATRSHMLOGBUFFER_INFOSIZE)
    {
      result = atrshmlog_error_read_fetch_4;
      
      /* This is bad. Someone has spoiled the buffer */
      goto ende;
    }

  /* Ok. We are clear to go to copy */
  
  /* Is the length ok for copy */ 

  result = atrshmlog_error_read_fetch_5;
  
  if (size > 0)
    {
      ATRSHMLOGSTAT(atrshmlog_counter_read_fetch_doit);

      /* We have to do the copy now */

      start = ATRSHMLOG_GET_TSC_CALL();

      char* restrict source = (char*)i_shm + b->info;

      int old_chksum = b->chksum;
      
#if 1
      (void)memcpy(o_target, source, size );
#else
      for (int zippo = 0; zippo < size; zippo++)
	((char*)o_target)[zippo] = source[zippo];
      
#endif

      // we calc the checksum trivial. but this is ok for our needs
      if (atrshmlog_checksum)
	{
	  int chksum = 0;
	  
	  for (int k = 0; k < size; k++)
	    {
	      chksum += ((char*)o_target)[k];
	    }
	  
	  if (old_chksum != chksum)
	    {
	      ATRSHMLOGSTAT(atrshmlog_counter_fence_alarm_2);
	    }
	}
  
      *o_pid = b->pid;
      *o_tid = b->tid;
      *o_inittime = b->inittime;
      *o_inittimetsc_before = b->inittimetsc_before;
      *o_inittimetsc_after = b->inittimetsc_after;
      *o_lasttime = b->lasttime;
      *o_lasttimetsc_before = b->lasttimetsc_before;
      *o_lasttimetsc_after = b->lasttimetsc_after;
      *o_target_length = size;
      *o_starttransfer = b->starttransfer;
      *o_acquiretime = b->acquiretime;
      *o_id = b->id;
      *o_number_dispatched = b->number_dispatched;
      *o_counter_write0 = b->counter_write0;
      *o_counter_write0_discard = b->counter_write0_discard;
      *o_counter_write0_wait = b->counter_write0_wait;
      *o_counter_write0_adaptive = b->counter_write0_adaptive;
      *o_counter_write0_adaptive_fast = b->counter_write0_adaptive_fast;
      *o_counter_write0_adaptive_very_fast = b->counter_write0_adaptive_very_fast;
      *o_counter_write1 = b->counter_write1;
      *o_counter_write1_discard = b->counter_write1_discard;
      *o_counter_write1_wait = b->counter_write1_wait;
      *o_counter_write1_adaptive = b->counter_write1_adaptive;
      *o_counter_write1_adaptive_fast = b->counter_write1_adaptive_fast;
      *o_counter_write1_adaptive_very_fast = b->counter_write1_adaptive_very_fast;
      *o_counter_write2 = b->counter_write2;
      *o_counter_write2_discard = b->counter_write2_discard;
      *o_counter_write2_wait = b->counter_write2_wait;
      *o_counter_write2_adaptive = b->counter_write2_adaptive;
      *o_counter_write2_adaptive_fast = b->counter_write2_adaptive_fast;
      *o_counter_write2_adaptive_very_fast = b->counter_write2_adaptive_very_fast;
      
      b->next_full = -1;

      end = ATRSHMLOG_GET_TSC_CALL();

      *o_difftimetransfer = (end - start);

      result = atrshmlog_error_ok; /* We have succesful transfered a buffer */

    }

 ende:

  b->shmsize =  0;

  atomic_store_explicit(&b->state, atrshmlog_writeable, memory_order_release);

  /* We push it now on the available list again */

  b->next_append = atomic_load_explicit(&i_shm->shma, memory_order_acquire);
      
  while (!atomic_compare_exchange_weak_explicit(&i_shm->shma,
						(int*)&b->next_append,
						isfull,
						memory_order_release,
						memory_order_relaxed))
    ;

  return result;
}
/** 
 * \n Main code:
 *
 * \brief This is the actual reader function now.
 * 
 * It transfers the top buffer of the f list in shm.
 * 
 * So if there are buffers it delivers a transfered buffer and puts the 
 * shm buffer on the a list again.
 * 
 *  The memory is transfered into the reader process.
 *
 * so the reader then has to handle it.
 *
 * test t_read_fetch.c
 */
\n Main code:
\brief This is the actual reader function now.

It transfers the top buffer of the f list in shm.

So if there are buffers it delivers a transfered buffer and puts the
shm buffer on the a list again.

The memory is transfered into the reader process.

so the reader then has to handle it.


\ n Main code : \ brief This is the actual reader function now . It transfers the top buffer of the f list in shm . So if there are buffers it delivers a transfered buffer and puts the shm buffer on the a list again . The memory is transfered into the reader process . so the reader then has to handle it .
atrshmlog_ret_t atrshmlog_read_fetch(volatile const void* const i_area,
				     atrshmlog_int32_t * const o_index_buffer,
				     void * const o_target,
				     atrshmlog_int32_t * const o_target_length,
				     atrshmlog_pid_t* const o_pid,
				     atrshmlog_tid_t* const o_tid,
				     atrshmlog_internal_time_t* const o_inittime,
				     atrshmlog_time_t* const o_inittimetsc_before,
				     atrshmlog_time_t* const o_inittimetsc_after,
				     atrshmlog_internal_time_t* const o_lasttime,
				     atrshmlog_time_t* const o_lasttimetsc_before,
				     atrshmlog_time_t* const o_lasttimetsc_after,
				     atrshmlog_time_t* const o_difftimetransfer,
				     atrshmlog_time_t* const o_starttransfer,
				     atrshmlog_time_t* const o_acquiretime,
				     atrshmlog_int32_t* const o_id,
				     atrshmlog_int32_t* const o_number_dispatched,
				     atrshmlog_int32_t* const o_counter_write0,
				     atrshmlog_int32_t* const o_counter_write0_discard,
				     atrshmlog_int32_t* const o_counter_write0_wait,
				     atrshmlog_int32_t* const o_counter_write0_adaptive,
				     atrshmlog_int32_t* const o_counter_write0_adaptive_fast,
				     atrshmlog_int32_t* const o_counter_write0_adaptive_very_fast,
				     atrshmlog_int32_t* const o_counter_write1,
				     atrshmlog_int32_t* const o_counter_write1_discard,
				     atrshmlog_int32_t* const o_counter_write1_wait,
				     atrshmlog_int32_t* const o_counter_write1_adaptive,
				     atrshmlog_int32_t* const o_counter_write1_adaptive_fast,
				     atrshmlog_int32_t* const o_counter_write1_adaptive_very_fast,
				     atrshmlog_int32_t* const o_counter_write2,
				     atrshmlog_int32_t* const o_counter_write2_discard,
				     atrshmlog_int32_t* const o_counter_write2_wait,
				     atrshmlog_int32_t* const o_counter_write2_adaptive,
				     atrshmlog_int32_t* const o_counter_write2_adaptive_fast,
				     atrshmlog_int32_t* const o_counter_write2_adaptive_very_fast
				     )
{
  ATRSHMLOGSTAT(atrshmlog_counter_read_fetch);
  *o_target_length = 0;
  atrshmlog_time_t start;
  atrshmlog_time_t end;
  int result = -1;
  if(i_area == 0)
    return atrshmlog_error_read_fetch_1;
  volatile atrshmlog_area_t * restrict i_shm = (volatile atrshmlog_area_t*)i_area;
  atrshmlog_g_tl_t* g  = (atrshmlog_g_tl_t* )atrshmlog_get_thread_locals_adress();
#if ATRSHMLOG_THREAD_LOCAL == 0
  if (g == NULL)
    return atrshmlog_error_read_fetch_6;
#endif
  if (g->atrshmlog_idnotok)
    {
      int tlret = atrshmlog_init_thread_local (g);
      if (tlret)
	return tlret;
    }
  if (i_shm->shmsafeguard != ATRSHMLOGSAFEGUARDVALUE)
    return atrshmlog_error_read_fetch_2;
  int isfull = atomic_load_explicit(&i_shm->shmf, memory_order_consume);
  if (isfull == -1)
    return atrshmlog_error_read_fetch_3; 
  while (isfull > -1
	 && !atomic_compare_exchange_weak_explicit(&i_shm->shmf,
						   &isfull,
						   i_shm->logbuffers[isfull].next_full,
						   memory_order_acq_rel,
						   memory_order_relaxed))
    ;
  if (isfull == -1)
    return atrshmlog_error_read_fetch_3; 
  volatile atrshmlog_buffer_t* restrict b = &(i_shm->logbuffers[isfull]);
  *o_index_buffer = isfull;
  if (atrshmlog_thread_fence_4)
    atomic_thread_fence(memory_order_acquire);
  int state = atomic_load_explicit(&(b->state), memory_order_acquire);
  size_t size = b->shmsize;
  if (size > ATRSHMLOGBUFFER_INFOSIZE)
    {
      result = atrshmlog_error_read_fetch_4;
      goto ende;
    }
  result = atrshmlog_error_read_fetch_5;
  if (size > 0)
    {
      ATRSHMLOGSTAT(atrshmlog_counter_read_fetch_doit);
      start = ATRSHMLOG_GET_TSC_CALL();
      char* restrict source = (char*)i_shm + b->info;
      int old_chksum = b->chksum;
#if 1
      (void)memcpy(o_target, source, size );
#else
      for (int zippo = 0; zippo < size; zippo++)
	((char*)o_target)[zippo] = source[zippo];
#endif
      if (atrshmlog_checksum)
	{
	  int chksum = 0;
	  for (int k = 0; k < size; k++)
	    {
	      chksum += ((char*)o_target)[k];
	    }
	  if (old_chksum != chksum)
	    {
	      ATRSHMLOGSTAT(atrshmlog_counter_fence_alarm_2);
	    }
	}
      *o_pid = b->pid;
      *o_tid = b->tid;
      *o_inittime = b->inittime;
      *o_inittimetsc_before = b->inittimetsc_before;
      *o_inittimetsc_after = b->inittimetsc_after;
      *o_lasttime = b->lasttime;
      *o_lasttimetsc_before = b->lasttimetsc_before;
      *o_lasttimetsc_after = b->lasttimetsc_after;
      *o_target_length = size;
      *o_starttransfer = b->starttransfer;
      *o_acquiretime = b->acquiretime;
      *o_id = b->id;
      *o_number_dispatched = b->number_dispatched;
      *o_counter_write0 = b->counter_write0;
      *o_counter_write0_discard = b->counter_write0_discard;
      *o_counter_write0_wait = b->counter_write0_wait;
      *o_counter_write0_adaptive = b->counter_write0_adaptive;
      *o_counter_write0_adaptive_fast = b->counter_write0_adaptive_fast;
      *o_counter_write0_adaptive_very_fast = b->counter_write0_adaptive_very_fast;
      *o_counter_write1 = b->counter_write1;
      *o_counter_write1_discard = b->counter_write1_discard;
      *o_counter_write1_wait = b->counter_write1_wait;
      *o_counter_write1_adaptive = b->counter_write1_adaptive;
      *o_counter_write1_adaptive_fast = b->counter_write1_adaptive_fast;
      *o_counter_write1_adaptive_very_fast = b->counter_write1_adaptive_very_fast;
      *o_counter_write2 = b->counter_write2;
      *o_counter_write2_discard = b->counter_write2_discard;
      *o_counter_write2_wait = b->counter_write2_wait;
      *o_counter_write2_adaptive = b->counter_write2_adaptive;
      *o_counter_write2_adaptive_fast = b->counter_write2_adaptive_fast;
      *o_counter_write2_adaptive_very_fast = b->counter_write2_adaptive_very_fast;
      b->next_full = -1;
      end = ATRSHMLOG_GET_TSC_CALL();
      *o_difftimetransfer = (end - start);
      result = atrshmlog_error_ok; 
    }
 ende:
  b->shmsize =  0;
  atomic_store_explicit(&b->state, atrshmlog_writeable, memory_order_release);
  b->next_append = atomic_load_explicit(&i_shm->shma, memory_order_acquire);
  while (!atomic_compare_exchange_weak_explicit(&i_shm->shma,
						(int*)&b->next_append,
						isfull,
						memory_order_release,
						memory_order_relaxed))
    ;
  return result;
}
atrshmlog_ret_t atrshmlog_read_fetch ( volatile const void * const i_area , atrshmlog_int32_t * const o_index_buffer , void * const o_target , atrshmlog_int32_t * const o_target_length , atrshmlog_pid_t * const o_pid , atrshmlog_tid_t * const o_tid , atrshmlog_internal_time_t * const o_inittime , atrshmlog_time_t * const o_inittimetsc_before , atrshmlog_time_t * const o_inittimetsc_after , atrshmlog_internal_time_t * const o_lasttime , atrshmlog_time_t * const o_lasttimetsc_before , atrshmlog_time_t * const o_lasttimetsc_after , atrshmlog_time_t * const o_difftimetransfer , atrshmlog_time_t * const o_starttransfer , atrshmlog_time_t * const o_acquiretime , atrshmlog_int32_t * const o_id , atrshmlog_int32_t * const o_number_dispatched , atrshmlog_int32_t * const o_counter_write0 , atrshmlog_int32_t * const o_counter_write0_discard , atrshmlog_int32_t * const o_counter_write0_wait , atrshmlog_int32_t * const o_counter_write0_adaptive , atrshmlog_int32_t * const o_counter_write0_adaptive_fast , atrshmlog_int32_t * const o_counter_write0_adaptive_very_fast , atrshmlog_int32_t * const o_counter_write1 , atrshmlog_int32_t * const o_counter_write1_discard , atrshmlog_int32_t * const o_counter_write1_wait , atrshmlog_int32_t * const o_counter_write1_adaptive , atrshmlog_int32_t * const o_counter_write1_adaptive_fast , atrshmlog_int32_t * const o_counter_write1_adaptive_very_fast , atrshmlog_int32_t * const o_counter_write2 , atrshmlog_int32_t * const o_counter_write2_discard , atrshmlog_int32_t * const o_counter_write2_wait , atrshmlog_int32_t * const o_counter_write2_adaptive , atrshmlog_int32_t * const o_counter_write2_adaptive_fast , atrshmlog_int32_t * const o_counter_write2_adaptive_very_fast ) { ATRSHMLOGSTAT ( atrshmlog_counter_read_fetch ) ; * o_target_length = 0 ; atrshmlog_time_t start ; atrshmlog_time_t end ; int result = -1 ; if ( i_area == 0 ) return atrshmlog_error_read_fetch_1 ; volatile atrshmlog_area_t * restrict i_shm = ( volatile atrshmlog_area_t * ) i_area ; atrshmlog_g_tl_t * g = ( atrshmlog_g_tl_t * ) atrshmlog_get_thread_locals_adress ( ) ; #if ATRSHMLOG_THREAD_LOCAL == 0 if ( g == NULL ) return atrshmlog_error_read_fetch_6 ; #endif if ( g -> atrshmlog_idnotok ) { int tlret = atrshmlog_init_thread_local ( g ) ; if ( tlret ) return tlret ; } if ( i_shm -> shmsafeguard != ATRSHMLOGSAFEGUARDVALUE ) return atrshmlog_error_read_fetch_2 ; int isfull = atomic_load_explicit ( & i_shm -> shmf , memory_order_consume ) ; if ( isfull == -1 ) return atrshmlog_error_read_fetch_3 ; while ( isfull > -1 && ! atomic_compare_exchange_weak_explicit ( & i_shm -> shmf , & isfull , i_shm -> logbuffers [ isfull ] . next_full , memory_order_acq_rel , memory_order_relaxed ) ) ; if ( isfull == -1 ) return atrshmlog_error_read_fetch_3 ; volatile atrshmlog_buffer_t * restrict b = & ( i_shm -> logbuffers [ isfull ] ) ; * o_index_buffer = isfull ; if ( atrshmlog_thread_fence_4 ) atomic_thread_fence ( memory_order_acquire ) ; int state = atomic_load_explicit ( & ( b -> state ) , memory_order_acquire ) ; size_t size = b -> shmsize ; if ( size > ATRSHMLOGBUFFER_INFOSIZE ) { result = atrshmlog_error_read_fetch_4 ; goto ende ; } result = atrshmlog_error_read_fetch_5 ; if ( size > 0 ) { ATRSHMLOGSTAT ( atrshmlog_counter_read_fetch_doit ) ; start = ATRSHMLOG_GET_TSC_CALL ( ) ; char * restrict source = ( char * ) i_shm + b -> info ; int old_chksum = b -> chksum ; #if 1 ( void ) memcpy ( o_target , source , size ) ; #else for ( int zippo = 0 ; zippo < size ; zippo ++ ) ( ( char * ) o_target ) [ zippo ] = source [ zippo ] ; #endif if ( atrshmlog_checksum ) { int chksum = 0 ; for ( int k = 0 ; k < size ; k ++ ) { chksum += ( ( char * ) o_target ) [ k ] ; } if ( old_chksum != chksum ) { ATRSHMLOGSTAT ( atrshmlog_counter_fence_alarm_2 ) ; } } * o_pid = b -> pid ; * o_tid = b -> tid ; * o_inittime = b -> inittime ; * o_inittimetsc_before = b -> inittimetsc_before ; * o_inittimetsc_after = b -> inittimetsc_after ; * o_lasttime = b -> lasttime ; * o_lasttimetsc_before = b -> lasttimetsc_before ; * o_lasttimetsc_after = b -> lasttimetsc_after ; * o_target_length = size ; * o_starttransfer = b -> starttransfer ; * o_acquiretime = b -> acquiretime ; * o_id = b -> id ; * o_number_dispatched = b -> number_dispatched ; * o_counter_write0 = b -> counter_write0 ; * o_counter_write0_discard = b -> counter_write0_discard ; * o_counter_write0_wait = b -> counter_write0_wait ; * o_counter_write0_adaptive = b -> counter_write0_adaptive ; * o_counter_write0_adaptive_fast = b -> counter_write0_adaptive_fast ; * o_counter_write0_adaptive_very_fast = b -> counter_write0_adaptive_very_fast ; * o_counter_write1 = b -> counter_write1 ; * o_counter_write1_discard = b -> counter_write1_discard ; * o_counter_write1_wait = b -> counter_write1_wait ; * o_counter_write1_adaptive = b -> counter_write1_adaptive ; * o_counter_write1_adaptive_fast = b -> counter_write1_adaptive_fast ; * o_counter_write1_adaptive_very_fast = b -> counter_write1_adaptive_very_fast ; * o_counter_write2 = b -> counter_write2 ; * o_counter_write2_discard = b -> counter_write2_discard ; * o_counter_write2_wait = b -> counter_write2_wait ; * o_counter_write2_adaptive = b -> counter_write2_adaptive ; * o_counter_write2_adaptive_fast = b -> counter_write2_adaptive_fast ; * o_counter_write2_adaptive_very_fast = b -> counter_write2_adaptive_very_fast ; b -> next_full = -1 ; end = ATRSHMLOG_GET_TSC_CALL ( ) ; * o_difftimetransfer = ( end - start ) ; result = atrshmlog_error_ok ; } ende : b -> shmsize = 0 ; atomic_store_explicit ( & b -> state , atrshmlog_writeable , memory_order_release ) ; b -> next_append = atomic_load_explicit ( & i_shm -> shma , memory_order_acquire ) ; while ( ! atomic_compare_exchange_weak_explicit ( & i_shm -> shma , ( int * ) & b -> next_append , isfull , memory_order_release , memory_order_relaxed ) ) ; return result ; }
\n Main code:
 \brief This is the actual reader function now.
\ n Main code : \ brief This is the actual reader function now .
// we do here a terrible thing. // we cast const away. // but its ok here. /* Ok. We can now do the transfer */ // this can happen if thread specific is in /* From now on we are the not ok flag */ /* We pop from list */ /* No buffer on list */ /* No buffer on list */ // We must use here the theoretical maximum size. period. /* This is bad. Someone has spoiled the buffer */ /* Ok. We are clear to go to copy */ /* Is the length ok for copy */ /* We have to do the copy now */ // we calc the checksum trivial. but this is ok for our needs /* We have succesful transfered a buffer */ /* We push it now on the available list again */