Exemplo n.º 1
0
void
_bmap_op_done(const struct pfl_callerinfo *pci, struct bmap *b,
    const char *fmt, ...)
{
	va_list ap;

	BMAP_LOCK_ENSURE(b);

	psc_assert(!(b->bcm_flags & BMAPF_TOFREE));

	va_start(ap, fmt);
	_psclogv_pci(pci, SLSS_BMAP, 0, fmt, ap);
	va_end(ap);

	if (!psc_atomic32_read(&b->bcm_opcnt)) {
		b->bcm_flags |= BMAPF_TOFREE;
		DEBUG_BMAP(PLL_DIAG, b, "free bmap now");
		BMAP_ULOCK(b);

		/*
		 * Invoke service specific bmap cleanup callbacks:
		 * mds_bmap_destroy(), iod_bmap_finalcleanup(), and
		 * msl_bmap_final_cleanup().
		 */
		if (sl_bmap_ops.bmo_final_cleanupf)
			sl_bmap_ops.bmo_final_cleanupf(b);

		bmap_remove(b);
	} else {
		bmap_wake_locked(b);
		BMAP_ULOCK(b);
	}
}
Exemplo n.º 2
0
void
slmbmaptimeothr_begin(struct psc_thread *thr)
{
	struct bmap_mds_lease *bml;
	int rc, nsecs = 0;

	while (pscthr_run(thr)) {
		spinlock(&mdsBmapTimeoTbl.btt_lock);
		bml = pll_peekhead(&mdsBmapTimeoTbl.btt_leases);
		if (!bml) {
			freelock(&mdsBmapTimeoTbl.btt_lock);
			nsecs = BMAP_TIMEO_MAX;
			goto sleep;
		}

		if (!BML_TRYLOCK(bml)) {
			freelock(&mdsBmapTimeoTbl.btt_lock);
			nsecs = 1;
			goto sleep;
		}
		if (bml->bml_refcnt) {
			BML_ULOCK(bml);
			freelock(&mdsBmapTimeoTbl.btt_lock);
			nsecs = 1;
			goto sleep;
		}

		if (!(bml->bml_flags & BML_FREEING)) {
			nsecs = bml->bml_expire - time(NULL);
			if (nsecs > 0) {
				BML_ULOCK(bml);
				freelock(&mdsBmapTimeoTbl.btt_lock);
				goto sleep;
			}
			bml->bml_flags |= BML_FREEING;
		}

		BML_ULOCK(bml);
		freelock(&mdsBmapTimeoTbl.btt_lock);

		rc = mds_bmap_bml_release(bml);
		if (rc) {
			DEBUG_BMAP(PLL_WARN, bml_2_bmap(bml),
			    "rc=%d bml=%p fl=%d seq=%"PRId64,
			    rc, bml, bml->bml_flags, bml->bml_seq);
			nsecs = 1;
		} else
			nsecs = 0;
 sleep:
		psclog_debug("nsecs=%d", nsecs);

		if (nsecs > 0)
			sleep((uint32_t)nsecs);
	}
}
Exemplo n.º 3
0
void
bmap_remove(struct bmap *b)
{
	struct fidc_membh *f = b->bcm_fcmh;

	DEBUG_BMAP(PLL_DIAG, b, "removing");

	pfl_rwlock_wrlock(&f->fcmh_rwlock);
	PSC_RB_XREMOVE(bmaptree, &f->fcmh_bmaptree, b);
	pfl_rwlock_unlock(&f->fcmh_rwlock);

	fcmh_op_done_type(f, FCMH_OPCNT_BMAP);
	psc_pool_return(bmap_pool, b);
}
Exemplo n.º 4
0
/*
 * Get the specified bmap.
 * @f: fcmh.
 * @n: bmap number.
 * @rw: access mode.
 * @flags: retrieval parameters.
 * @bp: value-result bmap pointer.
 * Notes: returns the bmap referenced and locked.
 */
int
_bmap_get(const struct pfl_callerinfo *pci, struct fidc_membh *f,
    sl_bmapno_t n, enum rw rw, int flags, struct bmap **bp)
{
	int rc = 0, new_bmap, bmaprw = 0;
	struct bmap *b;

	if (bp)
		*bp = NULL;

	if (rw)
		bmaprw = rw == SL_WRITE ? BMAPF_WR : BMAPF_RD;

	new_bmap = flags & BMAPGETF_CREATE;
	b = bmap_lookup_cache(f, n, bmaprw, &new_bmap);
	if (b == NULL) {
		rc = ENOENT;
		goto out;
	}
	if (flags & BMAPGETF_NONBLOCK) {
		if (b->bcm_flags & BMAPF_LOADING)
			goto out;
	} else
		bmap_wait_locked(b, b->bcm_flags & BMAPF_LOADING);

	if (b->bcm_flags & BMAPF_LOADED)
		goto loaded;

	if (flags & BMAPGETF_NORETRIEVE) {
		if (b->bcm_flags & BMAPF_LOADED)
			OPSTAT_INCR("bmap-already-loaded");
		else
			OPSTAT_INCR("bmap-not-yet-loaded");
		goto out;
	}

	b->bcm_flags |= BMAPF_LOADING;
	DEBUG_BMAP(PLL_DIAG, b, "loading bmap; flags=%d", flags);
	BMAP_ULOCK(b);

	/* msl_bmap_retrieve(), iod_bmap_retrieve(), mds_bmap_read() */
	rc = sl_bmap_ops.bmo_retrievef(b, flags);

	BMAP_LOCK(b);

	if (flags & BMAPGETF_NONBLOCK) {
		if (rc)
			b->bcm_flags &= ~BMAPF_LOADING;
		goto out;
	}
	b->bcm_flags &= ~BMAPF_LOADING;
	if (!rc) {
		b->bcm_flags |= BMAPF_LOADED;
		bmap_wake_locked(b);
	}

 loaded:

	/*
 	 * Early bail out should be safe.  There is only one place the client
 	 * will do a bmap lookup.  And it that code path, we just add DIO flag
 	 * to the bmap.  See msrcm_handle_bmapdio().
 	 */
	if (rc || !bmaprw)
		goto out;

	/*
	 * Others wishing to access this bmap in the same mode must wait
	 * until MODECHNG ops have completed.  If the desired mode is
	 * present then a thread may proceed without blocking here so
	 * long as it only accesses structures which pertain to its
	 * mode.
	 */
	if (flags & BMAPGETF_NONBLOCK) {
		if (b->bcm_flags & BMAPF_MODECHNG)
			goto out;
	} else
		bmap_wait_locked(b, b->bcm_flags & BMAPF_MODECHNG);

	/*
	 * Not all lookups are done with the intent of changing the bmap
	 * mode i.e. bmap_lookup() does not specify a rw value.
	 */
	if (!(bmaprw & b->bcm_flags) && sl_bmap_ops.bmo_mode_chngf) {

		psc_assert(!(b->bcm_flags & BMAPF_MODECHNG));
		b->bcm_flags |= BMAPF_MODECHNG;

		DEBUG_BMAP(PLL_DIAG, b, "mode change (rw=%d)", rw);

		BMAP_ULOCK(b);

		psc_assert(rw == SL_WRITE || rw == SL_READ);

	 	/* client only: call msl_bmap_modeset() */
		rc = sl_bmap_ops.bmo_mode_chngf(b, rw, flags);
		BMAP_LOCK(b);
	}

 out:
	if (b) {
		DEBUG_BMAP(rc && (rc != SLERR_BMAP_INVALID ||
		    (flags & BMAPGETF_NOAUTOINST) == 0) ?
		    PLL_ERROR : PLL_DIAG, b, "grabbed rc=%d", rc);
		if (rc)
			bmap_op_done(b);
		else
			*bp = b;
	}
	return (rc);
}
Exemplo n.º 5
0
/*
 * Lookup and optionally create a new bmap structure.
 * @f: file's bmap tree to search.
 * @n: bmap index number to search for.
 * @new_bmap: whether to allow creation and also value-result of whether
 * it was newly created or not.
 */
struct bmap *
bmap_lookup_cache(struct fidc_membh *f, sl_bmapno_t n, int bmaprw,
    int *new_bmap)
{
	struct bmap lb, *b, *bnew = NULL;
	int doalloc;

	doalloc = *new_bmap;
	lb.bcm_bmapno = n;

 restart:
	if (bnew)
		pfl_rwlock_wrlock(&f->fcmh_rwlock);
	else
		pfl_rwlock_rdlock(&f->fcmh_rwlock);
	b = RB_FIND(bmaptree, &f->fcmh_bmaptree, &lb);
	if (b) {
		if (!BMAP_TRYLOCK(b)) {
			pfl_rwlock_unlock(&f->fcmh_rwlock);
			usleep(10);
			goto restart;
		}

		if (b->bcm_flags & BMAPF_TOFREE) {
			/*
			 * This bmap is going away; wait for it so we
			 * can reload it back.
			 */
			DEBUG_BMAP(PLL_DIAG, b, "wait on to-free bmap");
			BMAP_ULOCK(b);
			/*
			 * We don't want to spin if we are waiting for a
			 * flush to clear.
			 */
			psc_waitq_waitrelf_us(&f->fcmh_waitq,
			    PFL_LOCKPRIMT_RWLOCK, &f->fcmh_rwlock, 100);
			goto restart;
		}
		bmap_op_start_type(b, BMAP_OPCNT_LOOKUP);
	}
	if (doalloc == 0 || b) {
		pfl_rwlock_unlock(&f->fcmh_rwlock);
		if (bnew)
			psc_pool_return(bmap_pool, bnew);
		*new_bmap = 0;
		OPSTAT_INCR("bmapcache.hit");
		return (b);
	}
	if (bnew == NULL) {
		pfl_rwlock_unlock(&f->fcmh_rwlock);

		if (sl_bmap_ops.bmo_reapf)
			sl_bmap_ops.bmo_reapf();

		bnew = psc_pool_get(bmap_pool);
		goto restart;
	}
	b = bnew;

	OPSTAT_INCR("bmapcache.miss");

	*new_bmap = 1;
	memset(b, 0, bmap_pool->ppm_master->pms_entsize);
	INIT_PSC_LISTENTRY(&b->bcm_lentry);
	INIT_SPINLOCK(&b->bcm_lock);

	psc_atomic32_set(&b->bcm_opcnt, 0);
	b->bcm_fcmh = f;
	b->bcm_bmapno = n;

	/*
	 * Signify that the bmap is newly initialized and therefore may
	 * not contain certain structures.
	 */
	psc_assert(bmaprw == BMAPF_RD || bmaprw == BMAPF_WR);
	b->bcm_flags = bmaprw;

	bmap_op_start_type(b, BMAP_OPCNT_LOOKUP);

	/*
	 * Perform app-specific substructure initialization, which is
	 * msl_bmap_init(), iod_bmap_init(), or mds_bmap_init().
	 */
	sl_bmap_ops.bmo_init_privatef(b);

	/* Add to the fcmh's bmap cache */
	PSC_RB_XINSERT(bmaptree, &f->fcmh_bmaptree, b);

	pfl_rwlock_unlock(&f->fcmh_rwlock);

	fcmh_op_start_type(f, FCMH_OPCNT_BMAP);

	BMAP_LOCK(b);

	return (b);
}
Exemplo n.º 6
0
void sc_lights_frmSun(SC_SCREEN* screen)
{
	if(screen.views.sun != NULL)
	{
		if(
		screen.settings.lights.sunPos.x == 0
		&& screen.settings.lights.sunPos.y == 0
		&& screen.settings.lights.sunPos.z == 0
		) //global sun
		{
			VECTOR distantSunPos;
			vec_for_angle(distantSunPos, sun_angle);
			vec_scale(distantSunPos, 9999999);
			screen.materials.sun.skill1 = floatv(distantSunPos.x);
			screen.materials.sun.skill2 = floatv(distantSunPos.y);
			screen.materials.sun.skill3 = floatv(distantSunPos.z);
		}
		else //local sun
		{
			screen.materials.sun.skill1 = floatv(screen.settings.lights.sunPos.x);
			screen.materials.sun.skill2 = floatv(screen.settings.lights.sunPos.y);
			screen.materials.sun.skill3 = floatv(screen.settings.lights.sunPos.z);
		}
		
		screen.materials.sun.skill4 = floatv(0); //local sun lightrange (not used)
		
		//sun color
		screen.materials.sun.skill5 = floatv(sun_color.red/255);
		screen.materials.sun.skill6 = floatv(sun_color.green/255);
		screen.materials.sun.skill7 = floatv(sun_color.blue/255);
		screen.materials.sun.skill8 = floatv(screen.views.main.clip_far);
		
		
		
		
		
		
		#ifndef SC_A7
			// PSSM main loop
			if(screen.settings.lights.sunPssmSplits>0 && screen.settings.lights.sunShadows == 1)
			{
				// update the views _after_ the camera was updated!
				//	proc_mode = PROC_LATE;
				
				// set up the split distances and the shadow view
				sc_lights_pssm_split(screen.views.main, screen.settings.lights.sunPssmSplits, screen.settings.lights.sunPssmSplitWeight, screen.settings.lights.sunShadowRange);
				//pssm_split(screen.views.main, screen.settings.lights.sunPssmSplits, screen.settings.lights.sunPssmSplitWeight);
				//pssm_viewcpy(screen.views.main, screen.views.sun);
				
				// set up the split view transformation matrices
				D3DXMATRIX matSplit[4];
				int i=0;
				for(i=0; i<screen.settings.lights.sunPssmSplits; i++) 
				{
					// look from the sun onto the scene			
					screen.views.sunShadowDepth[i]->pan = 180 + sun_angle.pan;
					screen.views.sunShadowDepth[i]->tilt = -sun_angle.tilt;
					vec_set(screen.views.sunShadowDepth[i]->x,sun_pos);
					
					// calculate the split view clipping borders and transformation matrix			
					view_to_split(screen.views.main, pssm_splitdist[i],pssm_splitdist[i+1], screen.views.sunShadowDepth[i], &matSplit[i]);
					LPD3DXEFFECT fx = screen.views.sunShadowDepth[i]->material->d3deffect;
					if(fx) fx->SetMatrix("matSplitViewProj",&matSplit[i]);
					
					// create a texture matrix from the split view proj matrix			
					D3DXMatrixMultiply(&matSplit[i],&matSplit[i],pssm_texscale(screen.settings.lights.sunShadowResolution));
					
					#ifdef DEBUG_PSSM		
						DEBUG_BMAP(screen.views.sunShadowDepth[i]->bmap,300 + i*220,0.2);
						var pssm_fps = 16/time_frame;
						DEBUG_VAR(pssm_fps,200);
						DEBUG_VAR(pssm_splitdist[i+1],220 + i*20);
					#endif
					//set depthmapshader maxDepth	
					screen.views.sunShadowDepth[i].material.skill4 = floatv(screen.views.sunShadowDepth[i].clip_far);
				}
				
				//put matrices to world space
				//mat_multiply(matSplit[0], matViewInv);
				// use a DX function to copy the 4 texture matrices to the shadow shader
				LPD3DXEFFECT fx = screen.views.sun->material->d3deffect;
				if(fx) {
					fx->SetMatrixArray("matTex",matSplit,screen.settings.lights.sunPssmSplits);
					if(screen.views.sunShadowDepth[0] != NULL) fx->SetTexture("shadowTex1",screen.renderTargets.sunShadowDepth[0].d3dtex);
					if(screen.views.sunShadowDepth[1] != NULL) fx->SetTexture("shadowTex2",screen.renderTargets.sunShadowDepth[1].d3dtex);
					if(screen.views.sunShadowDepth[2] != NULL) fx->SetTexture("shadowTex3",screen.renderTargets.sunShadowDepth[2].d3dtex);
					if(screen.views.sunShadowDepth[3] != NULL) fx->SetTexture("shadowTex4",screen.renderTargets.sunShadowDepth[3].d3dtex);
					//fx->SetFloat("shadowBias", screen.settings.lights.sunShadowBias);
					//fx->SetInt("shadowmapSize", (screen.settings.lights.sunShadowResolution) );
				}
				
				
				
				
				//same for shadowEdge acceleration
				LPD3DXEFFECT fx = screen.views.sunEdge->material->d3deffect;
				if(fx) {
					fx->SetMatrixArray("matTex",matSplit,screen.settings.lights.sunPssmSplits);
					if(screen.views.sunShadowDepth[0] != NULL) fx->SetTexture("shadowTex1",screen.renderTargets.sunShadowDepth[0].d3dtex);
					if(screen.views.sunShadowDepth[1] != NULL) fx->SetTexture("shadowTex2",screen.renderTargets.sunShadowDepth[1].d3dtex);
					if(screen.views.sunShadowDepth[2] != NULL) fx->SetTexture("shadowTex3",screen.renderTargets.sunShadowDepth[2].d3dtex);
					if(screen.views.sunShadowDepth[3] != NULL) fx->SetTexture("shadowTex4",screen.renderTargets.sunShadowDepth[3].d3dtex);
					//fx->SetFloat("shadowBias", screen.settings.lights.sunShadowBias);
					//fx->SetInt("shadowmapSize", (screen.settings.lights.sunShadowResolution) );
				}
				//and for the actual shadow view
				LPD3DXEFFECT fx = screen.views.sunShadow->material->d3deffect;
				if(fx) {
					fx->SetMatrixArray("matTex",matSplit,screen.settings.lights.sunPssmSplits);
					if(screen.views.sunShadowDepth[0] != NULL) fx->SetTexture("shadowTex1",screen.renderTargets.sunShadowDepth[0].d3dtex);
					if(screen.views.sunShadowDepth[1] != NULL) fx->SetTexture("shadowTex2",screen.renderTargets.sunShadowDepth[1].d3dtex);
					if(screen.views.sunShadowDepth[2] != NULL) fx->SetTexture("shadowTex3",screen.renderTargets.sunShadowDepth[2].d3dtex);
					if(screen.views.sunShadowDepth[3] != NULL) fx->SetTexture("shadowTex4",screen.renderTargets.sunShadowDepth[3].d3dtex);
					//fx->SetFloat("shadowBias", screen.settings.lights.sunShadowBias);
					//fx->SetInt("shadowmapSize", (screen.settings.lights.sunShadowResolution) );
				}
				
				
				
				
				screen.views.sun.material.skill4 = floatv(screen.views.sunShadowDepth[0].clip_far);
				
				#ifdef DEBUG_PSSM		
					DEBUG_BMAP(screen.views.sun->bmap,20,0.2);
				#endif
			}
		#endif
		
		
	}
}