int main(int argc, const char *const argv[]) { size_t i; uint64_t zz = 0; struct timespec ts0; struct timespec ts1; struct timespec ts2; lagopus_chrono_t now; uint64_t start0, start1, start2, end0, end1, end2; WHAT_TIME_IS_IT_NOW_IN_NSEC(now); NSEC_TO_TS(now, ts0); NSEC_TO_TS_MOD(now, ts1); NSEC_TO_TS_ASM(now, ts2); fprintf(stderr, "ts0: " PF64(u) ", " PF64(u) "\n", ts0.tv_sec, ts0.tv_nsec); fprintf(stderr, "ts1: " PF64(u) ", " PF64(u) "\n", ts1.tv_sec, ts1.tv_nsec); fprintf(stderr, "ts2: " PF64(u) ", " PF64(u) "\n", ts2.tv_sec, ts2.tv_nsec); for (i = 0; i < 1000LL * 1000LL * 1000LL; i++) { zz += i; } fprintf(stderr, "zz = " PF64(u) "\n", zz); start0 = lagopus_rdtsc(); for (i = 0; i < 1000LL * 1000LL * 1000LL; i++) { NSEC_TO_TS(i, ts0); } end0 = lagopus_rdtsc(); start1 = lagopus_rdtsc(); for (i = 0; i < 1000LL * 1000LL * 1000LL; i++) { NSEC_TO_TS_MOD(i, ts1); } end1 = lagopus_rdtsc(); start2 = lagopus_rdtsc(); for (i = 0; i < 1000LL * 1000LL * 1000LL; i++) { NSEC_TO_TS_ASM(i, ts0); } end2 = lagopus_rdtsc(); fprintf(stderr, "cur: " PF64(u) "\n", end0 - start0); fprintf(stderr, "mod: " PF64(u) "\n", end1 - start1); fprintf(stderr, "asm: " PF64(u) "\n", end2 - start2); return 0; }
static void s_once_proc(void) { char *dbg_lvl_str = getenv("MCCP_LOG_DEBUGLEVEL"); char *logfile = getenv("MCCP_LOG_FILE"); uint64_t d = 0; mccp_log_destination_t log_dst = MCCP_LOG_EMIT_TO_UNKNOWN; if (IS_VALID_STRING(dbg_lvl_str) == true) { uint64_t tmp = 0; if (mccp_str_parse_uint64(dbg_lvl_str, &tmp) == MCCP_RESULT_OK) { d = tmp; } } if ((logfile = s_validate_path(logfile, s_is_valid_path)) != NULL) { log_dst = MCCP_LOG_EMIT_TO_FILE; } if (mccp_log_initialize(log_dst, logfile, false, true, d, 0LL) != MCCP_RESULT_OK) { mccp_exit_error(1, "logger initialization error.\n"); } if (d > 0) { mccp_msg_debug(d, "Logger debug level is set to: " PF64(u) ".\n", d); } }
void test_idle_force(void) { lagopus_result_t r = LAGOPUS_RESULT_ANY_FAILURES; lagopus_callout_task_t t = NULL; size_t n_exec; size_t i; callout_arg_t arg = NULL; lagopus_callout_task_state_t st; arg = s_alloc_arg(10, 0LL); TEST_ASSERT_NOT_EQUAL(arg, NULL); r = lagopus_callout_create_task(&t, 0, __func__, callout_task, (void *)arg, s_freeup_arg); TEST_ASSERT_EQUAL(r, LAGOPUS_RESULT_OK); r = lagopus_callout_submit_task(&t, -1LL, 500LL * 1000LL * 1000LL); TEST_ASSERT_EQUAL(r, LAGOPUS_RESULT_OK); (void)lagopus_chrono_nanosleep(1000LL * 1000LL * 1000LL, NULL); for (i = 0; i < 5; i++) { lagopus_msg_debug(1, "iter. " PF64(u) "\n", i); r = lagopus_callout_task_state(&t, &st); TEST_ASSERT_EQUAL(r, LAGOPUS_RESULT_OK); if (st == TASK_STATE_ENQUEUED) { r = lagopus_callout_exec_task_forcibly(&t); if (r == LAGOPUS_RESULT_INVALID_STATE) { continue; } TEST_ASSERT_EQUAL(r, LAGOPUS_RESULT_OK); } else if (st == TASK_STATE_UNKNOWN || st == TASK_STATE_CANCELLED) { break; } (void)lagopus_chrono_nanosleep(100LL * 1000LL * 1000LL, NULL); } n_exec = s_wait_freeup_arg(arg); TEST_ASSERT_EQUAL(n_exec, 10); s_destroy_arg(arg); }
static lagopus_result_t callout_task(void *arg) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; lagopus_chrono_t now; WHAT_TIME_IS_IT_NOW_IN_NSEC(now); lagopus_msg_debug(1, "enter.\n"); if (likely(arg != NULL)) { callout_arg_t carg = (callout_arg_t)arg; size_t n_exec = __sync_add_and_fetch(&(carg->m_n_exec), 1); lagopus_msg_debug(1, "exec " PFSZ(u) ".\n", n_exec); if (carg->m_last_exec_abstime != 0) { lagopus_msg_debug(1, "interval: " PF64(d) " nsec.\n", now - carg->m_last_exec_abstime); } carg->m_last_exec_abstime = now; if (carg->m_wait_nsec > 0) { lagopus_msg_debug(1, "sleep " PFSZ(u) " nsec.\n", carg->m_wait_nsec); (void)lagopus_chrono_nanosleep(carg->m_wait_nsec, NULL); } if (n_exec < carg->m_n_stop) { ret = LAGOPUS_RESULT_OK; } } lagopus_msg_debug(1, "leave.\n"); return ret; }
int main(int argc, const char *const argv[]) { lagopus_result_t st = LAGOPUS_RESULT_ANY_FAILURES; lagopus_pipeline_stage_t s = NULL; size_t nthd = 1; (void)argc; if (IS_VALID_STRING(argv[1]) == true) { size_t tmp; if (lagopus_str_parse_uint64(argv[1], &tmp) == LAGOPUS_RESULT_OK && tmp > 0LL) { nthd = tmp; } } fprintf(stdout, "Creating... "); st = lagopus_pipeline_stage_create(&s, 0, "a_test", nthd, sizeof(void *), 1024, s_pre_pause, s_sched, s_setup, s_fetch, s_main, s_throw, s_shutdown, s_finalize, s_freeup); if (st == LAGOPUS_RESULT_OK) { fprintf(stdout, "Created.\n"); fprintf(stdout, "Setting up... "); st = lagopus_pipeline_stage_setup(&s); if (st == LAGOPUS_RESULT_OK) { fprintf(stdout, "Set up.\n"); fprintf(stdout, "Starting... "); st = lagopus_pipeline_stage_start(&s); if (st == LAGOPUS_RESULT_OK) { fprintf(stdout, "Started.\n"); fprintf(stdout, "Opening the front door... "); st = global_state_set(GLOBAL_STATE_STARTED); if (st == LAGOPUS_RESULT_OK) { char buf[1024]; char *cmd = NULL; fprintf(stdout, "The front door is open.\n"); fprintf(stdout, "> "); while (fgets(buf, sizeof(buf), stdin) != NULL && st == LAGOPUS_RESULT_OK) { (void)lagopus_str_trim_right(buf, "\r\n\t ", &cmd); if (strcasecmp(cmd, "pause") == 0 || strcasecmp(cmd, "spause") == 0) { fprintf(stdout, "Pausing... "); if ((st = lagopus_pipeline_stage_pause(&s, -1LL)) == LAGOPUS_RESULT_OK) { if (strcasecmp(cmd, "spause") == 0) { s_set(0LL); } fprintf(stdout, "Paused " PF64(u) "\n", s_get()); } else { fprintf(stdout, "Failure.\n"); } } else if (strcasecmp(cmd, "resume") == 0) { fprintf(stdout, "Resuming... "); if ((st = lagopus_pipeline_stage_resume(&s)) == LAGOPUS_RESULT_OK) { fprintf(stdout, "Resumed.\n"); } else { fprintf(stdout, "Failure.\n"); } } else if (strcasecmp(cmd, "get") == 0) { fprintf(stdout, PF64(u) "\n", s_get()); } free((void *)cmd); cmd = NULL; fprintf(stdout, "> "); } fprintf(stdout, "\nDone.\n"); fprintf(stdout, "Shutting down... "); st = lagopus_pipeline_stage_shutdown(&s, SHUTDOWN_GRACEFULLY); if (st == LAGOPUS_RESULT_OK) { fprintf(stdout, "Shutdown accepted... "); sleep(1); s_do_stop = true; fprintf(stdout, "Waiting shutdown... "); st = lagopus_pipeline_stage_wait(&s, -1LL); if (st == LAGOPUS_RESULT_OK) { fprintf(stdout, "OK, Shutdown.\n"); } } } } } } fflush(stdout); if (st != LAGOPUS_RESULT_OK) { lagopus_perror(st); } fprintf(stdout, "Destroying... "); lagopus_pipeline_stage_destroy(&s); fprintf(stdout, "Destroyed.\n"); return (st == LAGOPUS_RESULT_OK) ? 0 : 1; }
static inline lagopus_result_t s_start_callout_main_loop(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; global_state_t s; shutdown_grace_level_t l; ret = global_state_wait_for(GLOBAL_STATE_STARTED, &s, &l, -1LL); if (likely(ret == LAGOPUS_RESULT_OK)) { if (likely(s == GLOBAL_STATE_STARTED)) { #ifdef CO_MSG_DEBUG lagopus_chrono_t timeout = s_idle_interval; #else lagopus_chrono_t timeout; #endif /* CO_MSG_DEBUG */ lagopus_callout_task_t out_tasks[CALLOUT_TASK_MAX * 3]; size_t n_out_tasks; lagopus_callout_task_t urgent_tasks[CALLOUT_TASK_MAX]; lagopus_result_t sn_urgent_tasks; lagopus_callout_task_t idle_tasks[CALLOUT_TASK_MAX]; lagopus_result_t sn_idle_tasks; lagopus_callout_task_t timed_tasks[CALLOUT_TASK_MAX]; lagopus_result_t sn_timed_tasks; lagopus_result_t r; lagopus_chrono_t now; lagopus_chrono_t next_wakeup; lagopus_chrono_t prev_wakeup; int cstate = 0; WHAT_TIME_IS_IT_NOW_IN_NSEC(prev_wakeup); (void)lagopus_mutex_enter_critical(&s_sched_lck, &cstate); { s_is_stopped = false; mbar(); while (s_do_loop == true) { n_out_tasks = 0; /* * Get the current time. */ WHAT_TIME_IS_IT_NOW_IN_NSEC(now); #ifdef CO_MSG_DEBUG lagopus_msg_debug(3, "now: " PF64(d) "\n", now); lagopus_msg_debug(3, "prv: " PF64(d) "\n", prev_wakeup); lagopus_msg_debug(3, "to: " PF64(d) "\n", timeout); #endif /* CO_MSG_DEBUG */ s_lock_global(); { /* * Acquire the global lock to make the task * submisson/fetch atomic. */ sn_urgent_tasks = lagopus_bbq_get_n(&s_urgent_tsk_q, (void **)urgent_tasks, CALLOUT_TASK_MAX, 1LL, lagopus_callout_task_t, 0LL, NULL); sn_idle_tasks = lagopus_bbq_get_n(&s_idle_tsk_q, (void **)idle_tasks, CALLOUT_TASK_MAX, 1LL, lagopus_callout_task_t, 0LL, NULL); } s_unlock_global(); /* * Pack the tasks into a buffer. */ sn_timed_tasks = s_get_runnable_timed_task(now, timed_tasks, CALLOUT_TASK_MAX, &next_wakeup); if (sn_timed_tasks > 0) { /* * Pack the timed tasks. */ (void)memcpy((void *)(out_tasks + n_out_tasks), timed_tasks, (size_t)(sn_timed_tasks) * sizeof(lagopus_callout_task_t)); n_out_tasks += (size_t)sn_timed_tasks; #ifdef CO_MSG_DEBUG lagopus_msg_debug(3, "timed task " PF64(u) ".\n", sn_timed_tasks); lagopus_msg_debug(3, "nw: " PF64(d) ".\n", next_wakeup); #endif /* CO_MSG_DEBUG */ } else if (sn_timed_tasks < 0) { /* * We can't be treat this as a fatal error. Carry on. */ lagopus_perror(sn_timed_tasks); lagopus_msg_error("timed tasks fetch failed.\n"); } if (sn_urgent_tasks > 0) { /* * Pack the urgent tasks. */ (void)memcpy((void *)(out_tasks + n_out_tasks), urgent_tasks, (size_t)(sn_urgent_tasks) * sizeof(lagopus_callout_task_t)); n_out_tasks += (size_t)sn_urgent_tasks; } else if (sn_urgent_tasks < 0) { /* * We can't be treat this as a fatal error. Carry on. */ lagopus_perror(sn_urgent_tasks); lagopus_msg_error("urgent tasks fetch failed.\n"); } if (sn_idle_tasks > 0) { /* * Pack the idle tasks. */ (void)memcpy((void *)(out_tasks + n_out_tasks), idle_tasks, (size_t)(sn_idle_tasks) * sizeof(lagopus_callout_task_t)); n_out_tasks += (size_t)sn_idle_tasks; } else if (sn_idle_tasks < 0) { /* * We can't be treat this as a fatal error. Carry on. */ lagopus_perror(sn_idle_tasks); lagopus_msg_error("idle tasks fetch failed.\n"); } if (n_out_tasks > 0) { /* * Run/Submit the tasks. */ r = (s_final_task_sched_proc)(out_tasks, now, n_out_tasks); if (unlikely(r <= 0)) { /* * We can't be treat this as a fatal error. Carry on. */ lagopus_perror(r); lagopus_msg_error("failed to submit " PFSZ(u) " urgent/timed tasks.\n", n_out_tasks); } } if (s_idle_proc != NULL && s_next_idle_abstime < (now + CALLOUT_TASK_SCHED_JITTER)) { if (likely(s_idle_proc(s_idle_proc_arg) == LAGOPUS_RESULT_OK)) { s_next_idle_abstime = now + s_idle_interval; } else { /* * Stop the main loop and return (clean finish.) */ s_do_loop = false; goto critical_end; } } /* * fetch the start time of the timed task in the queue head. */ next_wakeup = s_peek_current_wakeup_time(); if (next_wakeup <= 0LL) { /* * Nothing in the timed Q. */ if (s_next_idle_abstime <= 0LL) { s_next_idle_abstime = now + s_idle_interval; } next_wakeup = s_next_idle_abstime; } /* * TODO * * Re-optimize forcible waje up by timed task submission * timing and times. See also * callout_queue.c:s_do_sched(). */ /* * calculate the timeout and sleep. */ timeout = next_wakeup - now; if (likely(timeout > 0LL)) { if (timeout > s_idle_interval) { timeout = s_idle_interval; next_wakeup = now + timeout; } #ifdef CO_MSG_DEBUG lagopus_msg_debug(4, "about to sleep, timeout " PF64(d) " nsec.\n", timeout); #endif /* CO_MSG_DEBUG */ prev_wakeup = next_wakeup; r = lagopus_bbq_wait_gettable(&s_urgent_tsk_q, timeout); if (unlikely(r <= 0 && r != LAGOPUS_RESULT_TIMEDOUT && r != LAGOPUS_RESULT_WAKEUP_REQUESTED)) { lagopus_perror(r); lagopus_msg_error("Event wait failure.\n"); ret = r; goto critical_end; } else { if (r == LAGOPUS_RESULT_WAKEUP_REQUESTED) { #ifdef CO_MSG_DEBUG lagopus_msg_debug(4, "woke up.\n"); #endif /* CO_MSG_DEBUG */ } } } else { WHAT_TIME_IS_IT_NOW_IN_NSEC(next_wakeup); prev_wakeup = next_wakeup; #ifdef CO_MSG_DEBUG lagopus_msg_debug(4, "timeout zero. contiune.\n"); #endif /* CO_MSG_DEBUG */ } /* * The end of the desired potion of the loop. */ } /* while (s_do_loop == true) */ } critical_end: s_is_stopped = true; s_wakeup_sched(); (void)lagopus_mutex_leave_critical(&s_sched_lck, cstate); if (s_do_loop == false) { /* * The clean finish. */ ret = LAGOPUS_RESULT_OK; } } else { /* s == GLOBAL_STATE_STARTED */ s_is_stopped = true; ret = LAGOPUS_RESULT_INVALID_STATE_TRANSITION; } } else { s_is_stopped = true; } return ret; }
static inline lagopus_result_t s_wait_io_ready(lagopus_cbuffer_t cb, lagopus_cond_t *cptr, lagopus_chrono_t nsec) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; size_t n_waiters; if (cb != NULL && cptr != NULL) { if (nsec != 0LL) { lagopus_msg_debug(5, "wait " PF64(d) " nsec.\n", nsec); (void)__sync_fetch_and_add(&(cb->m_n_waiters), 1); ret = lagopus_cond_wait(cptr, &(cb->m_lock), nsec); n_waiters = __sync_sub_and_fetch(&(cb->m_n_waiters), 1); if (cb->m_is_awakened == true) { lagopus_msg_debug(5, "awakened while sleeping " PF64(d) " nsec.\n", nsec); } else { lagopus_msg_debug(5, "wait " PF64(d) " nsec done.\n", nsec); } if (ret == LAGOPUS_RESULT_OK && cb->m_is_awakened == true) { /* * A waker wakes all the waiting threads up. Note that the * waker is waiting for a notification that the all the * waiters are awakened and leave this function. */ if (cb->m_is_operational == true) { if (n_waiters == 0) { /* * All the waiters are gone. Wake the waker up. */ lagopus_msg_debug(5, "sync wakeup who woke me up.\n"); cb->m_is_awakened = false; (void)lagopus_cond_notify(&(cb->m_cond_awakened), true); } ret = LAGOPUS_RESULT_WAKEUP_REQUESTED; } else { cb->m_is_awakened = false; (void)lagopus_cond_notify(&(cb->m_cond_awakened), true); ret = LAGOPUS_RESULT_NOT_OPERATIONAL; } } } else { ret = LAGOPUS_RESULT_OK; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }