From patchwork Tue Mar 18 13:13:07 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petri Savolainen X-Patchwork-Id: 26493 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ig0-f199.google.com (mail-ig0-f199.google.com [209.85.213.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 3C8D6202FA for ; Tue, 18 Mar 2014 13:11:32 +0000 (UTC) Received: by mail-ig0-f199.google.com with SMTP id uy17sf13952597igb.2 for ; Tue, 18 Mar 2014 06:11:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:to:cc:subject:date:message-id :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe:content-type; bh=o1BFGuFxqlDXjBUCFz8kQAuqL/qlBnfoMkxr0HMwSKs=; b=MUHrpx3mo4r9JjmVlEdFj7Sm27G8vD7fyfV8DLkM6aEIY7Yb/13OH6HKaCFma5hHzb PdgWFt+tMalTTuqq9rbtsXj7AvQKncVMqgPq2wwJ9bFvWn4KTSOYY9VK/cb3J7tumrhC d5MvCuhcowN0XteZpnpiBwvBkPhSaa0b1SJyuvoX7Z6aTTkB5UaJGJsVUkRt8S/QhAMc Ql2IXoKgJ77QwqNyLf232aJiXFNul0B6H9FGTRMck1wdOnp8T3F6JjRFmsKRR3H3LKg4 TbDfca61z+ibX2/BjAoRSpxMmWKuimvzEnZHvLcq0UhqrnauJaV2YneQz0fNiKQN93JI AU7g== X-Gm-Message-State: ALoCoQl0JODJh7S6FnWvUvqKlOiinLyyauM/jYEnGEuGIJcrtKLKVcXkBESMyLTMe+ipeTmu9Gnl X-Received: by 10.182.186.105 with SMTP id fj9mr11157249obc.5.1395148291502; Tue, 18 Mar 2014 06:11:31 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: lng-odp@linaro.org Received: by 10.140.97.229 with SMTP id m92ls2127792qge.47.gmail; Tue, 18 Mar 2014 06:11:31 -0700 (PDT) X-Received: by 10.229.96.199 with SMTP id i7mr10448055qcn.20.1395148291284; Tue, 18 Mar 2014 06:11:31 -0700 (PDT) Received: from mail-qc0-f178.google.com (mail-qc0-f178.google.com [209.85.216.178]) by mx.google.com with ESMTPS id j62si2938455qgf.191.2014.03.18.06.11.31 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 18 Mar 2014 06:11:31 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.216.178 is neither permitted nor denied by best guess record for domain of petri.savolainen@linaro.org) client-ip=209.85.216.178; Received: by mail-qc0-f178.google.com with SMTP id i8so7569055qcq.23 for ; Tue, 18 Mar 2014 06:11:31 -0700 (PDT) X-Received: by 10.224.161.72 with SMTP id q8mr9969020qax.83.1395148291154; Tue, 18 Mar 2014 06:11:31 -0700 (PDT) Received: from localhost.localdomain (ec2-23-23-178-99.compute-1.amazonaws.com. [23.23.178.99]) by mx.google.com with ESMTPSA id b16sm53219780qag.14.2014.03.18.06.11.28 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 18 Mar 2014 06:11:30 -0700 (PDT) From: Petri Savolainen To: lng-odp@linaro.org Cc: Petri Savolainen Subject: [lng-odp] [PATCH] Fixed back-to-back barrier bug Date: Tue, 18 Mar 2014 15:13:07 +0200 Message-Id: <1395148387-8912-1-git-send-email-petri.savolainen@linaro.org> X-Mailer: git-send-email 1.8.5.3 X-Original-Sender: petri.savolainen@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.216.178 is neither permitted nor denied by best guess record for domain of petri.savolainen@linaro.org) smtp.mail=petri.savolainen@linaro.org Precedence: list Mailing-list: list lng-odp@linaro.org; contact lng-odp+owners@linaro.org List-ID: X-Google-Group-Id: 474323889996 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , There was a race condition with the "in" variable. This patch uses more robust barrier exit synchronization to avoid the race. Signed-off-by: Petri Savolainen --- include/odp_barrier.h | 5 ++- platform/linux-generic/source/odp_barrier.c | 52 +++++++++++++++++++++-------- test/example/odp_example.c | 4 +++ 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/include/odp_barrier.h b/include/odp_barrier.h index bb4a6c5..19dfc06 100644 --- a/include/odp_barrier.h +++ b/include/odp_barrier.h @@ -28,8 +28,11 @@ extern "C" { */ typedef struct odp_barrier_t { int count; + volatile int wait; + volatile int wait_exit; odp_atomic_int_t in; - odp_atomic_int_t out; + odp_atomic_int_t waiting; + odp_atomic_int_t waiting_exit; } odp_barrier_t; diff --git a/platform/linux-generic/source/odp_barrier.c b/platform/linux-generic/source/odp_barrier.c index 64fbdb9..b27afc7 100644 --- a/platform/linux-generic/source/odp_barrier.c +++ b/platform/linux-generic/source/odp_barrier.c @@ -10,9 +10,13 @@ void odp_barrier_init_count(odp_barrier_t *barrier, int count) { - barrier->count = count; - barrier->in = 0; - barrier->out = count - 1; + barrier->count = count; + barrier->wait = 1; + barrier->wait_exit = 0; + barrier->in = 0; + barrier->waiting = 0; + barrier->waiting_exit = 0; + odp_sync_stores(); } @@ -26,25 +30,47 @@ void odp_barrier_sync(odp_barrier_t *barrier) count = odp_atomic_fetch_inc_int(&barrier->in); if (count == barrier->count - 1) { - /* If last thread, release others */ - barrier->in = 0; + /* + * This is the last thread. + * Spin until other threads are waiting. + */ + while (barrier->waiting != barrier->count-1) + odp_spin(); + + /* Reset barrier entry */ + barrier->wait_exit = 1; + barrier->in = 0; + barrier->waiting = 0; + barrier->waiting_exit = 0; odp_sync_stores(); - /* Wait for others to exit */ - while (barrier->out) + /* Move other threads to wait for exit */ + barrier->wait = 0; + + /* Spin until other threads are waiting for exit */ + while (barrier->waiting_exit != barrier->count-1) odp_spin(); - /* Ready, reset out counter */ - barrier->out = barrier->count - 1; + /* Reset barrier exit */ + barrier->waiting_exit = 0; + barrier->wait = 1; odp_sync_stores(); + /* Let other threads to exit */ + barrier->wait_exit = 0; + + odp_sync_stores(); } else { - /* Wait for the last thread*/ - while (barrier->in) + odp_atomic_inc_int(&barrier->waiting); + + while (barrier->wait) + odp_spin(); + + odp_atomic_inc_int(&barrier->waiting_exit); + + while (barrier->wait_exit) odp_spin(); - /* Ready */ - odp_atomic_dec_int(&barrier->out); odp_mem_barrier(); } } diff --git a/test/example/odp_example.c b/test/example/odp_example.c index 4764657..a6ab89e 100644 --- a/test/example/odp_example.c +++ b/test/example/odp_example.c @@ -507,6 +507,10 @@ static void *run_thread(void *arg) odp_barrier_sync(&test_barrier); odp_barrier_sync(&test_barrier); odp_barrier_sync(&test_barrier); + odp_barrier_sync(&test_barrier); + odp_barrier_sync(&test_barrier); + odp_barrier_sync(&test_barrier); + odp_barrier_sync(&test_barrier); /* * Find the buffer pool