static uword allocate_per_cpu_mheap (uword cpu) { clib_smp_main_t * m = &clib_smp_main; void * heap; uword vm_size, stack_size, mheap_flags; ASSERT (os_get_cpu_number () == cpu); vm_size = (uword) 1 << m->log2_n_per_cpu_vm_bytes; stack_size = (uword) 1 << m->log2_n_per_cpu_stack_bytes; mheap_flags = MHEAP_FLAG_SMALL_OBJECT_CACHE; /* Heap extends up to start of stack. */ heap = mheap_alloc_with_flags (clib_smp_vm_base_for_cpu (m, cpu), vm_size - stack_size, mheap_flags); clib_mem_set_heap (heap); if (cpu == 0) { /* Now that we have a heap, allocate main structure on cpu 0. */ vec_resize (m->per_cpu_mains, m->n_cpus); /* Allocate shared global heap (thread safe). */ m->global_heap = mheap_alloc_with_flags (clib_smp_vm_base_for_cpu (m, cpu + m->n_cpus), vm_size, mheap_flags | MHEAP_FLAG_THREAD_SAFE); } m->per_cpu_mains[cpu].heap = heap; return 0; }
int main (int argc, char *argv[]) { word i, n = atoi (argv[1]); word run_foo = argc > 2; bar_t b = { limit:10 }; if (run_foo) { f64 time_limit; time_limit = atof (argv[2]); vec_resize (foos, n); for (i = 0; i < n; i++) { foos[i].time_requested = time_limit * random_f64 (); foos[i].time_called = 1e100; } foo_base_time = unix_time_now (); for (i = 0; i < n; i++) timer_call (foo, i, foos[i].time_requested); } else timer_call (bar, (any) & b, random_f64 ()); while (vec_len (timers) > 0) os_sched_yield (); if (vec_len (foos) > 0) { f64 min = 1e100, max = -min; f64 ave = 0, rms = 0; for (i = 0; i < n; i++) { f64 dt = foos[i].time_requested - foos[i].time_called; if (dt < min) min = dt; if (dt > max) max = dt; ave += dt; rms += dt * dt; } ave /= n; rms = sqrt (rms / n - ave * ave); fformat (stdout, "error min %g max %g ave %g +- %g\n", min, max, ave, rms); } fformat (stdout, "%d function calls, ave. timer delay %g secs\n", ave_delay_count, ave_delay / ave_delay_count); return 0; }
static clib_error_t * flowprobe_create_state_tables (u32 active_timer) { flowprobe_main_t *fm = &flowprobe_main; vlib_thread_main_t *tm = &vlib_thread_main; vlib_main_t *vm = vlib_get_main (); clib_error_t *error = 0; u32 num_threads; int i; /* Decide how many worker threads we have */ num_threads = 1 /* main thread */ + tm->n_threads; /* Hash table per worker */ fm->ht_log2len = FLOWPROBE_LOG2_HASHSIZE; /* Init per worker flow state and timer wheels */ if (active_timer) { vec_validate (fm->timers_per_worker, num_threads - 1); vec_validate (fm->expired_passive_per_worker, num_threads - 1); vec_validate (fm->hash_per_worker, num_threads - 1); vec_validate (fm->pool_per_worker, num_threads - 1); for (i = 0; i < num_threads; i++) { int j; pool_alloc (fm->pool_per_worker[i], 1 << fm->ht_log2len); vec_resize (fm->hash_per_worker[i], 1 << fm->ht_log2len); for (j = 0; j < (1 << fm->ht_log2len); j++) fm->hash_per_worker[i][j] = ~0; fm->timers_per_worker[i] = clib_mem_alloc (sizeof (TWT (tw_timer_wheel))); tw_timer_wheel_init_2t_1w_2048sl (fm->timers_per_worker[i], flowprobe_expired_timer_callback, 1.0, 1024); } fm->disabled = true; } else { f64 now = vlib_time_now (vm); vec_validate (fm->stateless_entry, num_threads - 1); for (i = 0; i < num_threads; i++) fm->stateless_entry[i].last_exported = now; fm->disabled = false; } fm->initialized = true; return error; }
VEC *LUsolve(const MAT *LU, PERM *pivot, const VEC *b, VEC *x) { if ( ! LU || ! b || ! pivot ) error(E_NULL,"LUsolve"); if ( LU->m != LU->n || LU->n != b->dim ) error(E_SIZES,"LUsolve"); if( x->max_dim < b->dim ) x = v_resize( x, b->dim ); else x = vec_resize( x, b->dim ); px_vec(pivot,b,x); /* x := P.b */ Lsolve(LU,x,x,1.0); /* implicit diagonal = 1 */ Usolve(LU,x,x,0.0); /* explicit diagonal */ return (x); }
static clib_error_t * catchup_socket_read_ready (unix_file_t * uf, int is_server) { unix_main_t * um = &unix_main; mc_socket_main_t *msm = (mc_socket_main_t *)uf->private_data; mc_main_t *mcm = &msm->mc_main; mc_socket_catchup_t * c = find_catchup_from_file_descriptor (msm, uf->file_descriptor); word l, n, is_eof; l = vec_len (c->input_vector); vec_resize (c->input_vector, 4096); n = read (uf->file_descriptor, c->input_vector + l, vec_len (c->input_vector) - l); is_eof = n == 0; if (n < 0) { if (errno == EAGAIN) n = 0; else { catchup_cleanup (msm, c, um, uf); return clib_error_return_unix (0, "read"); } } _vec_len (c->input_vector) = l + n; if (is_eof && vec_len (c->input_vector) > 0) { if (is_server) { mc_msg_catchup_request_handler (mcm, (void *) c->input_vector, c - msm->catchups); _vec_len (c->input_vector) = 0; } else { mc_msg_catchup_reply_handler (mcm, (void *) c->input_vector, c - msm->catchups); c->input_vector = 0; /* reply handler is responsible for freeing vector */ catchup_cleanup (msm, c, um, uf); } } return 0 /* no error */; }
clib_error_t * clib_file_contents (char *file, u8 ** result) { uword n_bytes; clib_error_t *error = 0; u8 *v; if ((error = clib_file_n_bytes (file, &n_bytes))) return error; v = 0; vec_resize (v, n_bytes); error = clib_file_read_contents (file, v, n_bytes); if (error) vec_free (v); else *result = v; return error; }
static uword startup_config_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) { unix_main_t *um = &unix_main; u8 *buf = 0; uword l, n = 1; vlib_process_suspend (vm, 2.0); while (um->unix_config_complete == 0) vlib_process_suspend (vm, 0.1); if (um->startup_config_filename) { unformat_input_t sub_input; int fd; struct stat s; char *fn = (char *) um->startup_config_filename; fd = open (fn, O_RDONLY); if (fd < 0) { clib_warning ("failed to open `%s'", fn); return 0; } if (fstat (fd, &s) < 0) { clib_warning ("failed to stat `%s'", fn); bail: close (fd); return 0; } if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode))) { clib_warning ("not a regular file: `%s'", fn); goto bail; } while (n > 0) { l = vec_len (buf); vec_resize (buf, 4096); n = read (fd, buf + l, 4096); if (n > 0) { _vec_len (buf) = l + n; if (n < 4096) break; } else break; } if (um->log_fd && vec_len (buf)) { u8 *lv = 0; lv = format (lv, "%U: ***** Startup Config *****\n%v", format_timeval, 0 /* current bat-time */ , 0 /* current bat-format */ , buf); { int rv __attribute__ ((unused)) = write (um->log_fd, lv, vec_len (lv)); } vec_reset_length (lv); lv = format (lv, "%U: ***** End Startup Config *****\n", format_timeval, 0 /* current bat-time */ , 0 /* current bat-format */ ); { int rv __attribute__ ((unused)) = write (um->log_fd, lv, vec_len (lv)); } vec_free (lv); } if (vec_len (buf)) { unformat_init_vector (&sub_input, buf); vlib_cli_input (vm, &sub_input, 0, 0); /* frees buf for us */ unformat_free (&sub_input); } close (fd); } return 0; }
clib_error_t * ip_main_init (vlib_main_t * vm) { ip_main_t * im = &ip_main; clib_error_t * error = 0; memset (im, 0, sizeof (im[0])); { ip_protocol_info_t * pi; u32 i; #define ip_protocol(n,s) \ do { \ vec_add2 (im->protocol_infos, pi, 1); \ pi->protocol = n; \ pi->name = (u8 *) #s; \ } while (0); #include "protocols.def" #undef ip_protocol im->protocol_info_by_name = hash_create_string (0, sizeof (uword)); for (i = 0; i < vec_len (im->protocol_infos); i++) { pi = im->protocol_infos + i; hash_set_mem (im->protocol_info_by_name, pi->name, i); hash_set (im->protocol_info_by_protocol, pi->protocol, i); } } { tcp_udp_port_info_t * pi; u32 i; static char * port_names[] = { #define ip_port(s,n) #s, #include "ports.def" #undef ip_port }; static u16 ports[] = { #define ip_port(s,n) n, #include "ports.def" #undef ip_port }; vec_resize (im->port_infos, ARRAY_LEN (port_names)); im->port_info_by_name = hash_create_string (0, sizeof (uword)); for (i = 0; i < vec_len (im->port_infos); i++) { pi = im->port_infos + i; pi->port = clib_host_to_net_u16 (ports[i]); pi->name = (u8 *) port_names[i]; hash_set_mem (im->port_info_by_name, pi->name, i); hash_set (im->port_info_by_port, pi->port, i); } } if ((error = vlib_call_init_function (vm, vnet_main_init))) return error; if ((error = vlib_call_init_function (vm, ip4_init))) return error; if ((error = vlib_call_init_function (vm, ip6_init))) return error; if ((error = vlib_call_init_function (vm, icmp4_init))) return error; if ((error = vlib_call_init_function (vm, icmp6_init))) return error; if ((error = vlib_call_init_function (vm, ip6_hop_by_hop_init))) return error; if ((error = vlib_call_init_function (vm, udp_local_init))) return error; if ((error = vlib_call_init_function (vm, udp_init))) return error; if ((error = vlib_call_init_function (vm, ip_classify_init))) return error; if ((error = vlib_call_init_function (vm, input_acl_init))) return error; return error; }
int main (int argc, char * argv[]) { word i, j, k, n, seed, check_mask; u32 * h = 0; uword * objects = 0; uword * handles = 0; uword objects_used; uword align, fixed_size; n = 10; seed = getpid (); check_mask = 0; fixed_size = 0; if (argc > 1) { n = atoi (argv[1]); verbose = 1; } if (argc > 2) { word i = atoi (argv[2]); if (i) seed = i; } if (argc > 3) check_mask = atoi (argv[3]); align = 0; if (argc > 4) align = 1 << atoi (argv[4]); if_verbose ("testing %wd iterations seed %wd\n", n, seed); srandom (seed); if (verbose) fformat (stderr, "%U\n", format_clib_mem_usage, /* verbose */ 0); vec_resize (objects, 1000); memset (objects, ~0, vec_bytes (objects)); vec_resize (handles, vec_len (objects)); objects_used = 0; if (fixed_size) { uword max_len = 1024 * 1024; void * memory = clib_mem_alloc (max_len * sizeof (h[0])); h = heap_create_from_memory (memory, max_len, sizeof (h[0])); } for (i = 0; i < n; i++) { while (1) { j = random () % vec_len (objects); if (objects[j] != ~0 || i + objects_used < n) break; } if (objects[j] != ~0) { heap_dealloc (h, handles[j]); objects_used--; objects[j] = ~0; } else { u32 * data; uword size; size = 1 + (random () % 100); objects[j] = heap_alloc_aligned (h, size, align, handles[j]); objects_used++; if (align) ASSERT (0 == (objects[j] & (align - 1))); ASSERT (objects[j] < vec_len (h)); ASSERT (size <= heap_len (h, handles[j])); /* Set newly allocated object with test data. */ if (check_mask & 2) { data = h + objects[j]; for (k = 0; k < size; k++) data[k] = objects[j] + k; } } if (check_mask & 1) heap_validate (h); if (check_mask & 4) { /* Duplicate heap at each iteration. */ u32 * h1 = heap_dup (h); heap_free (h); h = h1; } /* 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]; for (k = 0; k < heap_len (h, handles[j]); k++) ASSERT(data[k] == objects[j] + k); } } } if (verbose) fformat (stderr, "%U\n", format_heap, h, 1); { u32 * h1 = heap_dup (h); if (verbose) fformat (stderr, "%U\n", format_heap, h1, 1); heap_free (h1); } heap_free (h); if (verbose) fformat (stderr, "%U\n", format_heap, h, 1); ASSERT (objects_used == 0); vec_free (objects); vec_free (handles); if (fixed_size) vec_free_h (h, sizeof (heap_header_t)); if (verbose) fformat (stderr, "%U\n", format_clib_mem_usage, /* verbose */ 0); return 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; }
static int stack_resize(Stack *p, int newcap) { return vec_resize(p,newcap); }