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 ==========