示例#1
0
文件: gengc.c 项目: mflatt/gc-demo
void collect_garbage()
{
  if (!chunks) return;
  
  /* minor collection: */
  mark_and_sweep_from_roots();

  /* The minor collection above relies on having no references from
     old object to new objects; this is not a general-purpose GC. If
     such references were allowed, we'd have to add them as roots. */
  
  /* move non-empty chunks to old generation: */
  if (chunks) {
    struct gc_chunk *prev_c = NULL, *next;

    for (struct gc_chunk *c = chunks; c; c = next) {
      next = c->next;
      if (c->num_marked_nodes == 0) {
        /* This chunk is empty, so free it */
        raw_free(c->mem, NODES_PER_CHUNK * sizeof(struct gc_node));
        raw_free(c, sizeof(struct gc_chunk));
        if (!prev_c)
          chunks = next;
      } else {
        /* Keep this chunk, now as an old-generation chunk */
        num_gen1_chunks++;
        if (prev_c)
          prev_c->next = c;
        prev_c = c;
      }
      c = next;
    }

    if (prev_c) {
      prev_c->next = gen1_chunks;
      gen1_chunks = chunks;
    }

    chunks = NULL;
    free_list = NULL;
  }

  if (num_gen1_chunks >= (last_major_gen1_chunks * 2)) {
    /* perform major collection by moving all old-generation
       chunks back to the "new" generation, and GC again */
    // printf("Major GC\n");
    last_major_gen1_chunks = num_gen1_chunks;
    chunks = gen1_chunks;
    gen1_chunks = NULL;
    num_gen1_chunks = 0;
    collect_garbage();
  }
}
示例#2
0
/** Log a message <b>msg</b> at <b>severity</b> in <b>domain</b>, and follow
 * that with a backtrace log. */
void
log_backtrace(int severity, int domain, const char *msg)
{
  size_t depth;
  char **symbols;
  size_t i;

  tor_mutex_acquire(&cb_buf_mutex);

  depth = backtrace(cb_buf, MAX_DEPTH);
  symbols = backtrace_symbols(cb_buf, (int)depth);

  tor_log(severity, domain, "%s. Stack trace:", msg);
  if (!symbols) {
    /* LCOV_EXCL_START -- we can't provoke this. */
    tor_log(severity, domain, "    Unable to generate backtrace.");
    goto done;
    /* LCOV_EXCL_STOP */
  }
  for (i=0; i < depth; ++i) {
    tor_log(severity, domain, "    %s", symbols[i]);
  }
  raw_free(symbols);

 done:
  tor_mutex_release(&cb_buf_mutex);
}
示例#3
0
RAW *ben_enc(BEN * node)
{
	RAW *raw = raw_init();

	/* Calculate size of ben data */
	raw->size = ben_enc_size(node);
	if (raw->size <= 0) {
		raw_free(raw);
		return NULL;
	}

	/* Encode ben object */
	raw->code = (UCHAR *) myalloc(raw->size * sizeof(UCHAR));
	raw->p = ben_enc_rec(node, raw->code);
	if (raw->p == NULL || (LONG) (raw->p - raw->code) != raw->size) {
		raw_free(raw);
		return NULL;
	}

	return raw;
}
示例#4
0
void FvDebugMsgHelper::MessageBackTrace()
{
	void ** traceBuffer = new void*[MAX_DEPTH];
	FvUInt32 depth = backtrace( traceBuffer, MAX_DEPTH );
	char ** traceStringBuffer = backtrace_symbols( traceBuffer, depth );
	for (FvUInt32 i = 0; i < depth; i++)
	{
		this->message( "Stack: #%d %s\n", i, traceStringBuffer[i] );
	}
#ifdef ENABLE_MEMTRACKER
	raw_free( traceStringBuffer );
#else
	free( traceStringBuffer );
#endif
	delete[] traceBuffer;
}
示例#5
0
/** Install signal handlers as needed so that when we crash, we produce a
 * useful stack trace. Return 0 on success, -1 on failure. */
static int
install_bt_handler(void)
{
  int trap_signals[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS,
                         SIGIO, -1 };
  int i, rv=0;

  struct sigaction sa;

  tor_mutex_init(&cb_buf_mutex);

  memset(&sa, 0, sizeof(sa));
  sa.sa_sigaction = crash_handler;
  sa.sa_flags = SA_SIGINFO;
  sigfillset(&sa.sa_mask);

  for (i = 0; trap_signals[i] >= 0; ++i) {
    if (sigaction(trap_signals[i], &sa, NULL) == -1) {
      /* LCOV_EXCL_START */
      log_warn(LD_BUG, "Sigaction failed: %s", strerror(errno));
      rv = -1;
      /* LCOV_EXCL_STOP */
    }
  }

  {
    /* Now, generate (but do not log) a backtrace.  This ensures that
     * libc has pre-loaded the symbols we need to dump things, so that later
     * reads won't be denied by the sandbox code */
    char **symbols;
    size_t depth = backtrace(cb_buf, MAX_DEPTH);
    symbols = backtrace_symbols(cb_buf, (int) depth);
    if (symbols)
      raw_free(symbols);
  }

  return rv;
}
示例#6
0
void test_page(void * pParam)
{
	void *test1;
	void *test2;

	PAGETBL *pg;
	
	int count = 0;
	raw_page_init(test_page_mem, test_page_mem + 1024*1024);

	pg = system_page_table_get();

	vc_port_printf("111 max page is %d, free page is %d, top page addr is %p\n", 
	pg->maxpage, pg->freepage, pg->top_page);
	
	raw_malloc_init();

	test1 = raw_malloc(188888);
	

	test2 = raw_malloc(18888);

	pg = system_page_table_get();

	vc_port_printf("222 max page is %d, free page is %d, top page addr is %p\n", 
	pg->maxpage, pg->freepage, pg->top_page);
	
	raw_free(test2);
	
	pg = system_page_table_get();

	vc_port_printf("333 max page is %d, free page is %d, top page addr is %p\n", 
	pg->maxpage, pg->freepage, pg->top_page);

	raw_free(test1);


	pg = system_page_table_get();

	vc_port_printf("4444 max page is %d, free page is %d, top page addr is %p\n", 
	pg->maxpage, pg->freepage, pg->top_page);

	
	while (1) {
	    test1 = raw_page_allocate(25);

		if (test1 == 0) {

			vc_port_printf("RAW_NO_MEMORY\n");
			RAW_ASSERT(0);

		}
		
		test2 = raw_page_allocate(25);
		
		if (test2 == 0) {

			vc_port_printf("RAW_NO_MEMORY\n");
			RAW_ASSERT(0);

		}

		raw_page_free(test2);

		vc_port_printf("page success is %d\n", count++);

	}
	
	

}
示例#7
0
文件: bwauth.c 项目: jfrazelle/tor
/**
 * Read the measured bandwidth list <b>from_file</b>:
 * - store all the headers in <b>bw_file_headers</b>,
 * - apply bandwidth lines to the list of vote_routerstatus_t in
 *   <b>routerstatuses</b>,
 * - cache bandwidth lines for dirserv_get_bandwidth_for_router(),
 * - expire old entries in the measured bandwidth cache, and
 * - store the DIGEST_SHA256 of the contents of the file in <b>digest_out</b>.
 *
 * Returns -1 on error, 0 otherwise.
 *
 * If the file can't be read, or is empty:
 * - <b>bw_file_headers</b> is empty,
 * - <b>routerstatuses</b> is not modified,
 * - the measured bandwidth cache is not modified, and
 * - <b>digest_out</b> is the zero-byte digest.
 *
 * Otherwise, if there is an error later in the file:
 * - <b>bw_file_headers</b> contains all the headers up to the error,
 * - <b>routerstatuses</b> is updated with all the relay lines up to the error,
 * - the measured bandwidth cache is updated with all the relay lines up to
 *   the error,
 * - if the timestamp is valid and recent, old entries in the  measured
 *   bandwidth cache are expired, and
 * - <b>digest_out</b> is the digest up to the first read error (if any).
 *   The digest is taken over all the readable file contents, even if the
 *   file is outdated or unparseable.
 */
int
dirserv_read_measured_bandwidths(const char *from_file,
                                 smartlist_t *routerstatuses,
                                 smartlist_t *bw_file_headers,
                                 uint8_t *digest_out)
{
  FILE *fp = tor_fopen_cloexec(from_file, "r");
  int applied_lines = 0;
  time_t file_time, now;
  int ok;
   /* This flag will be 1 only when the first successful bw measurement line
   * has been encountered, so that measured_bw_line_parse don't give warnings
   * if there are additional header lines, as introduced in Bandwidth List spec
   * version 1.1.0 */
  int line_is_after_headers = 0;
  int rv = -1;
  char *line = NULL;
  size_t n = 0;
  crypto_digest_t *digest = crypto_digest256_new(DIGEST_SHA256);

  if (fp == NULL) {
    log_warn(LD_CONFIG, "Can't open bandwidth file at configured location: %s",
             from_file);
    goto err;
  }

  if (tor_getline(&line,&n,fp) <= 0) {
    log_warn(LD_DIRSERV, "Empty bandwidth file");
    goto err;
  }
  /* If the line could be gotten, add it to the digest */
  crypto_digest_add_bytes(digest, (const char *) line, strlen(line));

  if (!strlen(line) || line[strlen(line)-1] != '\n') {
    log_warn(LD_DIRSERV, "Long or truncated time in bandwidth file: %s",
             escaped(line));
    /* Continue adding lines to the digest. */
    goto continue_digest;
  }

  line[strlen(line)-1] = '\0';
  file_time = (time_t)tor_parse_ulong(line, 10, 0, ULONG_MAX, &ok, NULL);
  if (!ok) {
    log_warn(LD_DIRSERV, "Non-integer time in bandwidth file: %s",
             escaped(line));
    goto continue_digest;
  }

  now = approx_time();
  if ((now - file_time) > MAX_MEASUREMENT_AGE) {
    log_warn(LD_DIRSERV, "Bandwidth measurement file stale. Age: %u",
             (unsigned)(time(NULL) - file_time));
    goto continue_digest;
  }

  /* If timestamp was correct and bw_file_headers is not NULL,
   * add timestamp to bw_file_headers */
  if (bw_file_headers)
    smartlist_add_asprintf(bw_file_headers, "timestamp=%lu",
                           (unsigned long)file_time);

  if (routerstatuses)
    smartlist_sort(routerstatuses, compare_vote_routerstatus_entries);

  while (!feof(fp)) {
    measured_bw_line_t parsed_line;
    if (tor_getline(&line, &n, fp) >= 0) {
      crypto_digest_add_bytes(digest, (const char *) line, strlen(line));
      if (measured_bw_line_parse(&parsed_line, line,
                                 line_is_after_headers) != -1) {
        /* This condition will be true when the first complete valid bw line
         * has been encountered, which means the end of the header lines. */
        line_is_after_headers = 1;
        /* Also cache the line for dirserv_get_bandwidth_for_router() */
        dirserv_cache_measured_bw(&parsed_line, file_time);
        if (measured_bw_line_apply(&parsed_line, routerstatuses) > 0)
          applied_lines++;
      /* if the terminator is found, it is the end of header lines, set the
       * flag but do not store anything */
      } else if (strcmp(line, BW_FILE_HEADERS_TERMINATOR) == 0) {
        line_is_after_headers = 1;
      /* if the line was not a correct relay line nor the terminator and
       * the end of the header lines has not been detected yet
       * and it is key_value and bw_file_headers did not reach the maximum
       * number of headers,
       * then assume this line is a header and add it to bw_file_headers */
      } else if (bw_file_headers &&
              (line_is_after_headers == 0) &&
              string_is_key_value(LOG_DEBUG, line) &&
              !strchr(line, ' ') &&
              (smartlist_len(bw_file_headers)
               < MAX_BW_FILE_HEADER_COUNT_IN_VOTE)) {
        line[strlen(line)-1] = '\0';
        smartlist_add_strdup(bw_file_headers, line);
      };
    }
  }

  /* Now would be a nice time to clean the cache, too */
  dirserv_expire_measured_bw_cache(now);

  log_info(LD_DIRSERV,
           "Bandwidth measurement file successfully read. "
           "Applied %d measurements.", applied_lines);
  rv = 0;

 continue_digest:
  /* Continue parsing lines to return the digest of the Bandwidth File. */
  while (!feof(fp)) {
    if (tor_getline(&line, &n, fp) >= 0) {
      crypto_digest_add_bytes(digest, (const char *) line, strlen(line));
    }
  }

 err:
  if (line) {
    // we need to raw_free this buffer because we got it from tor_getdelim()
    raw_free(line);
  }
  if (fp)
    fclose(fp);
  if (digest_out)
    crypto_digest_get_digest(digest, (char *) digest_out, DIGEST256_LEN);
  crypto_digest_free(digest);
  return rv;
}