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.