Print this page
6138 don't abuse atomic_cas_*
*** 62,72 ****
* Every CPU has xc_work_cnt, which indicates it has messages to process.
* This value is incremented as message traffic is initiated and decremented
* with every message that finishes all processing.
*
* The code needs no mfence or other membar_*() calls. The uses of
! * atomic_cas_ptr(), atomic_cas_32() and atomic_dec_32() for the message
* passing are implemented with LOCK prefix instructions which are
* equivalent to mfence.
*
* One interesting aspect of this implmentation is that it allows 2 or more
* CPUs to initiate cross calls to intersecting sets of CPUs at the same time.
--- 62,72 ----
* Every CPU has xc_work_cnt, which indicates it has messages to process.
* This value is incremented as message traffic is initiated and decremented
* with every message that finishes all processing.
*
* The code needs no mfence or other membar_*() calls. The uses of
! * atomic_cas_ptr(), atomic_inc_32_nv() and atomic_dec_32() for the message
* passing are implemented with LOCK prefix instructions which are
* equivalent to mfence.
*
* One interesting aspect of this implmentation is that it allows 2 or more
* CPUs to initiate cross calls to intersecting sets of CPUs at the same time.
*** 140,154 ****
* Increment a CPU's work count and return the old value
*/
static int
xc_increment(struct machcpu *mcpu)
{
! int old;
! do {
! old = mcpu->xc_work_cnt;
! } while (atomic_cas_32(&mcpu->xc_work_cnt, old, old + 1) != old);
! return (old);
}
/*
* Put a message into a queue. The insertion is atomic no matter
* how many different inserts/extracts to the same queue happen.
--- 140,150 ----
* Increment a CPU's work count and return the old value
*/
static int
xc_increment(struct machcpu *mcpu)
{
! return (atomic_inc_32_nv(&mcpu->xc_work_cnt) - 1);
}
/*
* Put a message into a queue. The insertion is atomic no matter
* how many different inserts/extracts to the same queue happen.