DirectResult fusion_property_purchase (FusionProperty *property) { int count = 0; D_ASSERT( property != NULL ); if (property->multi.builtin.destroyed) return DR_DESTROYED; D_ASSUME( property->multi.builtin.owner != direct_gettid() ); asm( "" ::: "memory" ); while (property->multi.builtin.state == FUSION_PROPERTY_LEASED) { /* Check whether owner exited without releasing. */ if (kill( property->multi.builtin.owner, 0 ) < 0 && errno == ESRCH) { property->multi.builtin.state = FUSION_PROPERTY_AVAILABLE; property->multi.builtin.requested = false; break; } property->multi.builtin.requested = true; asm( "" ::: "memory" ); if (++count > 1000) { usleep( 10000 ); count = 0; } else { direct_sched_yield(); } if (property->multi.builtin.destroyed) return DR_DESTROYED; } if (property->multi.builtin.state == FUSION_PROPERTY_PURCHASED) { /* Check whether owner exited without releasing. */ if (!(kill( property->multi.builtin.owner, 0 ) < 0 && errno == ESRCH)) return DR_BUSY; } property->multi.builtin.state = FUSION_PROPERTY_PURCHASED; property->multi.builtin.owner = direct_gettid(); asm( "" ::: "memory" ); return DR_OK; }
DirectResult fusion_property_cede (FusionProperty *property) { D_ASSERT( property != NULL ); if (property->multi.builtin.destroyed) return DR_DESTROYED; D_ASSUME( property->multi.builtin.state != FUSION_PROPERTY_AVAILABLE ); D_ASSUME( property->multi.builtin.owner == direct_gettid() ); property->multi.builtin.state = FUSION_PROPERTY_AVAILABLE; property->multi.builtin.owner = 0; asm( "" ::: "memory" ); if (property->multi.builtin.requested) { property->multi.builtin.requested = false; asm( "" ::: "memory" ); direct_sched_yield(); }
DirectResult fusion_skirmish_prevail( FusionSkirmish *skirmish ) { D_ASSERT( skirmish != NULL ); if (skirmish->multi.builtin.destroyed) return DR_DESTROYED; asm( "" ::: "memory" ); if (skirmish->multi.builtin.locked && skirmish->multi.builtin.owner != direct_gettid()) { int count = 0; while (skirmish->multi.builtin.locked) { /* Check whether owner exited without unlocking. */ if (kill( skirmish->multi.builtin.owner, 0 ) < 0 && errno == ESRCH) { skirmish->multi.builtin.locked = 0; skirmish->multi.builtin.requested = false; break; } skirmish->multi.builtin.requested = true; asm( "" ::: "memory" ); if (++count > 1000) { usleep( 10000 ); count = 0; } else { direct_sched_yield(); } if (skirmish->multi.builtin.destroyed) return DR_DESTROYED; } }