static int release_chunks(ChunkList *chunks, Chunk *chunk, Opts *options, SpillControl *spillage) { for (;NULL != chunk; chunk = chunk->next) { if (0 != release_chunk(chunks, chunk, options, spillage)) return -1; } return 0; }
void PageReleaseBatch::release(thread::ThreadGroupId numa_node, PagePoolOffset offset) { ASSERT_ND(numa_node < numa_node_count_); if (chunks_[numa_node]->full()) { release_chunk(numa_node); } ASSERT_ND(!chunks_[numa_node]->full()); chunks_[numa_node]->push_back(offset); }
void* pop_chunk_and_item() { release_chunk(start); if (chunks.size()) { pop_chunk(); assert(cur == end); return *--cur; // no need for any bounds checks here since we're guaranteed we're CHUNK_SIZE from the start } return NULL; }
void mc_destroy(struct mcache *cache) { struct mc_chunk *chunk; struct mcache *child; DBGTRACE("%s(%d): cache:%p %s\n", __func__, __LINE__, cache, cache->name); unlink_cache(cache); if (cache->destroy_cb) (*cache->destroy_cb)(cache, cache->destroy_arg); while ((child = TAILQ_FIRST(&cache->childs)) != NULL) mc_destroy(child); while ((chunk = TAILQ_FIRST(&cache->chunks)) != NULL) { struct mc_chunk *next = TAILQ_NEXT(chunk, node); release_chunk(chunk); if (!next) break; } }
static inline struct mc_obj * join_obj(struct mc_obj *obj) { struct mc_obj *prev = TAILQ_PREV(obj, mc_obj_lst, node); if (prev) { struct mc_chunk *chunk = obj->chunk; TAILQ_REMOVE(&chunk->objs, obj, node); prev->size += (obj->size + sizeof(*obj)); DBGTRACE("%s(%d): chunk:%p obj:%p prev:%p size:%lu\n", __func__, __LINE__, chunk, obj, prev, prev->size); if (TAILQ_FIRST(&chunk->objs) == TAILQ_LAST(&chunk->objs, mc_obj_lst)) { release_chunk(chunk); prev = NULL; } } return prev; }
void PageReleaseBatch::release_all() { for (thread::ThreadGroupId i = 0; i < numa_node_count_; ++i) { release_chunk(i); } }
void OsMemory_free_chunk(address chunk_ptr) { ChunkInfo* ci = get_chunk_info(chunk_ptr); jvm_munmap(ci->addr, ci->mmaped_size); release_chunk(chunk_ptr); }
static ssize_t do_write(Output *output, ChunkList *chunks, Opts *options, SpillControl *spillage, int index) { ssize_t bytes = 0; Chunk *curr_chunk = output->curr_chunk; while (curr_chunk->next != NULL || output->offset < curr_chunk->len) { /* While there's something to write ... */ assert(NULL != curr_chunk->data); if (output->offset < curr_chunk->len) { /* Data available in the current Chunk */ ssize_t b; /* Send it */ do { b = write(output->fd, curr_chunk->data + output->offset, curr_chunk->len - output->offset); } while (b < 0 && EINTR == errno); if (b < 0) { /* Error */ if (EAGAIN == errno || EWOULDBLOCK == errno) break; /* Blocking is OK */ if (EPIPE == errno) return -2; /* Got EPIPE, file should be closed */ fprintf(stderr, "Error writing to %s : %s\n", output->name, strerror(errno)); return -1; } if (b == 0) break; /* Wrote nothing, try again later */ /* Update amount read */ output->written += b; output->offset += b; bytes += b; /* Record time and update linked list */ if (!output->is_reg) { output->write_time = get_time(); if (output->write_time < 0) { return -1; } while (NULL != output->next && output->next->written < output->written) { Output *n = output->next; assert(n->prev == output); pipe_list_remove(output, spillage); pipe_list_insert(output, n, spillage); } if (output == spillage->blocking_output) { spillage->blocking_output = spillage->pipe_list_head; } } } assert(output->offset <= curr_chunk->len); /* Check if at end of current Chunk */ if (output->offset == curr_chunk->len) { /* Stop sending if no more Chunks yet */ if (NULL == curr_chunk->next) break; /* Otherwise, move on to the next Chunk */ output->curr_chunk = curr_chunk->next; output->offset = 0; --curr_chunk->nwriters; if (0 != release_chunk(chunks, curr_chunk, options, spillage)) { return -1; } curr_chunk = output->curr_chunk; curr_chunk->nwriters++; if (NULL == curr_chunk->data) { /* Need to re-read spilled data */ if (0 != reread_data(curr_chunk, spillage)) return -1; } } } if (verbosity > 2 && bytes > 0) { fprintf(stderr, "%.3f Wrote %zd bytes to output #%d (%s); %lld (%sB) so far.\n", get_time(), bytes, index, output->name, (long long) output->written, human_size(output->written)); } return bytes; }