Skip to content

Commit

Permalink
UCS/ARBITER: Fix push_head when only one group is scheduled
Browse files Browse the repository at this point in the history
Also, unite with purge code and add unit test.
  • Loading branch information
yosefe committed Apr 4, 2019
1 parent 086f664 commit 5dfef6d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
33 changes: 17 additions & 16 deletions src/ucs/datastruct/arbiter.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,17 @@ static void ucs_arbiter_group_head_replaced(ucs_arbiter_t *arbiter,
ucs_assert(old_head->list.next != NULL);
ucs_assert(old_head != new_head);

ucs_list_insert_replace(old_head->list.prev, old_head->list.next,
&new_head->list);
if (arbiter->current == old_head) {
if (old_head->list.next == &old_head->list) {
/* single group which was scheduled */
ucs_assert(arbiter->current == old_head);
ucs_list_head_init(&new_head->list);
arbiter->current = new_head;
} else {
ucs_list_insert_replace(old_head->list.prev, old_head->list.next,
&new_head->list);
if (arbiter->current == old_head) {
arbiter->current = new_head;
}
}
}

Expand Down Expand Up @@ -168,28 +175,22 @@ void ucs_arbiter_group_purge(ucs_arbiter_t *arbiter,
} while (ptr != tail);

if (is_scheduled) {
if (orig_head == prev_group) {
/* this is the only group which was scheduled */
if (group->tail == NULL) {
if (group->tail == NULL) {
/* group became empty */
if (orig_head == prev_group) {
/* group became empty - no more groups scheduled */
arbiter->current = NULL;
} else if (orig_head != head) {
/* keep the group scheduled, but with new head element */
arbiter->current = head;
ucs_list_head_init(&head->list);
}
} else {
if (group->tail == NULL) {
} else {
/* group became empty - deschedule it */
prev_group->list.next = &next_group->list;
next_group->list.prev = &prev_group->list;
if (arbiter->current == orig_head) {
arbiter->current = next_group;
}
} else if (orig_head != head) {
/* keep the group scheduled, but with new head element */
ucs_arbiter_group_head_replaced(arbiter, orig_head, head);
}
} else if (orig_head != head) {
/* head changed, and group is non-empty */
ucs_arbiter_group_head_replaced(arbiter, orig_head, head);
}
} else if ((orig_head != head) && (group->tail != NULL)) {
/* Mark new head as unscheduled */
Expand Down
16 changes: 16 additions & 0 deletions test/gtest/ucs/test_arbiter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,22 @@ UCS_TEST_F(test_arbiter, push_head_scheduled) {
ucs_arbiter_dispatch(&m_arb1, 2, remove_cb, this);
EXPECT_EQ(3, m_count);

/* Add to single scheduled group */
ucs_arbiter_group_push_head_elem(&m_arb1, &group2, &elem2.elem);
ucs_arbiter_group_schedule(&m_arb1, &group2);
ucs_arbiter_group_push_head_elem(&m_arb1, &group2, &elem3.elem);

m_count = 0;
elem2.count = elem3.count = 0;
ucs_arbiter_dispatch(&m_arb1, 2, count_cb, this);
EXPECT_EQ(0, elem2.count);
EXPECT_EQ(1, elem3.count);
EXPECT_EQ(1, m_count);

m_count = 0;
ucs_arbiter_dispatch(&m_arb1, 2, remove_cb, this);
EXPECT_EQ(2, m_count);

ucs_arbiter_cleanup(&m_arb1);
}

Expand Down

0 comments on commit 5dfef6d

Please sign in to comment.