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; }
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; }
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; }
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); }
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; }
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; }
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; }
/** * 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; }
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); } }
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; }