Skip to content
Snippets Groups Projects
defs_common.h 42.3 KiB
Newer Older
                              uint8_t F,
                              time_stats_t *init_stats,
                              time_stats_t *alpha_stats,
                              time_stats_t *beta_stats,
                              time_stats_t *gamma_stats,
                              time_stats_t *ext_stats,
                              time_stats_t *intl1_stats,
                              time_stats_t *intl2_stats,
                              decode_abort_t *abort_decode);

typedef uint8_t(encoder_if_t)(uint8_t *input,
                              uint16_t input_length_bytes,
                              uint8_t *output,
                              uint8_t F);

extern int oai_exit;

static inline void wait_sync(char *thread_name) {
  int rc;
  printf( "waiting for sync (%s,%d/%p,%p,%p)\n",thread_name,sync_var,&sync_var,&sync_cond,&sync_mutex);
  AssertFatal((rc = pthread_mutex_lock( &sync_mutex ))==0,"sync mutex lock error");

  while (sync_var<0 && !oai_exit)
    pthread_cond_wait( &sync_cond, &sync_mutex );

  AssertFatal((rc = pthread_mutex_unlock( &sync_mutex ))==0,"sync mutex unlock error");
  printf( "got sync (%s)\n", thread_name);
  /*
   * Raphael Defosseux: added for CI to get faster the got sync message.
   */
  fflush(stdout);
  fflush(stderr);
}


static inline int wakeup_thread(pthread_mutex_t *mutex,
                                pthread_cond_t *cond,
                                int *instance_cnt,
                                char *name,
                                int sleeptime,
                                int sleep_cnt_max) {
  int rc;
  int sleep_cnt=0;
  AssertFatal((rc = pthread_mutex_lock(mutex))==0,"wakeup_thread(): error locking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);

  while (*instance_cnt == 0 && !oai_exit) {
    AssertFatal((rc = pthread_mutex_unlock(mutex))==0,"wakeup_thread(): error unlocking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);
    sleep_cnt++;

    if (sleep_cnt>sleep_cnt_max) return(-1);

    usleep(sleeptime);
    AssertFatal((rc = pthread_mutex_lock(mutex))==0,"wakeup_thread(): error locking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);
  }

  *instance_cnt = *instance_cnt + 1;
  AssertFatal((rc = pthread_mutex_unlock(mutex))==0,"wakeup_thread(): error unlocking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);

  // the thread can now be woken up
  if (pthread_cond_signal(cond) != 0) {
    LOG_E( PHY, "ERROR pthread_cond_signal\n");
    exit_fun( "ERROR pthread_cond_signal" );
    return(-1);
  }

  AssertFatal((rc = pthread_mutex_unlock(mutex))==0,"wakeup_thread(): error unlocking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);
  return(0);
}


static inline int timedwait_on_condition(pthread_mutex_t *mutex,
    pthread_cond_t *cond,
    int *instance_cnt,
    char *name,
    uint32_t time_ns) {
  int rc;
  int waitret=0;
  struct timespec now, abstime;
  AssertFatal((rc = pthread_mutex_lock(mutex))==0,"[SCHED][eNB] timedwait_on_condition(): error locking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);

  while (*instance_cnt < 0 && !oai_exit) {
    clock_gettime(CLOCK_REALTIME, &now);
    // most of the time the thread is waiting here
    // proc->instance_cnt_rxtx is -1
    abstime.tv_sec = now.tv_sec;
    abstime.tv_nsec = now.tv_nsec + time_ns;

    if (abstime.tv_nsec >= 1000*1000*1000) {
      abstime.tv_nsec -= 1000*1000*1000;
      abstime.tv_sec  += 1;
    }

    if ((waitret = pthread_cond_timedwait(cond,mutex,&abstime)) == 0) break; // this unlocks mutex_rxtx while waiting and then locks it again
  }

  AssertFatal((rc = pthread_mutex_unlock(mutex)) == 0,"[SCHED][eNB] timedwait_on_condition(): error unlocking mutex return %d for %s\n", rc, name);
  return(waitret);
}


static inline int wait_on_condition(pthread_mutex_t *mutex,
                                    pthread_cond_t *cond,
                                    int *instance_cnt,
                                    char *name) {
  int rc;
  AssertFatal((rc = pthread_mutex_lock(mutex))==0,"[SCHED][eNB] wait_on_condition(): error locking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);

  while (*instance_cnt < 0 && !oai_exit) {
    // most of the time the thread is waiting here
    // proc->instance_cnt_rxtx is -1
    pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again
  }

  AssertFatal((rc = pthread_mutex_unlock(mutex))==0,"[SCHED][eNB] wait_on_condition(): error unlocking mutex return %d for %s\n", rc, name);
  return(0);
}


static inline int wait_on_busy_condition(pthread_mutex_t *mutex,
    pthread_cond_t *cond,
    int *instance_cnt,
    char *name) {
  int rc;
  AssertFatal((rc = pthread_mutex_lock(mutex))==0,"[SCHED][eNB] wait_on_busy_condition(): error locking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);

  while (*instance_cnt == 0 && !oai_exit) {
    // most of the time the thread will skip this
    // waits only if proc->instance_cnt_rxtx is 0
    pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again
  }

  AssertFatal((rc = pthread_mutex_unlock(mutex))==0,"[SCHED][eNB] wait_on_busy_condition(): error unlocking mutex return %d for %s\n", rc, name);
  return(0);
}


static inline int release_thread(pthread_mutex_t *mutex,
                                 int *instance_cnt,
                                 char *name) {
  int rc;
  AssertFatal((rc = pthread_mutex_lock(mutex))==0,"[SCHED][eNB] release_thread(): error locking mutex for %s (%d %s, %p)\n", name, rc, strerror(rc), (void *)mutex);
  *instance_cnt=-1;
  AssertFatal((rc = pthread_mutex_unlock(mutex))==0,"[SCHED][eNB] release_thread(): error unlocking mutex return %d for %s\n", rc, name);
  return(0);
}

#endif //  __PHY_DEFS_COMMON_H__