Beispiel #1
0
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;
}
Beispiel #2
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);
}
Beispiel #3
0
 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;
 }
Beispiel #4
0
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;
	}
}
Beispiel #5
0
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;
}
Beispiel #6
0
void PageReleaseBatch::release_all() {
  for (thread::ThreadGroupId i = 0; i < numa_node_count_; ++i) {
    release_chunk(i);
  }
}
Beispiel #7
0
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);
}
Beispiel #8
0
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;
}