/* * Update GC stats for a new object allocation */ void ejsAddToGcStats(Ejs *ejs, EjsVar *vp, int id) { #if BLD_DEBUG EjsPool *pool; EjsGC *gc; gc = &ejs->gc; if (id < ejs->gc.numPools) { pool = ejs->gc.pools[id]; pool->allocated++; mprAssert(pool->allocated >= 0); if (pool->allocated > pool->peakAllocated) { pool->peakAllocated = pool->allocated; } } gc->totalAllocated++; gc->allocatedObjects++; if (gc->allocatedObjects >= gc->peakAllocatedObjects) { gc->peakAllocatedObjects = gc->allocatedObjects; } if (vp->type == ejs->typeType) { gc->allocatedTypes++; if (gc->allocatedTypes >= gc->peakAllocatedTypes) { gc->peakAllocatedTypes = gc->allocatedTypes; } } /* Convenient place for this */ vp->seq = nextSequence++; checkAddr(vp); #endif }
/* * Sweep up the garbage for a given generation */ static void sweep(Ejs *ejs, int maxGeneration) { EjsVar *vp; EjsGC *gc; EjsGen *gen; MprBlk *bp, *next; int destroyed, generation; /* * Go from oldest to youngest incase moving objects to elder generations and we clear the mark. */ gc = &ejs->gc; for (generation = maxGeneration; generation >= 0; generation--) { gc->collectGeneration = generation; gen = gc->generations[generation]; for (destroyed = 0, bp = mprGetFirstChild(gen); bp; bp = next) { next = bp->next; vp = MPR_GET_PTR(bp); checkAddr(vp); if (!vp->marked && !vp->permanent) { (vp->type->helpers->destroyVar)(ejs, vp); destroyed++; } } #if BLD_DEBUG gc->allocatedObjects -= destroyed; gc->totalReclaimed += destroyed; gen->totalReclaimed += destroyed; gen->totalSweeps++; #endif } }
/* * Mark a variable as used. All variable marking comes through here. * NOTE: The container is not used by anyone (verified). */ void ejsMarkVar(Ejs *ejs, EjsVar *container, EjsVar *vp) { if (vp && !vp->marked) { checkAddr(vp); vp->marked = 1; (vp->type->helpers->markVar)(ejs, container, vp); } }
bool DCStartd::_suspendClaim( ) { setCmdStr( "suspendClaim" ); if( ! checkClaimId() ) { return false; } if( ! checkAddr() ) { return false; } // if this claim is associated with a security session ClaimIdParser cidp(claim_id); char const *sec_session = cidp.secSessionId(); if (IsDebugLevel(D_COMMAND)) { int cmd = SUSPEND_CLAIM; dprintf (D_COMMAND, "DCStartd::_suspendClaim(%s,...) making connection to %s\n", getCommandStringSafe(cmd), _addr ? _addr : "NULL"); } bool result; ReliSock reli_sock; reli_sock.timeout(20); // years of research... :) if( ! reli_sock.connect(_addr) ) { std::string err = "DCStartd::_suspendClaim: "; err += "Failed to connect to startd ("; err += _addr ? _addr : "NULL"; err += ')'; newError( CA_CONNECT_FAILED, err.c_str() ); return false; } int cmd = SUSPEND_CLAIM; result = startCommand( cmd, (Sock*)&reli_sock, 20, NULL, NULL, false, sec_session ); if( ! result ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::_suspendClaim: Failed to send command " ); return false; } // Now, send the ClaimId if( ! reli_sock.put_secret(claim_id) ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::_suspendClaim: Failed to send ClaimId to the startd" ); return false; } if( ! reli_sock.end_of_message() ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::_suspendClaim: Failed to send EOM to the startd" ); return false; } return true; }
int Rom::writeData(void* data,int size,int addr) { if(!checkAddr(addr,size)) return 0; uchar* dataPtr = (uchar*)data; for(int i=0;i<size;) { romData[addr++] = dataPtr[i++]; } return 1; }
int Rom::checkRATSdata(int addr) { if(checkAddr(addr,8)) { // ゴリ押しは正義 if(romData[addr]=='S' && romData[addr+1]=='T' && romData[addr+2]=='A' && romData[addr+3]=='R') { ushort size = ((romData[addr+5]<<8) + romData[addr+4]); ushort invSize = ((romData[addr+7]<<8) + romData[addr+6]); if((size ^ invSize) == 0xFFFF) { //printf("RATS検出: Addr:%06X AllocSize:%04X\n",addr+0x0200,size+1); return (int)size+1; } } } return -1; }
EjsVar *ejsAllocPooledVar(Ejs *ejs, int id) { EjsPool *pool; EjsVar *vp; MprBlk *bp, *gp; if (id < ejs->gc.numPools) { pool = ejs->gc.pools[id]; if ((bp = mprGetFirstChild(pool)) != NULL) { /* * Transfer from the pool to the current generation. Inline for speed. */ gp = MPR_GET_BLK(ejs->currentGeneration); if (bp->prev) { bp->prev->next = bp->next; } else { bp->parent->children = bp->next; } if (bp->next) { bp->next->prev = bp->prev; } bp->parent = gp; if (gp->children) { gp->children->prev = bp; } bp->next = gp->children; gp->children = bp; bp->prev = 0; vp = MPR_GET_PTR(bp); memset(vp, 0, pool->type->instanceSize); vp->type = pool->type; vp->master = (ejs->master == 0); #if BLD_DEBUG vp->seq = nextSequence++; checkAddr((EjsVar*) vp); pool->reuse++; pool->count--; mprAssert(pool->count >= 0); ejsAddToGcStats(ejs, vp, id); #endif if (++ejs->workDone >= ejs->workQuota) { ejs->gcRequired = 1; ejs->attention = 1; } return vp; } } return 0; }
int Rom::findData(void* data,int size,int startAddr,int endAddr) { if(!checkAddr(startAddr,size)) return -1; int count = 0; uchar* dataPtr = (uchar*)data; for(int addr=startAddr;addr<endAddr;addr++) { if(romData[addr] == dataPtr[count]) { if(++count >= size) { return addr - size + 1; } } else { count = 0; } } return -1; }
int Rom::eraseData(int addr,int size,bool alwaysMode) { // romSizeから飛び出さないか確認 if(!checkAddr(addr,size)) return 0; // 強制削除モードでない場合、範囲内にRATSタグが存在するか事前に確認 if(!alwaysMode) { for(int addr2 = addr;addr2 < addr+size;addr2++) { if(checkRATSdata(addr2)>0) return 0; } } // 領域を削除 while(size>0) { romData[addr++] = freeSpaceNum; size--; } return 1; }
void ejsDestroyGCService(Ejs *ejs) { EjsGC *gc; EjsGen *gen; EjsVar *vp; MprBlk *bp, *next; int generation; gc = &ejs->gc; for (generation = EJS_GEN_ETERNAL; generation >= 0; generation--) { gen = gc->generations[generation]; for (bp = mprGetFirstChild(gen); bp; bp = next) { next = bp->next; vp = MPR_GET_PTR(bp); checkAddr(vp); if (vp->type->needFinalize) { (vp->type->helpers->destroyVar)(ejs, vp); } } } }
void DCStartd::asyncSwapClaims(const char * claim_id, char const *src_descrip, const char * dest_slot_name, int timeout, classy_counted_ptr<DCMsgCallback> cb) { dprintf(D_FULLDEBUG|D_PROTOCOL,"Swapping claim %s into slot %s\n", src_descrip, dest_slot_name); setCmdStr( "swapClaims" ); ASSERT( checkClaimId() ); ASSERT( checkAddr() ); classy_counted_ptr<SwapClaimsMsg> msg = new SwapClaimsMsg( claim_id, src_descrip, dest_slot_name ); ASSERT( msg.get() ); msg->setCallback(cb); msg->setSuccessDebugLevel(D_ALWAYS|D_PROTOCOL); // if this claim is associated with a security session ClaimIdParser cid(claim_id); msg->setSecSessionId(cid.secSessionId()); msg->setTimeout(timeout); //msg->setDeadlineTimeout(deadline_timeout); sendMsg(msg.get()); }
void DCStartd::asyncRequestOpportunisticClaim( ClassAd const *req_ad, char const *description, char const *scheduler_addr, int alive_interval, int timeout, int deadline_timeout, classy_counted_ptr<DCMsgCallback> cb ) { dprintf(D_FULLDEBUG|D_PROTOCOL,"Requesting claim %s\n",description); setCmdStr( "requestClaim" ); ASSERT( checkClaimId() ); ASSERT( checkAddr() ); classy_counted_ptr<ClaimStartdMsg> msg = new ClaimStartdMsg( claim_id, extra_ids, req_ad, description, scheduler_addr, alive_interval ); ASSERT( msg.get() ); msg->setCallback(cb); msg->setSuccessDebugLevel(D_ALWAYS|D_PROTOCOL); // if this claim is associated with a security session ClaimIdParser cid(claim_id); msg->setSecSessionId(cid.secSessionId()); msg->setTimeout(timeout); msg->setDeadlineTimeout(deadline_timeout); sendMsg(msg.get()); }
bool DCStartd::deactivateClaim( bool graceful, bool *claim_is_closing ) { dprintf( D_FULLDEBUG, "Entering DCStartd::deactivateClaim(%s)\n", graceful ? "graceful" : "forceful" ); if( claim_is_closing ) { *claim_is_closing = false; } setCmdStr( "deactivateClaim" ); if( ! checkClaimId() ) { return false; } if( ! checkAddr() ) { return false; } // if this claim is associated with a security session ClaimIdParser cidp(claim_id); char const *sec_session = cidp.secSessionId(); if (IsDebugLevel(D_COMMAND)) { int cmd = graceful ? DEACTIVATE_CLAIM : DEACTIVATE_CLAIM_FORCIBLY; dprintf (D_COMMAND, "DCStartd::deactivateClaim(%s,...) making connection to %s\n", getCommandStringSafe(cmd), _addr ? _addr : "NULL"); } bool result; ReliSock reli_sock; reli_sock.timeout(20); // years of research... :) if( ! reli_sock.connect(_addr) ) { std::string err = "DCStartd::deactivateClaim: "; err += "Failed to connect to startd ("; err += _addr ? _addr : "NULL"; err += ')'; newError( CA_CONNECT_FAILED, err.c_str() ); return false; } int cmd; if( graceful ) { cmd = DEACTIVATE_CLAIM; } else { cmd = DEACTIVATE_CLAIM_FORCIBLY; } result = startCommand( cmd, (Sock*)&reli_sock, 20, NULL, NULL, false, sec_session ); if( ! result ) { std::string err = "DCStartd::deactivateClaim: "; err += "Failed to send command "; if( graceful ) { err += "DEACTIVATE_CLAIM"; } else { err += "DEACTIVATE_CLAIM_FORCIBLY"; } err += " to the startd"; newError( CA_COMMUNICATION_ERROR, err.c_str() ); return false; } // Now, send the ClaimId if( ! reli_sock.put_secret(claim_id) ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::deactivateClaim: Failed to send ClaimId to the startd" ); return false; } if( ! reli_sock.end_of_message() ) { newError( CA_COMMUNICATION_ERROR, "DCStartd::deactivateClaim: Failed to send EOM to the startd" ); return false; } reli_sock.decode(); ClassAd response_ad; if( !getClassAd(&reli_sock, response_ad) || !reli_sock.end_of_message() ) { dprintf( D_FULLDEBUG, "DCStartd::deactivateClaim: failed to read response ad.\n"); // The response ad is not critical and is expected to be missing // if the startd is from before 7.0.5. } else { bool start = true; response_ad.LookupBool(ATTR_START,start); if( claim_is_closing ) { *claim_is_closing = !start; } } // we're done dprintf( D_FULLDEBUG, "DCStartd::deactivateClaim: " "successfully sent command\n" ); return true; }
static void initOpts(int argc, char *argv[]) { int opt, err, i; uint32_t addr; int64_t mask; while ((opt = getopt(argc, argv, "a:b:c:d:e:fgkln:p:s:t:x:vV")) != -1) { switch (opt) { case 'a': i = getNum(optarg, &err); if ((i >= PI_MEM_ALLOC_AUTO) && (i <= PI_MEM_ALLOC_MAILBOX)) memAllocMode = i; else fatal("invalid -a option (%d)", i); break; case 'b': i = getNum(optarg, &err); if ((i >= PI_BUF_MILLIS_MIN) && (i <= PI_BUF_MILLIS_MAX)) bufferSizeMilliseconds = i; else fatal("invalid -b option (%d)", i); break; case 'c': i = getNum(optarg, &err); if ((i >= 0) && (i < PI_CFG_ILLEGAL_VAL)) cfgInternals = i; else fatal("invalid -c option (%x)", i); break; case 'd': i = getNum(optarg, &err); if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_DMA_CHANNEL)) DMAprimaryChannel = i; else fatal("invalid -d option (%d)", i); break; case 'e': i = getNum(optarg, &err); if ((i >= PI_MIN_DMA_CHANNEL) && (i <= PI_MAX_DMA_CHANNEL)) DMAsecondaryChannel = i; else fatal("invalid -e option (%d)", i); break; case 'f': ifFlags |= PI_DISABLE_FIFO_IF; break; case 'g': foreground = 1; break; case 'k': ifFlags |= PI_DISABLE_SOCK_IF; break; case 'l': ifFlags |= PI_LOCALHOST_SOCK_IF; break; case 'n': addr = checkAddr(optarg); if (addr && (numSockNetAddr<MAX_CONNECT_ADDRESSES)) sockNetAddr[numSockNetAddr++] = addr; else fatal("invalid -n option (%s)", optarg); break; case 'p': i = getNum(optarg, &err); if ((i >= PI_MIN_SOCKET_PORT) && (i <= PI_MAX_SOCKET_PORT)) socketPort = i; else fatal("invalid -p option (%d)", i); break; case 's': i = getNum(optarg, &err); switch(i) { case 1: case 2: case 4: case 5: case 8: case 10: clockMicros = i; break; default: fatal("invalid -s option (%d)", i); break; } break; case 't': i = getNum(optarg, &err); if ((i >= PI_CLOCK_PWM) && (i <= PI_CLOCK_PCM)) clockPeripheral = i; else fatal("invalid -t option (%d)", i); break; case 'v': case 'V': printf("%d\n", PIGPIO_VERSION); exit(EXIT_SUCCESS); break; case 'x': mask = getNum(optarg, &err); if (!err) { updateMask = mask; updateMaskSet = 1; } else fatal("invalid -x option (%s)", optarg); break; default: /* '?' */ usage(); exit(EXIT_FAILURE); } } }
/* * Free a variable. This is should only ever be called by the destroyVar helpers to free a object or recycle the * object to a type specific free pool. */ void ejsFreeVar(Ejs *ejs, EjsVar *vp, int id) { EjsType *type; EjsPool *pool; EjsGC *gc; MprBlk *bp, *pp; mprAssert(vp); checkAddr(vp); gc = &ejs->gc; type = vp->type; if (id < 0) { id = type->id; } pool = gc->pools[id]; if (!vp->noPool && !type->dontPool && 0 <= id && id < gc->numPools && pool->count < EJS_MAX_TYPE_POOL) { /* * Transfer from the current generation back to the pool. Inline for speed. */ pool->type = vp->type; pp = MPR_GET_BLK(pool); bp = MPR_GET_BLK(vp); if (bp->prev) { bp->prev->next = bp->next; } else { bp->parent->children = bp->next; } if (bp->next) { bp->next->prev = bp->prev; } if (bp->children) { mprFreeChildren(vp); } /* * Add to the pool */ bp->parent = pp; if (pp->children) { pp->children->prev = bp; } bp->next = pp->children; pp->children = bp; bp->prev = 0; #if BLD_DEBUG vp->type = (void*) -1; pool->allocated--; mprAssert(pool->allocated >= 0); pool->count++; if (pool->count > pool->peakCount) { pool->peakCount = pool->count; } #endif } else { #if BLD_DEBUG vp->type = (void*) -1; if (0 <= id && id < gc->numPools) { pool = gc->pools[id]; pool->allocated--; mprAssert(pool->allocated >= 0); } #endif mprFree(vp); } }