Deutsch English Français Italiano |
<vbq57c$33j9p$2@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!3.eu.feeder.erje.net!feeder.erje.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> Newsgroups: comp.arch Subject: Re: arm ldxr/stxr vs cas Date: Tue, 10 Sep 2024 12:04:12 -0700 Organization: A noiseless patient Spider Lines: 279 Message-ID: <vbq57c$33j9p$2@dont-email.me> References: <vb4sit$2u7e2$1@dont-email.me> <07d60bd0a63b903820013ae60792fb7a@www.novabbs.org> <vbc4u3$aj5s$1@dont-email.me> <898cf44224e9790b74a0269eddff095a@www.novabbs.org> <vbd4k1$fpn6$1@dont-email.me> <vbd91c$g5j0$1@dont-email.me> <vbm790$2atfb$2@dont-email.me> <vbn0o6$2ed30$1@dont-email.me> <vbp33u$2sr79$1@dont-email.me> <vbpme1$30k42$2@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Tue, 10 Sep 2024 21:04:13 +0200 (CEST) Injection-Info: dont-email.me; posting-host="0eac113f4bd26321cfce58ecec11144e"; logging-data="3263801"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+xKboGKFBggcsNEJKDvfxaCUpUrHWl2v4=" User-Agent: Mozilla Thunderbird Cancel-Lock: sha1:9u4wE36aqFG6tICh18jV0dmcI5c= Content-Language: en-US In-Reply-To: <vbpme1$30k42$2@dont-email.me> Bytes: 7842 On 9/10/2024 7:51 AM, jseigh wrote: [...] This older code of mine is using Relacy, but you should get the "jist" of it: ________________________________ #include <iostream> #include <cstddef> #include <relacy/relacy.hpp> #define CT_THREAD_N 5 #define CT_WORK_N 3 #define CT_PRODUCER_WORK_N 5 #define CT_CONSUMER_WORK_N 2 #define CT_DISTRIBUTE_WORK_N CT_THREAD_N // Notes: // Using spin backoff for waits as of now // Need to slow-path it with with kernel waits // Need to refine the per-node backoff // humm... #define CT_PENDING ((ct_xchg_lifo_ver_001::work*)(0xDEADBEEF)) static unsigned long g_stats_local_work = 0; static unsigned long g_stats_foreign_work = 0; struct ct_xchg_lifo_ver_001 { // simulate some work... struct work { rl::atomic<work*> m_next; VAR_T(unsigned long) m_work; VAR_T(unsigned long) m_tidx; work(unsigned long tidx) : m_next(CT_PENDING), m_work(0), m_tidx(tidx) { } ~work() { RL_ASSERT(VAR(m_work) == 1); } // no data races on m_work! void execute_work(unsigned long tidx) { VAR(m_work) += 1; unsigned long local_tidx = VAR(m_tidx); if (local_tidx != tidx) { g_stats_foreign_work += 1; /* std::cout << "foriegn work detected " << local_tidx << " -> " << tidx << std::endl; */ } else { g_stats_local_work += 1; /* std::cout << "local work detected " << local_tidx << " -> " << tidx << std::endl; */ } } // this is the pending node logic... work* get_next() { work* next = m_next.load(rl::mo_relaxed, $); while (next == CT_PENDING) { rl::backoff(); next = m_next.load(rl::mo_relaxed, $); } return next; } static void process(work* cur, unsigned long tidx) { // must not be pending! RL_ASSERT(cur != CT_PENDING); // process work nodes... while (cur) { // do real work _before_ the pending logic // this is highly beneficial... Big time! cur->execute_work(tidx); // get the next work node. cur = cur->get_next(); } } // dump worked on nodes... static void destroy(work* cur, unsigned long tidx) { // no pending work shall be destroyed! RL_ASSERT(cur != CT_PENDING); while (cur) { work* next = cur->m_next.load(rl::mo_relaxed, $); // no pending work shall be destroyed! RL_ASSERT(next != CT_PENDING); delete cur; cur = next; } } }; rl::atomic<work*> m_head; ct_xchg_lifo_ver_001() : m_head(nullptr) { } ~ct_xchg_lifo_ver_001() { RL_ASSERT(!m_head.load(rl::mo_relaxed, $)); } void push(work* w) { // this completes the pending logic... w->m_next.store(CT_PENDING, rl::mo_relaxed, $); work* head = m_head.exchange(w, rl::mo_release, $); w->m_next.store(head, rl::mo_relaxed, $); } work* flush() ========== REMAINDER OF ARTICLE TRUNCATED ==========