Пример #1
0
static inline lagopus_result_t
s_create(null_thread_t *nptr, a_obj_t o) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  if (nptr != NULL) {
    if ((ret = lagopus_thread_create((lagopus_thread_t *)nptr,
                                     s_main, s_finalize, NULL,
                                     "waiter", NULL)) == LAGOPUS_RESULT_OK) {
      if ((ret = lagopus_mutex_create(&((*nptr)->m_lock))) ==
          LAGOPUS_RESULT_OK) {
        (*nptr)->m_o = o;
      } else {
        lagopus_perror(ret);
        goto done;
      }
    } else {
      lagopus_perror(ret);
      goto done;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

done:
  return ret;
}
Пример #2
0
static inline bool
s_initialize(test_thread_t tt, size_t n) {
  bool ret = false;

  if (tt != NULL) {
    tt->m_data = (int *)malloc(n * sizeof(int));
    if (tt->m_data != NULL) {
      lagopus_result_t r;
      if ((r = lagopus_mutex_create(&(tt->m_lock))) != LAGOPUS_RESULT_OK) {
        lagopus_perror(r);
        goto initfailure;
      }
      if ((r = lagopus_thread_create((lagopus_thread_t *)&tt,
                                     s_test_thread_main,
                                     s_test_thread_finalize,
                                     s_test_thread_destroy,
                                     "test", NULL)) != LAGOPUS_RESULT_OK) {
        lagopus_perror(r);
        goto initfailure;
      }
      tt->m_n_data = n;
      tt->m_is_operational = false;
      tt->m_stop_requested = false;

      ret = true;
    }
  initfailure:
    if (ret != true) {
      free((void *)tt->m_data);
    }
  }

  return ret;
}
Пример #3
0
static inline callout_arg_t
s_alloc_arg(size_t n_stop, lagopus_chrono_t wait_nsec) {
  callout_arg_t ret = NULL;
  lagopus_result_t r;
  lagopus_mutex_t lock = NULL;
  lagopus_cond_t cond = NULL;

  if (likely((r = lagopus_mutex_create(&lock)) != LAGOPUS_RESULT_OK)) {
    goto done;
  }
  if (likely((r = lagopus_cond_create(&cond)) != LAGOPUS_RESULT_OK)) {
    goto done;
  }

  ret = (callout_arg_t)malloc(sizeof(*ret));
  if (ret == NULL) {
    goto done;
  }

  (void)memset((void *)ret, 0, sizeof(*ret));
  ret->m_lock = lock;
  ret->m_cond = cond;
  ret->m_wait_nsec = wait_nsec;
  ret->m_last_exec_abstime = 0LL;
  ret->m_n_exec = 0LL;
  ret->m_n_stop = n_stop;
  ret->m_is_freeuped = false;

done:
  return ret;
}
Пример #4
0
static lagopus_result_t
s_setup(const lagopus_pipeline_stage_t *sptr) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  test_stage_t t = (test_stage_t)(*sptr);

  lagopus_msg_debug(1, "called.\n");

  t->m_counts = (size_t *)malloc(sizeof(size_t) *
                                 t->m_stg.m_n_workers);
  if (t->m_counts != NULL &&
      (ret = lagopus_mutex_create(&(t->m_lock))) == LAGOPUS_RESULT_OK) {
    size_t i;

    for (i = 0; i < t->m_stg.m_n_workers; i++) {
      t->m_counts[i] = 0LL;
    }

    ret = LAGOPUS_RESULT_OK;
  } else {
    if (t->m_counts == NULL) {
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }
  }

  return ret;
}
Пример #5
0
static void
s_once_proc(void) {
  lagopus_result_t r;

  if ((r = lagopus_mutex_create(&s_sched_lck)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize the callout scheduler main mutex.\n");
  }

  if ((r = lagopus_mutex_create(&s_lck)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize the callout global mutex.\n");
  }

  if ((r = lagopus_cond_create(&s_sched_cnd)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize the callout cond.\n");
  }

  if ((r = lagopus_hashmap_create(&s_tsk_tbl,
                                  LAGOPUS_HASHMAP_TYPE_ONE_WORD,
                                  NULL)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize the callout table.\n");
  }

  if ((r = lagopus_bbq_create(&s_urgent_tsk_q, lagopus_callout_task_t,
                              CALLOUT_TASK_MAX, s_task_freeup)) != 
      LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize the callout urgent tasks queue.\n");
  }

  if ((r = lagopus_bbq_create(&s_idle_tsk_q, lagopus_callout_task_t,
                              CALLOUT_TASK_MAX, s_task_freeup)) !=
      LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize the callout idle tasks queue.\n");
  }

  if ((r = lagopus_mutex_create_recursive(&s_q_lck)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize the callout task queue mutex.\n");
  }

  TAILQ_INIT(&s_chrono_tsk_q);
}
Пример #6
0
void
setUp(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  do_stop = false;
  called_counter_reset();

  ret = lagopus_mutex_create(&lock);
  TEST_ASSERT_EQUAL_MESSAGE(LAGOPUS_RESULT_OK, ret,
                            "lagopus_mutex_create error.");
}
Пример #7
0
static void
s_once_proc(void) {
  lagopus_result_t r;
  s_n_modules = 0;
  (void)memset((void *)s_modules, sizeof(s_modules), 0);

  if ((r = lagopus_mutex_create(&s_lck)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize a mutex.\n");
  }
}
Пример #8
0
static void
initialize_internal(void) {
  lagopus_result_t ret;

  ret = lagopus_mutex_create(&lock);
  if (ret != LAGOPUS_RESULT_OK) {
    lagopus_exit_fatal("session_tls_init:lagopus_mutex_create");
  }

  SSL_library_init();
  SSL_load_error_strings();
}
Пример #9
0
lagopus_result_t
lagopus_cbuffer_create_with_size(lagopus_cbuffer_t *cbptr,
                                 size_t elemsize,
                                 int64_t maxelems,
                                 lagopus_cbuffer_value_freeup_proc_t proc) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  if (cbptr != NULL &&
      elemsize > 0 &&
      maxelems > 0) {
    lagopus_cbuffer_t cb = (lagopus_cbuffer_t)malloc(
                             sizeof(*cb) + elemsize * (size_t)(maxelems + N_EMPTY_ROOM));

    *cbptr = NULL;

    if (cb != NULL) {
      if (((ret = lagopus_mutex_create(&(cb->m_lock))) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_cond_create(&(cb->m_cond_put))) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_cond_create(&(cb->m_cond_get))) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_cond_create(&(cb->m_cond_awakened))) ==
           LAGOPUS_RESULT_OK)) {
        cb->m_r_idx = 0;
        cb->m_w_idx = 0;
        cb->m_n_elements = 0;
        cb->m_n_waiters = 0;
        cb->m_n_max_elements = maxelems;
        cb->m_n_max_allocd_elements = maxelems + N_EMPTY_ROOM;
        cb->m_element_size = elemsize;
        cb->m_del_proc = proc;
        cb->m_is_operational = true;
        cb->m_is_awakened = false;
        cb->m_qmuxer = NULL;
        cb->m_type = LAGOPUS_QMUXER_POLL_UNKNOWN;

        *cbptr = cb;

        ret = LAGOPUS_RESULT_OK;

      } else {
        free((void *)cb);
      }
    } else {
      ret = LAGOPUS_RESULT_NO_MEMORY;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Пример #10
0
static inline lagopus_result_t
atomic_cmd_initialize(void) {
    lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

    /* create lock. */
    if ((ret = lagopus_mutex_create(&lock)) !=
            LAGOPUS_RESULT_OK) {
        lagopus_perror(ret);
    }

    return ret;
}
Пример #11
0
lagopus_result_t
dataplane_initialize(int argc,
                     const char *const argv[],
                     __UNUSED void *extarg,
                     lagopus_thread_t **thdptr) {
#ifdef HAVE_DPDK
  static struct dataplane_arg dparg;
#endif /* HAVE_DPDK */
  static struct dataplane_arg sockarg;
  static struct dataplane_arg timerarg;
  lagopus_result_t nb_ports;

  nb_ports = lagopus_dataplane_init(argc, argv);
  if (nb_ports < 0) {
    lagopus_msg_fatal("lagopus_dataplane_init failed\n");
    return nb_ports;
  }
  dp_api_init();
#ifdef HAVE_DPDK
  if (rawsocket_only_mode != true) {
    dparg.threadptr = &dpdk_thread;
    dparg.lock = &dpdk_lock;
    lagopus_thread_create(&dpdk_thread, dpdk_thread_loop,
                          dp_finalproc, dp_freeproc, "dataplane", &dparg);

    if (lagopus_mutex_create(&dpdk_lock) != LAGOPUS_RESULT_OK) {
      lagopus_exit_fatal("lagopus_mutex_create");
    }
  }
#endif /* HAVE_DPDK */

  lagopus_meter_init();
  lagopus_register_action_hook = lagopus_set_action_function;
  lagopus_register_instruction_hook = lagopus_set_instruction_function;
  flowinfo_init();

  timerarg.threadptr = &timer_thread;
  timerarg.lock = &timer_lock;
  timerarg.running = NULL;
  timerthread_initialize(&timerarg);

  sockarg.threadptr = &sock_thread;
  sockarg.lock = &sock_lock;
  sockarg.running = NULL;
  sockthread_initialize(&sockarg);

  *thdptr = &sock_thread;

  return LAGOPUS_RESULT_OK;
}
Пример #12
0
static inline a_obj_t
a_obj_create(void) {
  a_obj_t ret = (a_obj_t)malloc(sizeof(*ret));

  if (ret != NULL) {
    if (lagopus_mutex_create(&(ret->m_lock)) == LAGOPUS_RESULT_OK) {
      ret->m_bool = false;
    } else {
      free((void *)ret);
      ret = NULL;
    }
  }

  return ret;
}
Пример #13
0
static void
s_once_proc(void) {
  lagopus_result_t r;

  if ((r = lagopus_mutex_create(&s_lck)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("Can't initilize a mutex.\n");
  }
  if ((r = lagopus_cond_create(&s_cond)) !=  LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("Can't initilize a cond.\n");
  }

  (void)pthread_atfork(NULL, NULL, s_child_at_fork);
}
Пример #14
0
static void
initialize_internal(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  /* create hashmap */
  ret = lagopus_hashmap_create(&bridgeq_table,
                               LAGOPUS_HASHMAP_TYPE_ONE_WORD,
                               bridgeq_freeup_proc);
  if (ret != LAGOPUS_RESULT_OK) {
    lagopus_exit_fatal("Can't create bridgeq table.\n");
  }

  ret = lagopus_mutex_create(&lock);
  if (ret != LAGOPUS_RESULT_OK) {
    lagopus_exit_fatal("Can't create lock.\n");
  }
}
Пример #15
0
static void
initialize_internal(void) {
  lagopus_result_t ret;

  ret = lagopus_mutex_create(&lock);
  if (ret != LAGOPUS_RESULT_OK) {
    lagopus_exit_fatal("channel_mgr_initialize:lagopus_mutex_create");
  }

  ret = lagopus_hashmap_create(&main_table, LAGOPUS_HASHMAP_TYPE_STRING,
                               channel_entry_free);
  if (ret != LAGOPUS_RESULT_OK) {
    lagopus_exit_fatal("channel_mgr_initialize:lagopus_hashmap_create");
  }

  ret = lagopus_hashmap_create(&dp_table, LAGOPUS_HASHMAP_TYPE_ONE_WORD,
                               channel_list_entry_free);
  if (ret != LAGOPUS_RESULT_OK) {
    lagopus_exit_fatal("channel_mgr_initialize:lagopus_hashmap_create");
  }

}
Пример #16
0
static void
s_once_proc(void) {
  lagopus_result_t r;

  lagopus_msg_debug(5, "called.\n");

  if ((r = lagopus_mutex_create(&s_lck)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't initialize a mutex.\n");
  }

  if ((r = lagopus_module_register(MY_MOD_NAME,
                                   dummy_module_initialize, NULL,
                                   dummy_module_start,
                                   dummy_module_shutdown,
                                   dummy_module_stop,
                                   dummy_module_finalize,
                                   dummy_module_usage)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    lagopus_exit_fatal("can't register the %s module.\n", MY_MOD_NAME);
  }
}
Пример #17
0
static void
initialize_internal(void) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  void *logger_client_arg = NULL;
  char *master_agentx_socket = NULL;
  char *ping_interval_string = NULL;
  uint16_t ping_interval = 0;

  state = SNMPMGR_NONE;

  /* `is_thread` is able to be changed only once here */
  is_thread = is_thread_dummy;
  if (is_thread == false && thdptr_dummy != NULL) {
    *thdptr_dummy = NULL;
  } else if (thdptr_dummy != NULL) {
    *thdptr_dummy = &snmpmgr;
  } else {
    /* never reached! */
    return;
  }

  if (lagopus_mutex_create(&snmp_lock) != LAGOPUS_RESULT_OK) {
    return;
  }

  if (lagopus_mutex_create(&snmp_state_lock) != LAGOPUS_RESULT_OK) {
    return;
  }

  snmp_set_do_debugging(false);

  /* setup Net-SNMP logger to use the lagopus logging function */
  if (snmp_register_callback(SNMP_CALLBACK_LIBRARY,
                             SNMP_CALLBACK_LOGGING,
                             snmp_log_callback_wrapper,
                             logger_client_arg) != SNMPERR_SUCCESS) {
    return;
  }
  snmp_enable_calllog();

  /* setup the SNMP module to be Agentx subagent */
  netsnmp_enable_subagent();

#ifdef THE_CONFSYS_ERA
  master_agentx_socket = config_get("snmp master-agentx-socket WORD");
  if (master_agentx_socket == NULL) {
    config_set_default("snmp master-agentx-socket WORD",
                       (char *)DEFAULT_SNMPMGR_AGENTX_SOCKET);
    master_agentx_socket = config_get("snmp master-agentx-socket WORD");
  }
#else
  /*
   * FIXME:
   *	Fetch it from the datastore.
   */
  master_agentx_socket = (char *)DEFAULT_SNMPMGR_AGENTX_SOCKET;
#endif /* THE_CONFSYS_ERA */
  lagopus_msg_debug(25, "master agentx socket is %s\n", master_agentx_socket);

  if (netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
                            NETSNMP_DS_AGENT_X_SOCKET,
                            master_agentx_socket)
      != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  /* don't read/write configuration files */
  if (netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                             NETSNMP_DS_LIB_DONT_PERSIST_STATE,
                             true) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }
  if (netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                             NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD,
                             true) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  /* the interval [sec] to send ping to AgentX master agent */
#ifdef THE_CONFSYS_ERA
  ping_interval_string = config_get("snmp ping-interval-second 1-255");
  if (ping_interval_string != NULL &&
      (ret = check_ping_interval(ping_interval_string, &ping_interval))
      != LAGOPUS_RESULT_OK) {
    config_set_default("snmp ping-interval-second 1-255",
                       (char *) __STR__(DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC));
    ping_interval_string = config_get("snmp ping-interval-second 1-255");
    ping_interval = DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC; /* default value */
  }
#else
  /*
   * FIXME:
   *	Fetch it from the datastore.
   */
  ping_interval = DEFAULT_SNMPMGR_AGENTX_PING_INTERVAL_SEC;
#endif /* THE_CONFSYS_ERA */

  if (netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
                         NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL,
                         (int)ping_interval)
      != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  if (init_agent(SNMP_TYPE) != SNMPERR_SUCCESS) {
    initialize_ret = LAGOPUS_RESULT_SNMP_API_ERROR;
    return;
  }

  if ((ret = lagopus_hashmap_create(&iftable_entry_hash,
                                    LAGOPUS_HASHMAP_TYPE_STRING,
                                    delete_entry)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(ret);
    exit(1);
  }

  init_ifTable();
  init_ifNumber();
  init_dot1dBaseBridgeAddress();
  init_dot1dBaseNumPorts();
  init_dot1dBasePortTable();
  init_dot1dBaseType();

  if (is_thread == false) {
    initialize_ret = LAGOPUS_RESULT_OK;
  } else {
    keep_running = true;
    initialize_ret = lagopus_thread_create(&snmpmgr,
                                           snmpmgr_thread_loop,
                                           snmpmgr_thread_finally_called,
                                           NULL,
                                           "snmpmgr",
                                           NULL);
  }

  lagopus_msg_info("SNMP manager initialized.\n");
}
Пример #18
0
static inline lagopus_result_t
s_init_stage(lagopus_pipeline_stage_t *sptr,
             const char *name,
             bool is_heap_allocd,
             size_t n_workers,
             size_t event_size,
             size_t max_batch_size,
             lagopus_pipeline_stage_pre_pause_proc_t pre_pause_proc,
             lagopus_pipeline_stage_sched_proc_t sched_proc,
             lagopus_pipeline_stage_setup_proc_t setup_proc,
             lagopus_pipeline_stage_fetch_proc_t fetch_proc,
             lagopus_pipeline_stage_main_proc_t main_proc,
             lagopus_pipeline_stage_throw_proc_t throw_proc,
             lagopus_pipeline_stage_shutdown_proc_t shutdown_proc,
             lagopus_pipeline_stage_finalize_proc_t final_proc,
             lagopus_pipeline_stage_freeup_proc_t freeup_proc) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  /*
   * Note that receiving a pipeline stage as a reference
   * (lagopus_pipeline_stage_t *) IS VERY IMPOETANT in order to
   * create workers by calling the s_worker_create().
   */

  if (sptr != NULL && *sptr != NULL) {
    lagopus_pipeline_stage_t ps = *sptr;
    worker_main_proc_t proc = s_find_worker_proc(fetch_proc,
                              main_proc,
                              throw_proc);
    if (proc != NULL) {

      (void)memset((void *)ps, 0, DEFAULT_STAGE_ALLOC_SZ);

      if (((ret = lagopus_mutex_create(&(ps->m_lock))) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_mutex_create(&(ps->m_final_lock))) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_cond_create(&(ps->m_cond))) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_barrier_create(&(ps->m_pause_barrier), n_workers)) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_mutex_create(&(ps->m_pause_lock))) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_cond_create(&(ps->m_pause_cond))) ==
           LAGOPUS_RESULT_OK) &&
          ((ret = lagopus_cond_create(&(ps->m_resume_cond))) ==
           LAGOPUS_RESULT_OK)) {
        if ((ps->m_name = strdup(name)) != NULL &&
            (ps->m_workers = (lagopus_pipeline_worker_t *)
                             malloc(sizeof(lagopus_pipeline_worker_t) * n_workers)) != NULL) {
          size_t i;

          ps->m_event_size = event_size;
          ps->m_max_batch = max_batch_size;
          ps->m_batch_buffer_size = event_size * max_batch_size;

          for (i = 0; i < n_workers && ret == LAGOPUS_RESULT_OK; i++) {
            ret = s_worker_create(&(ps->m_workers[i]), sptr, i, proc);
          }
          if (ret == LAGOPUS_RESULT_OK) {
            ps->m_pre_pause_proc = pre_pause_proc;
            ps->m_sched_proc = sched_proc;
            ps->m_setup_proc = setup_proc;
            ps->m_fetch_proc = fetch_proc;
            ps->m_main_proc = main_proc;
            ps->m_throw_proc = throw_proc;
            ps->m_shutdown_proc = shutdown_proc;
            ps->m_final_proc = final_proc;
            ps->m_freeup_proc = freeup_proc;

            ps->m_n_workers = n_workers;
            ps->m_is_heap_allocd = is_heap_allocd;

            ps->m_do_loop = false;
            ps->m_sg_lvl = SHUTDOWN_UNKNOWN;
            ps->m_status = STAGE_STATE_INITIALIZED;

            ps->m_n_canceled_workers = 0LL;
            ps->m_n_shutdown_workers = 0LL;

            ps->m_pause_requested = false;

            ps->m_maint_proc = NULL;
            ps->m_maint_arg = NULL;

            ps->m_post_start_proc = NULL;
            ps->m_post_start_arg = NULL;

            /*
             * finally.
             */
            ret = LAGOPUS_RESULT_OK;

          } else {
            size_t n_created = i;

            for (i = 0; i < n_created; i++) {
              s_worker_destroy(&(ps->m_workers[i]));
            }
          }
        } else {
          free((void *)(ps->m_name));
          ps->m_name = NULL;
          free((void *)(ps->m_workers));
          ps->m_workers = NULL;
          ret = LAGOPUS_RESULT_NO_MEMORY;
        }
      }
    } else {
      ret = LAGOPUS_RESULT_INVALID_ARGS;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Пример #19
0
static int
do_run(size_t nthds, ssize_t nputs) {
  int ret = 1;

  lagopus_result_t r;

  size_t i;
  size_t j;
  char thdname[16];

  lagopus_chrono_t *put_dates = NULL;

  size_t n_need_watch = 0;
  size_t n_valid_polls = 0;
  ssize_t qsz;

  test_thread_t tt;
  lagopus_bbq_t bbq;

  lagopus_chrono_t t_begin;
  lagopus_chrono_t t_end;

  lagopus_chrono_t p_begin;
  lagopus_chrono_t p_t;

  ssize_t n_gets = 0;
  lagopus_chrono_t p_min = LLONG_MAX;
  lagopus_chrono_t p_max = LLONG_MIN;
  double p_sum = 0.0;
  double p_sum2 = 0.0;

  double p_avg;
  double p_sd;

  lagopus_chrono_t t_total = 0;
  double t_avg;

  /*
   * This is only for choking clang/scan-build.
   */
  WHAT_TIME_IS_IT_NOW_IN_NSEC(t_begin);

  put_dates = (lagopus_chrono_t *)
              malloc(sizeof(lagopus_chrono_t) * (size_t)nputs);
  if (put_dates == NULL) {
    goto done;
  }

  if ((r = lagopus_mutex_create(&start_lock)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    goto done;
  }
  if ((r = lagopus_mutex_create(&stop_lock)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    goto done;
  }

  /*
   * Create the qmuxer.
   */
  if ((r = lagopus_qmuxer_create(&qmx)) != LAGOPUS_RESULT_OK) {
    lagopus_perror(r);
    goto done;
  }

  /*
   * Then create queues.
   */
  bbqs = (lagopus_bbq_t *)malloc(sizeof(lagopus_bbq_t) * nthds);
  if (bbqs == NULL) {
    goto done;
  }
  for (i = 0; i < nthds; i++) {
    if ((r = lagopus_bbq_create(&(bbqs[i]), lagopus_chrono_t,
                                1000LL * 1000LL,
                                NULL)) != LAGOPUS_RESULT_OK) {
      lagopus_perror(r);
      goto done;
    }
    n_created_bbqs++;
  }
  if (n_created_bbqs == 0) {
    goto done;
  }

  /*
   * Then create poll objects for the each queue.
   */
  polls = (lagopus_qmuxer_poll_t *)malloc(sizeof(lagopus_qmuxer_poll_t) *
                                          n_created_bbqs);
  if (polls == NULL) {
    goto done;
  }
  for (i = 0; i < n_created_bbqs; i++) {
    if ((r = lagopus_qmuxer_poll_create(&(polls[i]),
                                        bbqs[i],
                                        LAGOPUS_QMUXER_POLL_READABLE)) !=
        LAGOPUS_RESULT_OK) {
      lagopus_perror(r);
      goto done;
    }
    n_created_polls++;
  }
  if (n_created_polls == 0) {
    goto done;
  }

  /*
   * Then create threads for the each poll objects/queues.
   */
  tts = (test_thread_record *)malloc(sizeof(test_thread_record) *
                                     n_created_polls);
  if (tts == NULL) {
    goto done;
  }
  for (i = 0; i < n_created_polls; i++) {
    snprintf(thdname, sizeof(thdname), "putter " PFSZS(4, u), i);
    tt = &(tts[i]);
    if (test_thread_create(&tt, start_lock, bbqs[i], nputs,
                           (const char *)thdname) != true) {
      goto done;
    }
    n_created_thds++;
  }
  if (n_created_thds == 0) {
    goto done;
  }

  /*
   * Let the initiation begin.
   */

  /*
   * Ready, note that all the created threads do this lock.
   */
  (void)lagopus_mutex_lock(&start_lock);

  /*
   * Steady,
   */
  for (i = 0; i < n_created_thds; i++) {
    tt = &(tts[i]);
    if (lagopus_thread_start((lagopus_thread_t *)&tt, false) !=
        LAGOPUS_RESULT_OK) {
      (void)lagopus_mutex_unlock(&start_lock);
      goto done;
    }
  }

  fprintf(stdout, "Test for " PFSZ(u) " threads " PFSZ(u)
          " events/thdread start.\n", n_created_thds, (size_t)nputs);

  /*
   * Go.
   */
  (void)lagopus_mutex_unlock(&start_lock);

  WHAT_TIME_IS_IT_NOW_IN_NSEC(t_begin);

  while (true) {
    /*
     * Like the select(2)/poll(2), initialize poll objects before
     * checking events.
     */
    n_need_watch = 0;
    n_valid_polls = 0;
    for (i = 0; i < n_created_thds; i++) {
      /*
       * Check if the poll has a valid queue.
       */
      bbq = NULL;
      if ((r = lagopus_qmuxer_poll_get_queue(&(polls[i]), &bbq)) !=
          LAGOPUS_RESULT_OK) {
        lagopus_perror(r);
        break;
      }
      if (bbq != NULL) {
        n_valid_polls++;
      }

      /*
       * Reset the poll status.
       */
      if ((r = lagopus_qmuxer_poll_reset(&(polls[i]))) != LAGOPUS_RESULT_OK) {
        lagopus_perror(r);
        break;
      }
      n_need_watch++;
    }

    /*
     * If there are no valid queues, exit.
     */
    if (n_valid_polls == 0) {
      break;
    }

    /*
     * Wait for an event.
     *
     *  Note that we better set timeout, not waiting forever.
     */
    r = lagopus_qmuxer_poll(&qmx, (lagopus_qmuxer_poll_t *const)polls,
                            n_need_watch,
                            100LL * 1000LL * 1000LL);

    if (r > 0) {
      /*
       * Check which poll got an event. Actually, check all the queues
       * in this sample.
       */
      size_t n_actual_get = 0LL;

      for (i = 0; i < n_created_thds; i++) {

        if ((qsz = lagopus_bbq_size(&(bbqs[i]))) > 0) {

          lagopus_msg_debug(1, "Got " PFSZS(8, u) " events from the Q"
                            PFSZS(03, u) ".\n",
                            (size_t)qsz, (size_t)i);
          if ((r = lagopus_bbq_get_n(&(bbqs[i]), (void **)put_dates,
                                     (size_t)nputs, 1LL,
                                     lagopus_chrono_t,
                                     1000LL * 1000LL * 1000LL,
                                     &n_actual_get)) > 0) {
#if 1
            WHAT_TIME_IS_IT_NOW_IN_NSEC(p_begin);
#endif
            for (j = 0; j < n_actual_get; j++) {
              /*
               * In this sample, -1LL is kinda 'EOF'. Check if we got
               * the EOF.
               */
              if (put_dates[j] == -1LL) {
                /*
                 * The queue is kinda 'closed'. From now on we don't
                 * check this queue anymore. To specify this:
                 */
                lagopus_msg_debug(1, "Got an EOF from the Q" PFSZS(04, u)
                                  ".\n", i);
                goto nullify;
              }

#if 0
              WHAT_TIME_IS_IT_NOW_IN_NSEC(p_begin);
#endif

              p_t = p_begin - put_dates[j];

              if (p_t < p_min) {
                p_min = p_t;
              }
              if (p_t > p_max) {
                p_max = p_t;
              }
              p_sum += (double)p_t;
              p_sum2 += ((double)p_t * (double)p_t);
              n_gets++;
            }

          } else {
            /*
             * Something wrong for the queue. But we must not exit
             * here. Keep on checking other queues. In order to do
             * this, set NULL as the queue into the poll object for
             * the queue.
             */
            lagopus_perror(r);
          nullify:
            if ((r = lagopus_qmuxer_poll_set_queue(&(polls[i]), NULL)) ==
                LAGOPUS_RESULT_OK) {
              lagopus_msg_debug(1, "Q" PFSZS(04, u) " is not valid "
                                "anymore, ignore the queue.\n", i);
              break;
            } else {
              /*
               * There is nothing we can do now.
               */
              lagopus_perror(r);
              goto done;
            }
          }

        }

      }

    } else if (r == LAGOPUS_RESULT_TIMEDOUT) {
      lagopus_msg_debug(1, "Timedout. continue.\n");
      continue;
    } else {
      lagopus_perror(r);
      lagopus_msg_debug(1, "Break the loop due to error(s).\n");
      goto done;
    }
  }

  ret = 0;

done:

  WHAT_TIME_IS_IT_NOW_IN_NSEC(t_end);

  if (is_signaled == false) {
    fprintf(stdout, "Done.\n");
  } else {
    fprintf(stdout, "Stopped.\n");
  }

  fprintf(stdout, "Total # of the events:\t" PFSZS(22, u) "\n\n", n_gets);

  p_avg = p_sum / (double)n_gets;
  p_sd = (p_sum2 -
          2.0 * p_avg * p_sum +
          p_avg * p_avg * (double)n_gets) / (double)(n_gets - 1);
  p_sd = sqrt(p_sd);

  fprintf(stdout, "Queue stats:\n");
  fprintf(stdout, "wait time min =\t" PFSZS(22, d) " nsec.\n", p_min);
  fprintf(stdout, "wait time max =\t" PFSZS(22, d) " nsec.\n", p_max);
  fprintf(stdout, "wait time avg =\t%25.2f nsec.\n", p_avg);
  fprintf(stdout, "wait time sd =\t%25.2f.\n\n", p_sd);

  t_total = t_end - t_begin;
  t_avg = (double)t_total / (double)n_gets;

  fprintf(stdout, "Throughput:\n");
  fprintf(stdout, "total time:\t" PFSZS(22, d) " msec.\n",
          (size_t)(t_total / 1000LL / 1000LL));
  fprintf(stdout, "total avg:\t%25.2f nsec/event.\n", t_avg);

  s_destroy_all();

  free((void *)put_dates);

  return ret;
}
Пример #20
0
lagopus_result_t
ofp_bridgeq_mgr_bridge_register(uint64_t dpid) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;
  struct ofp_bridge *ofp_bridge = NULL;
  struct ofp_bridgeq *bridgeq;

  lagopus_msg_debug(1, "called. (dpid: %"PRIu64")\n", dpid);

  if (bridgeq_table != NULL) {
    /* check not exists */
    ret = lagopus_hashmap_find(&bridgeq_table,
                               (void *)dpid, (void **)&bridgeq);
    if (ret == LAGOPUS_RESULT_NOT_FOUND) {
      /* allocate bridgeq */
      if ((bridgeq = (struct ofp_bridgeq *)malloc(sizeof(struct ofp_bridgeq)))
          == NULL) {
        ret = LAGOPUS_RESULT_NO_MEMORY;
      } else if ((ret = ofp_bridge_create(&ofp_bridge, dpid))
                 != LAGOPUS_RESULT_OK) {
        lagopus_perror(ret);
        free(bridgeq);
      } else {
        /* init bridgeq */
        bridgeq->ofp_bridge = ofp_bridge;
        bridgeq->refs = 1;
        bridgeq->lock = NULL;
        memset(bridgeq->polls, 0, sizeof(bridgeq->polls));
        memset(bridgeq->dp_polls, 0, sizeof(bridgeq->dp_polls));
        if ((ret = lagopus_mutex_create(&(bridgeq->lock)))
            != LAGOPUS_RESULT_OK) { /* create lock */
          lagopus_perror(ret);
          ofp_bridgeq_free(bridgeq, true);
        } else if ((ret = lagopus_qmuxer_poll_create(
                            &(bridgeq->polls[EVENTQ_POLL]),
                            ofp_bridge->eventq,
                            LAGOPUS_QMUXER_POLL_READABLE))
                   != LAGOPUS_RESULT_OK) { /* create eventq poll */
          lagopus_perror(ret);
          ofp_bridgeq_free(bridgeq, true);
        } else if ((ret = lagopus_qmuxer_poll_create(
                            &(bridgeq->polls[DATAQ_POLL]),
                            ofp_bridge->dataq,
                            LAGOPUS_QMUXER_POLL_READABLE))
                   != LAGOPUS_RESULT_OK) { /* create dataq poll */
          lagopus_perror(ret);
          ofp_bridgeq_free(bridgeq, true);
#ifdef OFPH_POLL_WRITING
        } else if ((ret = lagopus_qmuxer_poll_create(
                            &(bridgeq->polls[EVENT_DATAQ_POLL]),
                            ofp_bridge->event_dataq,
                            LAGOPUS_QMUXER_POLL_WRITABLE))
                   != LAGOPUS_RESULT_OK) { /* create event_dataq poll */
          lagopus_perror(ret);
          ofp_bridgeq_free(bridgeq, true);
#endif  /* OFPH_POLL_WRITING */
        } else if ((ret = lagopus_qmuxer_poll_create(
                            &(bridgeq->dp_polls[EVENT_DATAQ_DP_POLL]),
                            ofp_bridge->event_dataq,
                            LAGOPUS_QMUXER_POLL_READABLE))
                   != LAGOPUS_RESULT_OK) { /* create dataq poll for DataPlen */
          lagopus_perror(ret);
          ofp_bridgeq_free(bridgeq, true);
        } else {
          /* succeeded all create. */
          /* register. */
          if ((ret = bridge_register(dpid, bridgeq)) != LAGOPUS_RESULT_OK) {
            lagopus_perror(ret);
            ofp_bridgeq_free(bridgeq, true);
          } else {
            /* update array. */
            ret = bridgeq_mgr_map_to_array();
            if (ret != LAGOPUS_RESULT_OK) {
              lagopus_perror(ret);
              (void) bridge_unregister(dpid, true);
            }
          }
        }
      }
    } else if (ret == LAGOPUS_RESULT_OK) {
      ret = LAGOPUS_RESULT_ALREADY_EXISTS;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_OBJECT;
    lagopus_msg_warning("bridgeq_table is NULL.\n");
  }

  return ret;
}