static void RecordSpan(void *vh, byte *p) { MHeap *h; MSpan *s; MSpan **all; uint32 cap; h = vh; s = (MSpan*)p; if(h->nspan >= h->nspancap) { cap = 64*1024/sizeof(all[0]); if(cap < h->nspancap*3/2) cap = h->nspancap*3/2; all = (MSpan**)runtime_SysAlloc(cap*sizeof(all[0]), &mstats.other_sys); if(all == nil) runtime_throw("runtime: cannot allocate memory"); if(h->allspans) { runtime_memmove(all, h->allspans, h->nspancap*sizeof(all[0])); // Don't free the old array if it's referenced by sweep. // See the comment in mgc0.c. if(h->allspans != runtime_mheap.sweepspans) runtime_SysFree(h->allspans, h->nspancap*sizeof(all[0]), &mstats.other_sys); } h->allspans = all; h->nspancap = cap; } h->allspans[h->nspan++] = s; }
static void RecordSpan(void *vh, byte *p) { MHeap *h; MSpan *s; MSpan **all; uint32 cap; h = vh; s = (MSpan*)p; if(h->nspan >= h->nspancap) { cap = 64*1024/sizeof(all[0]); if(cap < h->nspancap*3/2) cap = h->nspancap*3/2; all = (MSpan**)runtime_SysAlloc(cap*sizeof(all[0])); if(all == nil) runtime_throw("runtime: cannot allocate memory"); if(h->allspans) { runtime_memmove(all, h->allspans, h->nspancap*sizeof(all[0])); runtime_SysFree(h->allspans, h->nspancap*sizeof(all[0])); } h->allspans = all; h->nspancap = cap; } h->allspans[h->nspan++] = s; }
static void mark(void) { uintptr blsize, nobj; struct root_list *pl; // Figure out how big an object stack we need. // Get a new one if we need more than we have // or we need significantly less than we have. nobj = mstats.heap_objects; if(nobj > (uintptr)(ebl - bl) || nobj < (uintptr)(ebl-bl)/4) { if(bl != nil) runtime_SysFree(bl, (byte*)ebl - (byte*)bl); // While we're allocated a new object stack, // add 20% headroom and also round up to // the nearest page boundary, since mmap // will anyway. nobj = nobj * 12/10; blsize = nobj * sizeof *bl; blsize = (blsize + 4095) & ~4095; nobj = blsize / sizeof *bl; bl = runtime_SysAlloc(blsize); ebl = bl + nobj; } for(pl = roots; pl != nil; pl = pl->next) { struct root* pr = &pl->roots[0]; while(1) { void *decl = pr->decl; if(decl == nil) break; scanblock(decl, pr->size); pr++; } } scanblock((byte*)&m0, sizeof m0); scanblock((byte*)&finq, sizeof finq); runtime_MProf_Mark(scanblock); // mark stacks __go_scanstacks(scanblock); // mark things pointed at by objects with finalizers runtime_walkfintab(markfin, scanblock); }
G* runtime_netpoll(bool block) { fd_set *prfds, *pwfds, *pefds, *ptfds; bool allocatedfds; struct timeval timeout; struct timeval *pt; int max, c, i; G *gp; int32 mode; byte b; struct stat st; retry: runtime_lock(&selectlock); max = allocated; if(max == 0) { runtime_unlock(&selectlock); return nil; } if(inuse) { prfds = runtime_SysAlloc(4 * sizeof fds, &mstats.other_sys); pwfds = prfds + 1; pefds = pwfds + 1; ptfds = pefds + 1; allocatedfds = true; } else { prfds = &grfds; pwfds = &gwfds; pefds = &gefds; ptfds = >fds; inuse = true; allocatedfds = false; } __builtin_memcpy(prfds, &fds, sizeof fds); runtime_unlock(&selectlock); __builtin_memcpy(pwfds, prfds, sizeof fds); FD_CLR(rdwake, pwfds); __builtin_memcpy(pefds, pwfds, sizeof fds); __builtin_memcpy(ptfds, pwfds, sizeof fds); __builtin_memset(&timeout, 0, sizeof timeout); pt = &timeout; if(block) pt = nil; c = select(max, prfds, pwfds, pefds, pt); if(c < 0) { if(errno == EBADF) { // Some file descriptor has been closed. // Check each one, and treat each closed // descriptor as ready for read/write. c = 0; FD_ZERO(prfds); FD_ZERO(pwfds); FD_ZERO(pefds); for(i = 0; i < max; i++) { if(FD_ISSET(i, ptfds) && fstat(i, &st) < 0 && errno == EBADF) { FD_SET(i, prfds); FD_SET(i, pwfds); c += 2; } } } else { if(errno != EINTR) runtime_printf("runtime: select failed with %d\n", errno); goto retry; } } gp = nil; for(i = 0; i < max && c > 0; i++) { mode = 0; if(FD_ISSET(i, prfds)) { mode += 'r'; --c; } if(FD_ISSET(i, pwfds)) { mode += 'w'; --c; } if(FD_ISSET(i, pefds)) { mode = 'r' + 'w'; --c; } if(i == rdwake) { while(read(rdwake, &b, sizeof b) > 0) ; continue; } if(mode) { PollDesc *pd; runtime_lock(&selectlock); pd = data[i]; runtime_unlock(&selectlock); if(pd != nil) runtime_netpollready(&gp, pd, mode); } } if(block && gp == nil) goto retry; if(allocatedfds) { runtime_SysFree(prfds, 4 * sizeof fds, &mstats.other_sys); } else { runtime_lock(&selectlock); inuse = false; runtime_unlock(&selectlock); } return gp; }