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); } }
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); } }
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); }
/* * 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); }
/* * 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); }
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 } }