From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 87D503896C1F for ; Tue, 15 Nov 2022 13:04:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 87D503896C1F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [111.9.175.10]) by gateway (Coremail) with SMTP id _____8Cx7NhEjnNj8UQHAA--.21569S3; Tue, 15 Nov 2022 21:04:05 +0800 (CST) Received: from localhost.localdomain (unknown [111.9.175.10]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Dx9VZCjnNjlqQTAA--.34056S2; Tue, 15 Nov 2022 21:04:03 +0800 (CST) From: Jinyang He To: Chenghua Xu , Lulu Cheng Cc: Weining Lu , Xing Li , yala , Peng Fan , gcc-patches@gcc.gnu.org Subject: [PATCH] LoongArch: Fix atomic_exchange make comparison and may jump out Date: Tue, 15 Nov 2022 21:03:28 +0800 Message-Id: <20221115130328.15413-1-hejinyang@loongson.cn> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:AQAAf8Dx9VZCjnNjlqQTAA--.34056S2 X-CM-SenderInfo: pkhmx0p1dqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxuF45Jr4rKw45ur47uFW5Awb_yoWrAr1rpr W7Awnxtr48Jan3G397GFW7Jws8A3sF9F42vFW7Gwn293y3WryUX3W0yr9IqFyUKw4Sqr1f ZF4av34UWa9rtrJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU b7kYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26F4UJVW0owAS 0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI0UMc02F40EFcxC0V AKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1l Ox8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28IcxkI7VAKI48JMxC20s 026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_ JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14 v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY6xAIw20EY4v20xva j40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVWUJV W8JbIYCTnIWIevJa73UjIFyTuYvjxUrNtxDUUUU X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_DMARC_STATUS,KAM_SHORT,SPF_HELO_PASS,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: gcc/ChangeLog: * config/loongarch/sync.md: Add atomic_cas_value_exchange_and_7 and fix atomic_exchange. gcc/testsuite/ChangeLog: * gcc.target/loongarch/sync-1.c: New test. --- gcc/config/loongarch/sync.md | 27 ++++- gcc/testsuite/gcc.target/loongarch/sync-1.c | 104 ++++++++++++++++++++ 2 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/sync-1.c diff --git a/gcc/config/loongarch/sync.md b/gcc/config/loongarch/sync.md index 0c4f1983e..8a8e6247b 100644 --- a/gcc/config/loongarch/sync.md +++ b/gcc/config/loongarch/sync.md @@ -448,6 +448,29 @@ } [(set (attr "length") (const_int 32))]) +(define_insn "atomic_cas_value_exchange_and_7_" + [(set (match_operand:GPR 0 "register_operand" "=&r") + (match_operand:GPR 1 "memory_operand" "+ZC")) + (set (match_dup 1) + (unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "rJ") + (match_operand:GPR 3 "reg_or_0_operand" "rJ") + (match_operand:GPR 4 "reg_or_0_operand" "rJ") + (match_operand:GPR 5 "reg_or_0_operand" "rJ") + (match_operand:SI 6 "const_int_operand")] ;; model + UNSPEC_SYNC_EXCHANGE)) + (clobber (match_scratch:GPR 7 "=&r"))] + "" +{ + return "%G6\\n\\t" + "1:\\n\\t" + "ll.\\t%0,%1\\n\\t" + "and\\t%7,%0,%z3\\n\\t" + "or%i5\\t%7,%7,%5\\n\\t" + "sc.\\t%7,%1\\n\\t" + "beqz\\t%7,1b\\n\\t"; +} + [(set (attr "length") (const_int 20))]) + (define_expand "atomic_exchange" [(set (match_operand:SHORT 0 "register_operand") (unspec_volatile:SHORT @@ -459,9 +482,9 @@ "" { union loongarch_gen_fn_ptrs generator; - generator.fn_7 = gen_atomic_cas_value_cmp_and_7_si; + generator.fn_7 = gen_atomic_cas_value_exchange_and_7_si; loongarch_expand_atomic_qihi (generator, operands[0], operands[1], - operands[1], operands[2], operands[3]); + const0_rtx, operands[2], operands[3]); DONE; }) diff --git a/gcc/testsuite/gcc.target/loongarch/sync-1.c b/gcc/testsuite/gcc.target/loongarch/sync-1.c new file mode 100644 index 000000000..cebed6a9b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/sync-1.c @@ -0,0 +1,104 @@ +/* Test __sync_test_and_set in atomic_exchange */ +/* { dg-do run } */ +/* { dg-options "-lpthread -std=c11" } */ + +#include +#include +#include +#include + +#define NR_THREAD 16 +#define NR_DATA 1000 +#define ITER_COUNT 10000 + +static int _data[NR_DATA]; +static char _lock; +static int _overcnt; + +static inline void proc_yield(int cnt) +{ + __asm__ __volatile__("":::"memory"); +} + +static void unlock() +{ + return atomic_store_explicit(&_lock, 0, memory_order_seq_cst); +} + +static int trylock() +{ + return atomic_exchange_explicit(&_lock, 1, memory_order_acquire) == 0; +} + +static void lockslow() +{ + for (int i = 0;; i++) { + if (i < 10) + proc_yield(i); + else + sched_yield(); + if (atomic_load_explicit(&_lock, memory_order_relaxed) == 0 + && atomic_exchange_explicit(&_lock, 1, memory_order_acquire) == 0) + return; + } +} + +static void lock() +{ + if (trylock()) + return; + lockslow(); +} + +static void checkeq(int a, int b) +{ + if (a != b) + __builtin_abort(); +} + +static void adddata() +{ + int i, v; + lock(); + v = _data[0]; + for (i = 0; i < NR_DATA; i++) { + checkeq(_data[i], v); + _data[i]++; + } + unlock(); +} + +static void backoff() +{ + int i, data[NR_DATA] = {0}; + for (i = 0; i < NR_DATA; i++) { + data[i]++; + checkeq(data[i], 1); + } +} + +static void *write_mutex_thread(void *unused) +{ + int i; + for (i = 0; i < ITER_COUNT; i++) { + adddata(); + backoff(); + } + atomic_fetch_add(&_overcnt, 1); +} + +int main() +{ + int cnt; + + pthread_t threads[NR_THREAD]; + for (int i = 0; i < NR_THREAD; i++) + pthread_create(&threads[i], 0, write_mutex_thread, NULL); + for (int i = 0; i < NR_THREAD; i++) + pthread_detach(threads[i]); + while(cnt != NR_THREAD) { + sched_yield(); + cnt = atomic_load(&_overcnt); + } + return 0; +} -- 2.34.3