DragonFlyBSDのcrit_enter()とcrit_exit()めも

せっかくなのでめもっとこφ(.. )メモシテオコウ crit_enter()とcrit_exit()はsys/sys/thread2.hでマクロとして定義されてて、これらの実態も同じくthred2.hで定義されてます。

#define crit_enter()                    _crit_enter(mycpu)
#define crit_exit()                     crit_exit_wrapper()

やってることはクリティカルセクションに入るときに変数の値をインクリメントして、出るときにデクリメントするというだけで、FreeBSDのcritical_enter()、critical_exit()と同じですね。

/*
 * crit_enter
 */
static __inline void
_crit_enter_quick(thread_t td __DEBUG_CRIT_ADD_ARG__)
{
    ++td->td_critcount;
    __DEBUG_CRIT_ENTER(td);
    cpu_ccfence();
}

static __inline void
_crit_enter(globaldata_t gd __DEBUG_CRIT_ADD_ARG__)
{
    _crit_enter_quick(gd->gd_curthread __DEBUG_CRIT_PASS_ARG__);
}

static __inline void
_crit_exit_noyield(thread_t td __DEBUG_CRIT_ADD_ARG__)
{
    __DEBUG_CRIT_EXIT(td);
    --td->td_critcount;
#ifdef INVARIANTS
    if (__predict_false(td->td_critcount td_gd->gd_reqflags & RQF_IDLECHECK_MASK))
        lwkt_maybe_splz(td);
}

static __inline void
_crit_exit(globaldata_t gd __DEBUG_CRIT_ADD_ARG__)
{
    _crit_exit_quick(gd->gd_curthread __DEBUG_CRIT_PASS_ARG__);
}

crit_enter()の場合はcpu_ccfence()が呼ばれますが、これは/usr/src/sys/cpu/x86_64/include /cpufunc.hで以下のように定義されてます。中身はメモリバリアの実施です。

static __inline void
cpu_ccfence(void)
{
        __asm __volatile("" : : : "memory");
}

そういえば、これらに__inlineがついてたのでよくよく探したら定義が /usr/src/sys/sys/cdefs.h にいたしちょっとこれをインクルードさせてみるか。