Esempio n. 1
0
 // atomically sets m_stack back and enqueues all elements to the cache
 bool fetch_new_data(pointer end_ptr) {
     CPPA_REQUIRE(m_head == nullptr);
     CPPA_REQUIRE(!end_ptr || end_ptr == stack_empty_dummy());
     pointer e = m_stack.load();
     // must not be called on a closed queue
     CPPA_REQUIRE(e != nullptr);
     // it's enough to check this once, since only the owner is allowed
     // to close the queue and only the owner is allowed to call this
     // member function
     while (e != end_ptr) {
         if (m_stack.compare_exchange_weak(e, end_ptr)) {
             if (is_dummy(e)) {
                 // only use-case for this is closing a queue
                 CPPA_REQUIRE(end_ptr == nullptr);
                 return false;
             }
             while (e) {
                 CPPA_REQUIRE(!is_dummy(e));
                 auto next = e->next;
                 e->next = m_head;
                 m_head = e;
                 e = next;
             }
             return true;
         }
         // next iteration
     }
     return false;
 }
 // atomically sets stack_ back and enqueues all elements to the cache
 bool fetch_new_data(pointer end_ptr) {
   CAF_ASSERT(end_ptr == nullptr || end_ptr == stack_empty_dummy());
   pointer e = stack_.load();
   // must not be called on a closed queue
   CAF_ASSERT(e != nullptr);
   // fetching data while blocked is an error
   CAF_ASSERT(e != reader_blocked_dummy());
   // it's enough to check this once, since only the owner is allowed
   // to close the queue and only the owner is allowed to call this
   // member function
   while (e != end_ptr) {
     if (stack_.compare_exchange_weak(e, end_ptr)) {
       // fetching data while blocked is an error
       CAF_ASSERT(e != reader_blocked_dummy());
       if (is_dummy(e)) {
         // only use-case for this is closing a queue
         CAF_ASSERT(end_ptr == nullptr);
         return false;
       }
       while (e) {
         CAF_ASSERT(! is_dummy(e));
         auto next = e->next;
         e->next = head_;
         head_ = e;
         e = next;
       }
       return true;
     }
     // next iteration
   }
   return false;
 }
Esempio n. 3
0
File: state.c Progetto: ysm001/slim
void state_print_label(State *s, LmnWord _fp, LmnWord _owner)
{
  Automata a;
  FILE *f;
  StateSpace owner;

  owner = (StateSpace)_owner;
  if (!statespace_has_property(owner) || (is_dummy(s) && is_encoded(s))) {
    return;
  }

  a     = statespace_automata(owner);
  f     = (FILE *)_fp;

  switch (lmn_env.mc_dump_format) {
  case Dir_DOT:
  {
    if (state_is_accept(a, s) || state_is_end(a, s)) {
      fprintf(f, "  %lu [peripheries = 2]\n", state_format_id(s, owner->is_formated));
    }
    break;
  }
  case LaViT:
    fprintf(f, "%lu::", state_format_id(s, owner->is_formated));
    fprintf(f, "%s\n", automata_state_name(a, state_property_state(s)));
  case FSM:
  case CUI:  /* 状態のグローバルルート膜の膜名としてdump済 */
    break;
  default:
    lmn_fatal("unexpected");
    break;
  }
}
 /// Queries whether there is new data to read, i.e., whether the next
 /// call to {@link try_pop} would succeeed.
 /// @pre !closed()
 bool can_fetch_more() {
   if (head_ != nullptr) {
     return true;
   }
   auto ptr = stack_.load();
   CAF_ASSERT(ptr != nullptr);
   return ! is_dummy(ptr);
 }
Esempio n. 5
0
 // returns true if the queue was empty
 enqueue_result enqueue(pointer new_element) {
     pointer e = m_stack.load();
     for (;;) {
         if (!e) {
             // if tail is nullptr, the queue has been closed
             m_delete(new_element);
             return enqueue_result::queue_closed;
         }
         new_element->next = is_dummy(e) ? nullptr : e;
         if (m_stack.compare_exchange_weak(e, new_element)) {
             return (e == reader_blocked_dummy())
                     ? enqueue_result::unblocked_reader
                     : enqueue_result::success;
         }
     }
 }
 /// Tries to enqueue a new element to the mailbox.
 /// @warning Call only from the reader (owner).
 enqueue_result enqueue(pointer new_element) {
   CAF_ASSERT(new_element != nullptr);
   pointer e = stack_.load();
   for (;;) {
     if (! e) {
       // if tail is nullptr, the queue has been closed
       delete_(new_element);
       return enqueue_result::queue_closed;
     }
     // a dummy is never part of a non-empty list
     new_element->next = is_dummy(e) ? nullptr : e;
     if (stack_.compare_exchange_strong(e, new_element)) {
       return  (e == reader_blocked_dummy()) ? enqueue_result::unblocked_reader
                                             : enqueue_result::success;
     }
     // continue with new value of e
   }
 }
Esempio n. 7
0
File: state.c Progetto: ysm001/slim
/* TODO: 美しさ */
void state_print_transition(State *s, LmnWord _fp, LmnWord _owner)
{
  FILE *f;
  StateSpace owner;
  unsigned int i;

  BOOL need_id_foreach_trans;
  char *state_separator,
       *trans_separator,
       *label_begin,
       *label_end;
  BOOL formated;

  /* Rehashが発生している場合,
   * サクセッサへの情報は, RehashしたオリジナルのStateオブジェクトが保持しているため,
   * dummyフラグが真かつエンコード済みの状態には遷移情報は載っていない.
   * (エンコード済のバイナリストリングしか載っていない) */
  if ((is_dummy(s) && is_encoded(s))) return;

  f     = (FILE *)_fp;
  owner = (StateSpace)_owner;

  need_id_foreach_trans = TRUE;
  switch (lmn_env.mc_dump_format) {
  case DOT:
    state_separator = " -> ";
    trans_separator = NULL;
    label_begin     = " [ label = \"";
    label_end       = "\" ];";
    break;
  case FSM:
    state_separator = " ";
    trans_separator = NULL;
    label_begin     = " \"";
    label_end       = "\"";
    break;
  case LaViT: /* FALLTHROUGH: CUIモードと共通 */
  case CUI:
    state_separator = "::"; /* なぜかspaceが混ざるとlavitは読み込むことができない */
    trans_separator = ",";
    label_begin     = "(";
    label_end       = ")";
    need_id_foreach_trans = FALSE;
    break;
  default:
    lmn_fatal("unexpected");
    break;
  }


  formated = owner ? owner->is_formated : FALSE;
  if (!need_id_foreach_trans) {
    fprintf(f, "%lu%s", state_format_id(s, formated), state_separator);
  }

  if (s->successors) {
    for (i = 0; i < state_succ_num(s); i++) { /* dump dst state's IDs */
      if (need_id_foreach_trans) {
        fprintf(f, "%lu%s", state_format_id(s, formated), state_separator);
      } else if (i > 0) {
        LMN_ASSERT(trans_separator);
        fprintf(f, "%s", trans_separator);
      }

      /* MEMO: rehashが発生していても, successorポインタを辿る先は, オリジナル */
      fprintf(f, "%lu", state_format_id(state_succ_state(s, i), formated));

      if (has_trans_obj(s)) {
        Transition t;
        unsigned int j;

        fprintf(f, "%s", label_begin);
        t = transition(s, i);

        for (j = 0; j < transition_rule_num(t); j++) {
          if (j > 0) fprintf(f, " "); /* ルール名の区切りは半角スペース1文字 */
          fprintf(f, "%s", lmn_id_to_name(transition_rule(t, j)));
        }
        fprintf(f, "%s", label_end);
      }

      if (i + 1 < state_succ_num(s) && need_id_foreach_trans) {
        fprintf(f,"\n");
      }
    }
    fprintf(f, "\n");
  } else if (!need_id_foreach_trans){
    fprintf(f, "\n");
  }
}
Esempio n. 8
0
File: state.c Progetto: ysm001/slim
/** Printer
 * ownerはNULLでもok */
void dump_state_data(State *s, LmnWord _fp, LmnWord _owner)
{
  FILE *f;
  StateSpace owner;
  unsigned long print_id;
#ifdef KWBT_OPT
  LmnCost cost = lmn_env.opt_mode != OPT_NONE ? state_cost(s) : 0UL;
#endif

  /* Rehashが発生している場合,
   * dummyフラグが真かつエンコード済みフラグが偽のStateオブジェクトが存在する.
   * このようなStateオブジェクトのバイナリストリングは
   * Rehashされた側のテーブルに存在するStateオブジェクトに登録されているためcontinueする. */
  if (is_dummy(s) && !is_encoded(s)) return;

  f     = (FILE *)_fp;
  owner = (StateSpace)_owner;
  {
    /* この時点で状態は, ノーマル || (dummyフラグが立っている && エンコード済)である.
     * dummyならば, バイナリストリング以外のデータはオリジナル側(parent)に記録している. */
    State *target = !is_dummy(s) ? s : state_get_parent(s);
    if (owner) {
      print_id = state_format_id(target, owner->is_formated);
    } else {
      print_id = state_format_id(target, FALSE);
    }
  }

  switch (lmn_env.mc_dump_format) {
  case LaViT:
    fprintf(f, "%lu::", print_id);
    state_print_mem(s, _fp);
    break;
  case FSM:
    /* under constructions.. */
    fprintf(f, "1\n");
    break;
  case Dir_DOT:
    if (state_succ_num(s) == 0) {
      fprintf(f, "  %lu [style=filled, fillcolor = \"#C71585\", shape = Msquare];\n",
                  print_id);
    }
    break;
  case CUI:
  {
    BOOL has_property = owner && statespace_has_property(owner);
#ifdef KWBT_OPT
    fprintf(f, "%lu::%lu::%s"
            , print_id, cost
             , has_property ? automata_state_name(statespace_automata(owner),
                                                  state_property_state(s))
                            : "");
#else
    fprintf(f, "%lu::%s"
             , print_id
             , has_property ? automata_state_name(statespace_automata(owner),
                                                  state_property_state(s))
                            : "");
#endif
    state_print_mem(s, _fp);
    break;
  }
  default:
    lmn_fatal("unexpected");
    break;
  }
}
Esempio n. 9
0
MonoLockFreeQueueNode*
mono_lock_free_queue_dequeue (MonoLockFreeQueue *q)
{
	MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
	MonoLockFreeQueueNode *head;

 retry:
	for (;;) {
		MonoLockFreeQueueNode *tail, *next;

		head = (MonoLockFreeQueueNode *) get_hazardous_pointer ((gpointer volatile*)&q->head, hp, 0);
		tail = (MonoLockFreeQueueNode*)q->tail;
		mono_memory_read_barrier ();
		next = head->next;
		mono_memory_read_barrier ();

		/* Are head, tail and next consistent? */
		if (head == q->head) {
			g_assert (next != INVALID_NEXT && next != FREE_NEXT);
			g_assert (next != head);

			/* Is queue empty or tail behind? */
			if (head == tail) {
				if (next == END_MARKER) {
					/* Queue is empty */
					mono_hazard_pointer_clear (hp, 0);

					/*
					 * We only continue if we
					 * reenqueue the dummy
					 * ourselves, so as not to
					 * wait for threads that might
					 * not actually run.
					 */
					if (!is_dummy (q, head) && try_reenqueue_dummy (q))
						continue;

					return NULL;
				}

				/* Try to advance tail */
				InterlockedCompareExchangePointer ((gpointer volatile*)&q->tail, next, tail);
			} else {
				g_assert (next != END_MARKER);
				/* Try to dequeue head */
				if (InterlockedCompareExchangePointer ((gpointer volatile*)&q->head, next, head) == head)
					break;
			}
		}

		mono_memory_write_barrier ();
		mono_hazard_pointer_clear (hp, 0);
	}

	/*
	 * The head is dequeued now, so we know it's this thread's
	 * responsibility to free it - no other thread can.
	 */
	mono_memory_write_barrier ();
	mono_hazard_pointer_clear (hp, 0);

	g_assert (head->next);
	/*
	 * Setting next here isn't necessary for correctness, but we
	 * do it to make sure that we catch dereferencing next in a
	 * node that's not in the queue anymore.
	 */
	head->next = INVALID_NEXT;
#if QUEUE_DEBUG
	g_assert (head->in_queue);
	head->in_queue = FALSE;
	mono_memory_write_barrier ();
#endif

	if (is_dummy (q, head)) {
		g_assert (q->has_dummy);
		q->has_dummy = 0;
		mono_memory_write_barrier ();
		mono_thread_hazardous_free_or_queue (head, free_dummy, FALSE, TRUE);
		if (try_reenqueue_dummy (q))
			goto retry;
		return NULL;
	}

	/* The caller must hazardously free the node. */
	return head;
}
Esempio n. 10
0
 /**
  * @warning call only from the reader (owner)
  */
 inline bool empty() {
     CPPA_REQUIRE(m_stack.load() != nullptr);
     return (!m_head && is_dummy(m_stack.load()));
 }
Esempio n. 11
0
 /**
  * @brief Queries whether there is new data to read.
  * @pre m_stack.load() != reader_blocked_dummy()
  */
 inline bool can_fetch_more() {
     auto ptr = m_stack.load();
     CPPA_REQUIRE(ptr != nullptr);
     return !is_dummy(ptr);
 }
 /// Queries whether this queue is empty.
 /// @warning Call only from the reader (owner).
 bool empty() {
   CAF_ASSERT(! closed());
   return cache_.empty() && head_ == nullptr && is_dummy(stack_.load());
 }