Пример #1
0
static inline void
a_obj_set(a_obj_t o, bool val) {
  if (o != NULL) {

    (void)lagopus_mutex_enter_critical(&(o->m_lock));
    {
      o->m_bool = val;
      /*
       * fprintf() is a cancel point.
       */
      fprintf(stderr, "%s:%d:%s:0x" PFTIDS(016, x) ": called.\n",
              __FILE__, __LINE__, __func__, pthread_self());
    }
    (void)lagopus_mutex_leave_critical(&(o->m_lock));

  }
}
Пример #2
0
static lagopus_result_t
s_main(const lagopus_thread_t *tptr, void *arg) {
  lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES;

  (void)arg;

  if (tptr != NULL) {
    null_thread_t nptr = (null_thread_t)*tptr;
    a_obj_t o = nptr->m_o;

    if (nptr != NULL &&
        o != NULL) {

      while (true) {

        (void)lagopus_mutex_enter_critical(&(nptr->m_lock));
        {
          /*
           * fprintf() is a cancel point.
           */
          fprintf(stderr, "%s:%d:%s:0x" PFTIDS(016, x) ": sleep one sec.\n",
                  __FILE__, __LINE__, __func__, pthread_self());
          sleep(1);
        }
        (void)lagopus_mutex_leave_critical(&(nptr->m_lock));

        a_obj_set(o, true);

      }

      ret = LAGOPUS_RESULT_OK;

    } else {
      ret = LAGOPUS_RESULT_INVALID_ARGS;
    }
  } else {
    ret = LAGOPUS_RESULT_INVALID_ARGS;
  }

  return ret;
}
Пример #3
0
static inline bool
a_obj_get(a_obj_t o) {
  bool ret = false;

  if (o != NULL) {

    (void)lagopus_mutex_enter_critical(&(o->m_lock));
    {
      ret = o->m_bool;
      /*
       * fprintf() is a cancel point.
       */
      fprintf(stderr, "%s:%d:%s: called.\n",
              __FILE__, __LINE__, __func__);
    }
    (void)lagopus_mutex_leave_critical(&(o->m_lock));

  }

  return ret;
}
Пример #4
0
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;
}