void benchmark_stress_aligned(CommandLine&) { const size_t heapSize = 100 * MB; const size_t churnSize = .05 * heapSize; const size_t churnCount = 100; srandom(1); // For consistency between runs. size_t limit = 0x00001ffffffffffful; for (size_t size = 0; size < limit; size = std::max(size, sizeof(void*)) * 2) { for (size_t alignment = sizeof(void*); alignment < limit; alignment *= 2) { void* object = mbmemalign(alignment, size); if (reinterpret_cast<uintptr_t>(object) & (alignment - 1)) abort(); mbfree(object, size); } for (size_t alignment = sizeof(void*); alignment < limit; alignment *= 2) { void* object = mbmemalign(alignment, size + 128); if (reinterpret_cast<uintptr_t>(object) & (alignment - 1)) abort(); mbfree(object, size + 128); } } std::vector<Object> objects; SizeStream sizeStream; size_t size = 0; for (size_t remaining = heapSize; remaining; remaining -= std::min(remaining, size)) { size = sizeStream.next(); objects.push_back(allocate(randomAlignment(), size)); } for (size_t i = 0; i < churnCount; ++i) { std::vector<Object> objectsToFree; for (size_t remaining = churnSize; remaining; remaining -= std::min(remaining, size)) { size = sizeStream.next(); Object object = allocate(randomAlignment(), size); size_t index = random() % objects.size(); objectsToFree.push_back(objects[index]); objects[index] = object; } for (auto& object : objectsToFree) deallocate(object); mbscavenge(); } for (auto& object : objects) mbfree(object.pointer, object.size); }
Mbuf CcpDataInput(Bund b, Mbuf comp) { CcpState const ccp = &b->ccp; Mbuf plain; LogDumpBp(LG_FRAME, comp, "[%s] %s: recv comp", Pref(&ccp->fsm), Fsm(&ccp->fsm)); /* Decompress packet */ if ((!ccp->recv) || (!ccp->recv->Decompress)) { Log(LG_ERR, ("[%s] %s: no compression for recv", Pref(&ccp->fsm), Fsm(&ccp->fsm))); mbfree(comp); return(NULL); } plain = (*ccp->recv->Decompress)(b, comp); /* Encrypted ok? */ if (plain == NULL) { Log(LG_CCP, ("[%s] %s: decompression failed", Pref(&ccp->fsm), Fsm(&ccp->fsm))); return(NULL); } LogDumpBp(LG_FRAME, plain, "[%s] %s: recv plain", Pref(&ccp->fsm), Fsm(&ccp->fsm)); return(plain); }
void Interpreter::run() { std::vector<Op> ops(1024); lseek(m_fd, 0, SEEK_SET); m_remaining = m_opCount * sizeof(Op); m_opsCursor = m_opsInBuffer = 0; doOnSameThread(0); for (auto thread : m_threads) thread->stop(); for (auto thread : m_threads) delete thread; // A recording might not free all of its allocations. if (!m_shouldFreeAllObjects) return; for (size_t i = 0; i < m_objects.size(); ++i) { if (!m_objects[i].object) continue; mbfree(m_objects[i].object, m_objects[i].size); m_objects[i] = { 0, 0 }; } }
void deallocate(const Object& object) { for (size_t i = 0; i < object.size / sizeof(long); ++i) { if ((static_cast<long*>(object.pointer))[i] != object.uuid) abort(); } mbfree(object.pointer, object.size); }
void InputFrame(Bund b, Link l, int proto, Mbuf bp) { Mbuf protoRej; u_int16_t nprot; /* Check the link */ if (l == NULL) { /* Only limited link-layer stuff allowed over the MP bundle */ if (PROT_LINK_LAYER(proto)) { InputMPLink(b, proto, bp); return; } } else { /* Check protocol vs. link state */ if (!InputLinkCheck(l, proto)) { mbfree(bp); return; } } /* Dispatch frame to the appropriate protocol engine */ if (InputDispatch(b, l, proto, bp) >= 0) return; /* Unknown protocol, so find a link to send protocol reject on */ if (l == NULL) { int k; for (k = 0; k < NG_PPP_MAX_LINKS && (!b->links[k] || b->links[k]->lcp.phase != PHASE_NETWORK); k++); if (k == NG_PPP_MAX_LINKS) { mbfree(bp); return; } l = b->links[k]; } /* Send a protocol reject on the chosen link */ nprot = htons((u_int16_t) proto); protoRej = mbcopyback(bp, -2, (u_char *) &nprot, 2); FsmOutputMbuf(&l->lcp.fsm, CODE_PROTOREJ, l->lcp.fsm.rejid++, protoRej); }
void * mbrealloc (void *Adresse, u32 Size) { u32 Bloc, Boucle, OldSize, CopySize; void * NewAdresse; if (((Adresse - BaseDynAlloc) % MEMORY_BLOC_SIZE) != 0) return NULL; Bloc = (Adresse - BaseDynAlloc) / MEMORY_BLOC_SIZE; if (BlocAllocate[Bloc].Used == 0) return NULL; for (Boucle = Bloc; BlocAllocate[Boucle].Expand == 1; Boucle++) { if (Boucle >= MaxMemoryBlocs) break; }; OldSize = Boucle - Bloc + 1; // Si pas de changement de taille de bloc, ... if ( Size == OldSize) return Adresse; // Si on reduit le nombre de bloc, ... if ( Size < OldSize) { for (Boucle = (Bloc + Size); Boucle < (Bloc + OldSize) ; Boucle++) { BlocAllocate[Boucle].Used = 0; BlocAllocate[Boucle].Expand = 0; } BlocAllocate[Size-1].Expand = 0; return Adresse; } // Si on augmente le nombre de bloc for (Boucle = (Bloc + OldSize); Boucle < (Bloc + Size) ; Boucle++) { // Si le bloc ne peut etre simplement agrandit, ... if ( BlocAllocate[Boucle].Used == 1 ) { NewAdresse = mballoc (Size); if (NewAdresse == NULL) return NULL; CopySize = (OldSize * MEMORY_BLOC_SIZE) / sizeof(u32); for (Boucle = 0; Boucle < CopySize; Boucle++) { ((u32*) NewAdresse)[Boucle] = ((u32*) Adresse)[Boucle]; }; mbfree (Adresse); return NewAdresse; } } // Le bloc est simplement agrandit for (Boucle = (Bloc + OldSize - 1); Boucle < (Bloc + Size) ; Boucle++) { BlocAllocate[Boucle].Used = 1; BlocAllocate[Boucle].Expand = 1; } BlocAllocate[Size-1].Expand = 0; return Adresse; }
/* * pre-allocate some message buffers at boot time. * if this supply is exhausted, more will be allocated as needed. */ void mbinit(void) { Msgbuf *mb; Rabuf *rb; int i; lock(&msgalloc); unlock(&msgalloc); msgalloc.lmsgbuf = 0; msgalloc.smsgbuf = 0; for(i=0; i<conf.nlgmsg; i++) { mb = malloc(sizeof(Msgbuf)); mb->magic = Mbmagic; mb->xdata = malloc(LARGEBUF+Slop); mb->flags = LARGE; mbfree(mb); cons.nlarge++; } for(i=0; i<conf.nsmmsg; i++) { mb = malloc(sizeof(Msgbuf)); mb->magic = Mbmagic; mb->xdata = malloc(SMALLBUF+Slop); mb->flags = 0; mbfree(mb); cons.nsmall++; } memset(mballocs, 0, sizeof(mballocs)); lock(&rabuflock); unlock(&rabuflock); rabuffree = 0; for(i=0; i<1000; i++) { rb = malloc(sizeof(*rb)); rb->link = rabuffree; rabuffree = rb; } }
/* * main filesystem server loop. * entered by many processes. * they wait for message buffers and * then process them. */ void serve(void *) { int i; Chan *cp; Msgbuf *mb; for (;;) { qlock(&reflock); /* read 9P request from a network input process */ mb = fs_recv(serveq, 0); assert(mb->magic == Mbmagic); /* fs kernel sets chan in /sys/src/fs/ip/il.c:/^getchan */ cp = mb->chan; if (cp == nil) panic("serve: nil mb->chan"); rlock(&cp->reflock); qunlock(&reflock); rlock(&mainlock); if (mb->data == nil) panic("serve: nil mb->data"); /* better sniffing code in /sys/src/cmd/disk/kfs/9p12.c */ if(cp->protocol == nil){ /* do we recognise the protocol in this packet? */ /* better sniffing code: /sys/src/cmd/disk/kfs/9p12.c */ for(i = 0; fsprotocol[i] != nil; i++) if(fsprotocol[i](mb) != 0) { cp->protocol = fsprotocol[i]; break; } if(cp->protocol == nil){ print("no protocol for message\n"); for(i = 0; i < 12; i++) print(" %2.2X", mb->data[i]); print("\n"); } } else /* process the request, generate an answer and reply */ cp->protocol(mb); mbfree(mb); runlock(&mainlock); runlock(&cp->reflock); } }
static void InputMPLink(Bund b, int proto, Mbuf pkt) { struct fsmheader *hdr; int k; switch (proto) { case PROTO_LCP: if (MBLEN(pkt) < sizeof(hdr)) break; hdr = (struct fsmheader *)MBDATA(pkt); switch (hdr->code) { case CODE_CODEREJ: /* these two are OK */ case CODE_PROTOREJ: for (k = 0; k < NG_PPP_MAX_LINKS && !b->links[k]; k++) if (k < NG_PPP_MAX_LINKS) { InputFrame(b, b->links[k], proto, pkt); return; } break; case CODE_ECHOREQ: Log(LG_ECHO, ("[%s] rec'd %s #%d, replying...", b->name, FsmCodeName(hdr->code), hdr->id)); MBDATAU(pkt)[0] = CODE_ECHOREP; NgFuncWritePppFrame(b, NG_PPP_BUNDLE_LINKNUM, PROTO_LCP, pkt); return; case CODE_ECHOREP: Log(LG_ECHO, ("[%s] rec'd %s #%d", b->name, FsmCodeName(hdr->code), hdr->id)); break; default: Log(LG_ERR, ("[%s] rec'd LCP %s #%d on MP link! (ignoring)", b->name, FsmCodeName(hdr->code), hdr->id)); break; } break; default: Log(LG_ERR, ("[%s] rec'd proto %s on MP link! (ignoring)", b->name, ProtoName(proto))); break; } mbfree(pkt); }
Mbuf CcpDataOutput(Bund b, Mbuf plain) { CcpState const ccp = &b->ccp; Mbuf comp; LogDumpBp(LG_FRAME, plain, "[%s] %s: xmit plain", Pref(&ccp->fsm), Fsm(&ccp->fsm)); /* Compress packet */ if ((!ccp->xmit) || (!ccp->xmit->Compress)) { Log(LG_ERR, ("[%s] %s: no encryption for xmit", Pref(&ccp->fsm), Fsm(&ccp->fsm))); mbfree(plain); return(NULL); } comp = (*ccp->xmit->Compress)(b, plain); LogDumpBp(LG_FRAME, comp, "[%s] %s: xmit comp", Pref(&ccp->fsm), Fsm(&ccp->fsm)); return(comp); }
void benchmark_stress(CommandLine&) { const size_t heapSize = 100 * MB; const size_t churnSize = .05 * heapSize; const size_t churnCount = 100; srandom(1); // For consistency between runs. std::vector<Object> objects; SizeStream sizeStream; size_t size = 0; for (size_t remaining = heapSize; remaining; remaining -= std::min(remaining, size)) { size = sizeStream.next(); objects.push_back(allocate(size)); } for (size_t i = 0; i < churnCount; ++i) { std::vector<Object> objectsToFree; for (size_t remaining = churnSize; remaining; remaining -= std::min(remaining, size)) { size = sizeStream.next(); Object object = allocate(size); size_t index = random() % objects.size(); objectsToFree.push_back(objects[index]); objects[index] = object; } for (auto& object : objectsToFree) deallocate(object); mbscavenge(); } for (auto& object : objects) mbfree(object.pointer, object.size); }
void Interpreter::doMallocOp(Op op, ThreadId threadId) { switch (op.opcode) { case op_malloc: { m_objects[op.slot] = { mbmalloc(op.size), op.size }; assert(m_objects[op.slot].object); bzero(m_objects[op.slot].object, op.size); break; } case op_free: { if (!m_objects[op.slot].object) return; mbfree(m_objects[op.slot].object, m_objects[op.slot].size); m_objects[op.slot] = { 0, 0 }; break; } case op_realloc: { if (!m_objects[op.slot].object) return; m_objects[op.slot] = { mbrealloc(m_objects[op.slot].object, m_objects[op.slot].size, op.size), op.size }; break; } case op_align_malloc: { size_t alignment = compute2toPower(op.alignLog2); m_objects[op.slot] = { mbmemalign(alignment, op.size), op.size }; assert(m_objects[op.slot].object); bzero(m_objects[op.slot].object, op.size); break; } default: { fprintf(stderr, "bad opcode: %d\n", op.opcode); abort(); break; } } }
static void CcpNgDataEvent(int type, void *cookie) { Bund b; struct sockaddr_ng naddr; socklen_t nsize; Mbuf bp; int num = 0; char *bundname, *rest; int id; while (1) { /* Protect from bundle shutdown and DoS */ if (num > 100) return; bp = mballoc(4096); /* Read data */ nsize = sizeof(naddr); if ((bp->cnt = recvfrom(gCcpDsock, MBDATA(bp), MBSPACE(bp), MSG_DONTWAIT, (struct sockaddr *)&naddr, &nsize)) < 0) { mbfree(bp); if (errno == EAGAIN) return; Log(LG_BUND|LG_ERR, ("CcpNgDataEvent: socket read: %s", strerror(errno))); return; } num++; /* Debugging */ LogDumpBp(LG_FRAME, bp, "CcpNgDataEvent: rec'd %d bytes frame on %s hook", MBLEN(bp), naddr.sg_data); bundname = ((struct sockaddr_ng *)&naddr)->sg_data; if (bundname[0] != 'c' && bundname[0] != 'd') { Log(LG_ERR, ("CCP: Packet from unknown hook \"%s\"", bundname)); mbfree(bp); continue; } bundname++; id = strtol(bundname, &rest, 10); if (rest[0] != 0 || !gBundles[id] || gBundles[id]->dead) { Log(LG_ERR, ("CCP: Packet from unexisting bundle \"%s\"", bundname)); mbfree(bp); continue; } b = gBundles[id]; /* Packet requiring compression */ if (bundname[0] == 'c') { bp = CcpDataOutput(b, bp); } else { /* Packet requiring decompression */ bp = CcpDataInput(b, bp); } if (bp) NgFuncWriteFrame(gCcpDsock, naddr.sg_data, b->name, bp); } }
void operator delete(void* p, size_t size) { mbfree(p, size); }
static int InputDispatch(Bund b, Link l, int proto, Mbuf bp) { int reject = 0; /* link level protos */ if (l) { switch (proto) { case PROTO_LCP: LcpInput(l, bp); return(0); case PROTO_PAP: case PROTO_CHAP: case PROTO_EAP: AuthInput(l, proto, bp); return(0); case PROTO_MP: if (!Enabled(&l->conf.options, LINK_CONF_MULTILINK)) reject = 1; goto done; } } /* bundle level protos */ if (b) { switch (proto) { case PROTO_IPCP: case PROTO_IP: case PROTO_VJUNCOMP: case PROTO_VJCOMP: if (!Enabled(&b->conf.options, BUND_CONF_IPCP)) reject = 1; else if (proto == PROTO_IPCP) { IpcpInput(b, bp); return(0); } break; case PROTO_IPV6CP: case PROTO_IPV6: if (!Enabled(&b->conf.options, BUND_CONF_IPV6CP)) reject = 1; else if (proto == PROTO_IPV6CP) { Ipv6cpInput(b, bp); return(0); } break; case PROTO_CCP: case PROTO_COMPD: if (!Enabled(&b->conf.options, BUND_CONF_COMPRESSION)) reject = 1; else if (proto == PROTO_CCP) { CcpInput(b, bp); return(0); } break; case PROTO_ECP: case PROTO_CRYPT: if (!Enabled(&b->conf.options, BUND_CONF_ENCRYPTION)) reject = 1; else if (proto == PROTO_ECP) { EcpInput(b, bp); return(0); } break; default: /* completely unknown protocol, reject it */ reject = 1; break; } } done: /* Protocol unexpected, so either reject or drop */ Log(LG_LINK|LG_BUND, ("[%s] rec'd unexpected protocol %s%s", (l ? l->name : b->name), ProtoName(proto), reject ? ", rejecting" : "")); if (!reject) mbfree(bp); return (reject ? -1 : 0); }