void * _lc_get(struct psc_listcache *plc, const struct timespec *abstime, int flags) { int locked, rc; void *p; locked = LIST_CACHE_RLOCK(plc); // if (plc->plc_flags & PLCF_DYING) // pfl_assert(flags & PLCF_DYINGOK) while (lc_empty(plc)) { if ((plc->plc_flags & PLCF_DYING) || (flags & PLCBF_NOBLOCK)) { LIST_CACHE_URLOCK(plc, locked); return (NULL); } /* Alert listeners who want to know about exhaustion. */ pfl_waitq_wakeall(&plc->plc_wq_want); if (abstime) psclog_debug("lc@%p <%s> timed wait "PSCPRI_TIMESPEC, plc, plc->plc_name, PSCPRI_TIMESPEC_ARGS(abstime)); else psclog_debug("lc@%p <%s> blocking wait", plc, plc->plc_name); if (abstime) { rc = pfl_waitq_waitabs(&plc->plc_wq_empty, LIST_CACHE_GETLOCK(plc), abstime); if (rc) { pfl_assert(rc == ETIMEDOUT); errno = rc; return (NULL); } } else pfl_waitq_wait(&plc->plc_wq_empty, LIST_CACHE_GETLOCK(plc)); LIST_CACHE_LOCK(plc); } if (flags & PLCBF_TAIL) p = pll_peektail(&plc->plc_pll); else p = pll_peekhead(&plc->plc_pll); if ((flags & PLCBF_PEEK) == 0) lc_remove(plc, p); LIST_CACHE_URLOCK(plc, locked); return (p); }
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 child_main(__unusedx struct psc_thread *thr) { char buf[40]; int i; /* * Wait here until the parent signals us to start */ psc_waitq_wait(&waitq, NULL); psclog_debug("after pseudo barrier"); /* Connect to control socket. */ (void)FMTSTR(buf, sizeof(buf), "foobar%h", FMTSTRCASE('h', "s", "test") ); for (i = 0; i < iterations; i++) { psc_waitq_wait(&waitq, NULL); psclog_debug("i=%d awake", i); } }
int main(int argc, char *argv[]) { int c, i, rc = 0; progname = argv[0]; pfl_init(); while ((c = getopt(argc, argv, "n:i:")) != -1) switch (c) { case 'n': nthreads = atoi(optarg); break; case 'i': iterations = atoi(optarg); break; default: usage(); } argc -= optind; if (argc) usage(); psclog_debug("nthreads = %d", nthreads); psc_waitq_init(&waitq); for (i = 0; i < nthreads; i++) pscthr_init(0, child_main, NULL, 0, "thr%d", i); sleep(1); psc_waitq_wakeall(&waitq); sleep(2); i = nthreads * iterations; while (i--) { psc_waitq_wakeone(&waitq); usleep(30); } return rc; }
/* * Build the pathname in the FID object root that corresponds to a FID, * allowing easily lookup of file metadata via FIDs. */ void sli_fg_makepath(const struct sl_fidgen *fg, char *fid_path) { char *p, str[(FID_PATH_DEPTH * 2) + 1]; uint64_t shift; int i; shift = BPHXC * (FID_PATH_START + FID_PATH_DEPTH - 1); for (p = str, i = 0; i < FID_PATH_DEPTH; i++, shift -= BPHXC) { *p = (fg->fg_fid & (0xf << shift)) >> shift; *p += *p < 10 ? '0' : 'a' - 10; p++; *p++ = '/'; } *p = '\0'; xmkfn(fid_path, "%s/%s/%"PRIx64"/%s/%s%016"PRIx64"_%"PRIx64, slcfg_local->cfg_fsroot, SL_RPATH_META_DIR, globalConfig.gconf_fsuuid, SL_RPATH_FIDNS_DIR, str, fg->fg_fid, fg->fg_gen); psclog_debug("fid="SLPRI_FID" fidpath=%s", fg->fg_fid, fid_path); }