Beispiel #1
0
int emit_create(void *data, emit_t *em){
    struct edp_emit  *ee;
    int	    i;

    ASSERT(em != NULL);

    ee = (struct edp_emit *)mheap_alloc(sizeof(*ee));
    if(ee == NULL){
	log_warn("not enough memory!\n");
	return -ENOMEM;
    }
    memset(ee, 0, sizeof(*ee));

    ee->ee_magic = EMIT_INSTANCE_MAGIC;
    spi_spin_init(&ee->ee_lock);
    atomic_reset(&ee->ee_pendings);
//    INIT_LIST_HEAD(&ee->ee_events);
    INIT_LIST_HEAD(&ee->ee_node);

    for(i = 0; i < kEMIT_EVENT_TYPE_MAX; i++){
	ee->ee_handler[i] = emit_default_handler;
    }

    ee->ee_data	= data;
    ee->ee_init	= 1;

    spi_spin_lock(&__emit_data.ed_lock);
    list_add(&ee->ee_node, &__emit_data.ed_emits);
    spi_spin_unlock(&__emit_data.ed_lock);

    *em = ee;

    return 0;
}
Beispiel #2
0
int
test1 (void)
{
  clib_time_t clib_time;
  void *h_mem = clib_mem_alloc (2ULL << 30);
  void *h;
  uword *objects = 0;
  int i;
  f64 before, after;

  clib_time_init (&clib_time);

  vec_validate (objects, 2000000 - 1);

  h = mheap_alloc (h_mem, (uword) (2 << 30));

  before = clib_time_now (&clib_time);

  for (i = 0; i < vec_len (objects); i++)
    {
      h = mheap_get_aligned (h, 24 /* size */ ,
			     64 /* align */ ,
			     16 /* align at offset */ , &objects[i]);
    }

  after = clib_time_now (&clib_time);

  fformat (stdout, "alloc: %u objects in %.2f seconds, %.2f objects/second\n",
	   vec_len (objects), (after - before),
	   ((f64) vec_len (objects)) / (after - before));

  return 0;
}
Beispiel #3
0
runtime·MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large, bool needzero)
{
	MSpan *s;

	// Don't do any operations that lock the heap on the G stack.
	// It might trigger stack growth, and the stack growth code needs
	// to be able to allocate heap.
	if(g == g->m->g0) {
		s = mheap_alloc(h, npage, sizeclass, large);
	} else {
		g->m->ptrarg[0] = h;
		g->m->scalararg[0] = npage;
		g->m->scalararg[1] = sizeclass;
		g->m->scalararg[2] = large;
		runtime·mcall(mheap_alloc_m);
		s = g->m->ptrarg[0];
		g->m->ptrarg[0] = nil;
	}
	if(s != nil) {
		if(needzero && s->needzero)
			runtime·memclr((byte*)(s->start<<PageShift), s->npages<<PageShift);
		s->needzero = 0;
	}
	return s;
}
Beispiel #4
0
static void
mheap_alloc_m(G *gp)
{
	MHeap *h;
	MSpan *s;

	h = g->m->ptrarg[0];
	g->m->ptrarg[0] = nil;
	s = mheap_alloc(h, g->m->scalararg[0], g->m->scalararg[1], g->m->scalararg[2]);
	g->m->ptrarg[0] = s;

	runtime·gogo(&gp->sched);
}
Beispiel #5
0
int edpnet_sock_create(edpnet_sock_t *sock, edpnet_sock_cbs_t *cbs, void *data){
    edpnet_data_t	*ed = &__edpnet_data;
    struct edpnet_sock	*s;
    int			ret;

    if(!ed->ed_init){
	log_warn("ednet not inited!\n");
	return -1;
    }

    s = mheap_alloc(sizeof(*s));
    if(s == NULL){
	log_warn("no enough memory!\n");
	return -ENOMEM;
    }
    memset(s, 0, sizeof(*s));

    ret = emit_create(s, &s->es_emit);
    if(ret !=0 ){
	log_warn("create emit fail:%d\n", ret);
	return ret;
    }
    emit_add_handler(s->es_emit, kEDPNET_SOCK_EPOLLOUT, edpnet_sock_epollout_handler);
    emit_add_handler(s->es_emit, kEDPNET_SOCK_EPOLLIN, edpnet_sock_epollin_handler);
    emit_add_handler(s->es_emit, kEDPNET_SOCK_EPOLLERR, edpnet_sock_epollerr_handler);
    emit_add_handler(s->es_emit, kEDPNET_SOCK_EPOLLHUP, edpnet_sock_epollhup_handler);

    s->es_sock = socket(PF_INET, SOCK_STREAM, 0);
    if(s->es_sock < 0){
	log_warn("init sock failure!\n");
	emit_destroy(s->es_emit);
	mheap_free(s);
	return -1;
    }

    ret = sock_init(s);
    if(ret != 0){
	log_warn("initialize sock failure!\n");
	emit_destroy(s->es_emit);
	mheap_free(s);
	return ret;
    }

    edpnet_sock_set(s, cbs, data);
    *sock = s;

    return 0;
}
Beispiel #6
0
int mcache_create(size_t size, size_t align, int flags, mcache_t *mc){
    struct mem_cache	*m;

    m = mheap_alloc(sizeof(*m));
    if(m == NULL){
	return -ENOMEM;
    }
    memset(m, 0, sizeof(*m));

    m->mc_size	= size;
    m->mc_align	= (sizeof(void*) >= align) ? sizeof(void*) : align;
    m->mc_flags	= flags;

    *mc = m;

    return 0;
}
Beispiel #7
0
int edpnet_serv_create(edpnet_serv_t *serv, edpnet_serv_cbs_t *cbs, void *data){
    struct edpnet_serv	    *s;

    ASSERT((serv != NULL) && (cbs != NULL));

    s = mheap_alloc(sizeof(*s));
    if(s == NULL){
	log_warn("no enough memory for serv!\n");
	return -ENOMEM;
    }
    memset(s, 0, sizeof(*s));

    INIT_LIST_HEAD(&s->es_node);
    INIT_LIST_HEAD(&s->es_socks);
    s->es_cbs = cbs;
    s->es_data = data;

    s->es_sock = socket(PF_INET, SOCK_STREAM, 0);
    if(s->es_sock < 0){
	log_warn("init sock failure!\n");
	mheap_free(s);
	return -1;
    }

    if(set_nonblock(s->es_sock) < 0){
	close(s->es_sock);
	mheap_free(s);
	return -1;
    }

    spi_spin_init(&s->es_lock);

    if(eio_addfd(s->es_sock, serv_worker_cb, s) != 0){
	log_warn("watch serv handle fail!\n");
	spi_spin_fini(&s->es_lock);
	close(s->es_sock);
	mheap_free(s);
	return -1;
    }

    s->es_status = kEDPNET_SERV_STATUS_INIT;

    *serv = s;

    return 0;
}
Beispiel #8
0
/**
 * Initialize segment in a private heap
 */
int
ssvm_master_init_private (ssvm_private_t * ssvm)
{
  ssvm_shared_header_t *sh;
  u32 pagesize = clib_mem_get_page_size ();
  u32 rnd_size = 0;
  u8 *heap;

  rnd_size = clib_max (ssvm->ssvm_size + (pagesize - 1), ssvm->ssvm_size);
  rnd_size &= ~(pagesize - 1);

#if USE_DLMALLOC == 0
  {
    mheap_t *heap_header;

    heap = mheap_alloc (0, rnd_size);
    if (heap == 0)
      {
	clib_unix_warning ("mheap alloc");
	return -1;
      }
    heap_header = mheap_header (heap);
    heap_header->flags |= MHEAP_FLAG_THREAD_SAFE;
  }
#else
  heap = create_mspace (rnd_size, 1 /* locked */ );
#endif

  ssvm->ssvm_size = rnd_size;
  ssvm->i_am_master = 1;
  ssvm->my_pid = getpid ();
  ssvm->requested_va = ~0;

  /* Allocate a [sic] shared memory header, in process memory... */
  sh = clib_mem_alloc_aligned (sizeof (*sh), CLIB_CACHE_LINE_BYTES);
  ssvm->sh = sh;

  clib_memset (sh, 0, sizeof (*sh));
  sh->heap = heap;
  sh->ssvm_va = pointer_to_uword (heap);
  sh->type = SSVM_SEGMENT_PRIVATE;

  return 0;
}
Beispiel #9
0
static void serv_worker_cb(uint32_t events, void *data){
    struct edpnet_serv *s = (struct edpnet_serv *)data;
    struct edpnet_sock *sock;

    ASSERT(s != NULL);

    if(events & EPOLLIN){
	sock = mheap_alloc(sizeof(*sock));
	if(sock == NULL){
	    log_warn("no memory for sock!\n");
	    return ;
	}
	memset(sock, 0, sizeof(*sock));

	sock->es_sock = accept(s->es_sock, NULL, NULL);
	if(sock->es_sock < 0){
	    log_warn("accept client fail!\n");
	    return ;
	}
	
	if(sock_init(sock) < 0){
	    sock_fini(sock);
	    mheap_free(sock);
	}else{
	    s->es_cbs->connected(s, sock, s->es_data);
	}
    }

    if(events & EPOLLOUT){
	ASSERT(0);
    }

    if(events & (EPOLLERR | EPOLLHUP)){
	s->es_cbs->close(s, s->es_data);
    }
}
Beispiel #10
0
int
test_mheap_main (unformat_input_t * input)
{
  int i, j, k, n_iterations;
  void *h, *h_mem;
  uword *objects = 0;
  u32 objects_used, really_verbose, n_objects, max_object_size;
  u32 check_mask, seed, trace, use_vm;
  u32 print_every = 0;
  u32 *data;
  mheap_t *mh;

  /* Validation flags. */
  check_mask = 0;
#define CHECK_VALIDITY 1
#define CHECK_DATA     2
#define CHECK_ALIGN    4
#define TEST1	       8

  n_iterations = 10;
  seed = 0;
  max_object_size = 100;
  n_objects = 1000;
  trace = 0;
  really_verbose = 0;
  use_vm = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (0 == unformat (input, "iter %d", &n_iterations)
	  && 0 == unformat (input, "count %d", &n_objects)
	  && 0 == unformat (input, "size %d", &max_object_size)
	  && 0 == unformat (input, "seed %d", &seed)
	  && 0 == unformat (input, "print %d", &print_every)
	  && 0 == unformat (input, "validdata %|",
			    &check_mask, CHECK_DATA | CHECK_VALIDITY)
	  && 0 == unformat (input, "valid %|",
			    &check_mask, CHECK_VALIDITY)
	  && 0 == unformat (input, "verbose %=", &really_verbose, 1)
	  && 0 == unformat (input, "trace %=", &trace, 1)
	  && 0 == unformat (input, "vm %=", &use_vm, 1)
	  && 0 == unformat (input, "align %|", &check_mask, CHECK_ALIGN)
	  && 0 == unformat (input, "test1 %|", &check_mask, TEST1))
	{
	  clib_warning ("unknown input `%U'", format_unformat_error, input);
	  return 1;
	}
    }

  /* Zero seed means use default. */
  if (!seed)
    seed = random_default_seed ();

  if (check_mask & TEST1)
    {
      return test1 ();
    }

  if_verbose
    ("testing %d iterations, %d %saligned objects, max. size %d, seed %d",
     n_iterations, n_objects, (check_mask & CHECK_ALIGN) ? "randomly " : "un",
     max_object_size, seed);

  vec_resize (objects, n_objects);
  if (vec_bytes (objects) > 0)	/* stupid warning be gone */
    clib_memset (objects, ~0, vec_bytes (objects));
  objects_used = 0;

  /* Allocate initial heap. */
  {
    uword size =
      max_pow2 (2 * n_objects * max_object_size * sizeof (data[0]));

    h_mem = clib_mem_alloc (size);
    if (!h_mem)
      return 0;

    h = mheap_alloc (h_mem, size);
  }

  if (trace)
    mheap_trace (h, trace);

  mh = mheap_header (h);

  if (use_vm)
    mh->flags &= ~MHEAP_FLAG_DISABLE_VM;
  else
    mh->flags |= MHEAP_FLAG_DISABLE_VM;

  if (check_mask & CHECK_VALIDITY)
    mh->flags |= MHEAP_FLAG_VALIDATE;

  for (i = 0; i < n_iterations; i++)
    {
      while (1)
	{
	  j = random_u32 (&seed) % vec_len (objects);
	  if (objects[j] != ~0 || i + objects_used < n_iterations)
	    break;
	}

      if (objects[j] != ~0)
	{
	  mheap_put (h, objects[j]);
	  objects_used--;
	  objects[j] = ~0;
	}
      else
	{
	  uword size, align, align_offset;

	  size = (random_u32 (&seed) % max_object_size) * sizeof (data[0]);
	  align = align_offset = 0;
	  if (check_mask & CHECK_ALIGN)
	    {
	      align = 1 << (random_u32 (&seed) % 10);
	      align_offset = round_pow2 (random_u32 (&seed) & (align - 1),
					 sizeof (u32));
	    }

	  h = mheap_get_aligned (h, size, align, align_offset, &objects[j]);

	  if (align > 0)
	    ASSERT (0 == ((objects[j] + align_offset) & (align - 1)));

	  ASSERT (objects[j] != ~0);
	  objects_used++;

	  /* Set newly allocated object with test data. */
	  if (check_mask & CHECK_DATA)
	    {
	      uword len;

	      data = (void *) h + objects[j];
	      len = mheap_len (h, data);

	      ASSERT (size <= mheap_data_bytes (h, objects[j]));

	      data[0] = len;
	      for (k = 1; k < len; k++)
		data[k] = objects[j] + k;
	    }
	}

      /* Verify that all used objects have correct test data. */
      if (check_mask & 2)
	{
	  for (j = 0; j < vec_len (objects); j++)
	    if (objects[j] != ~0)
	      {
		u32 *data = h + objects[j];
		uword len = data[0];
		for (k = 1; k < len; k++)
		  ASSERT (data[k] == objects[j] + k);
	      }
	}
      if (print_every != 0 && i > 0 && (i % print_every) == 0)
	fformat (stderr, "iteration %d: %U\n", i, format_mheap, h,
		 really_verbose);
    }

  if (verbose)
    fformat (stderr, "%U\n", format_mheap, h, really_verbose);
  mheap_free (h);
  clib_mem_free (h_mem);
  vec_free (objects);

  return 0;
}