summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/test_fpool.c
blob: e2d67f1690793cbfbdbf590f6c7d937527bfd3be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

#include <vppinfra/pool.h>

/* can be a very large size */
#define NELTS 1024

int
main (int argc, char *argv[])
{
  u32 *junk = 0;
  int i;
  u32 *tp = 0;
  u32 *indices = 0;

  clib_mem_init (0, 3ULL << 30);

  vec_validate (indices, NELTS - 1);
  _vec_len (indices) = 0;

  pool_init_fixed (tp, NELTS);

  for (i = 0; i < NELTS; i++)
    {
      pool_get (tp, junk);
      vec_add1 (indices, junk - tp);
      *junk = i;
    }

  for (i = 0; i < NELTS; i++)
    {
      junk = pool_elt_at_index (tp, indices[i]);
      ASSERT (*junk == i);
    }

  fformat (stdout, "%d pool elts before deletes\n", pool_elts (tp));

  pool_put_index (tp, indices[12]);
  pool_put_index (tp, indices[43]);

  fformat (stdout, "%d pool elts after deletes\n", pool_elts (tp));

  pool_validate (tp);

  pool_free (tp);
  return 0;
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
------------------------------------------------ * Copyright (c) 2018 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------ */ #include <vnet/qos/qos_egress_map.h> #include <vnet/qos/qos_mark.h> /** * Pool from which to allocate table */ qos_egress_map_t *qem_pool; /** * DB to map user table-IDs to internal table indicies. */ uword *qem_db; index_t qos_egress_map_find (qos_egress_map_id_t mid) { uword *p = NULL; p = hash_get (qem_db, mid); if (NULL != p) return p[0]; return (INDEX_INVALID); } qos_egress_map_id_t qos_egress_map_get_id (index_t qemi) { qos_egress_map_id_t qid; index_t qmi; hash_foreach(qid, qmi, qem_db, ({ if (qmi == qemi) return (qid); })); return (~0); } qos_egress_map_t * qos_egress_map_find_i (qos_egress_map_id_t mid) { index_t qemi; qemi = qos_egress_map_find (mid); if (INDEX_INVALID != qemi) { return (pool_elt_at_index (qem_pool, qemi)); } return (NULL); } static qos_egress_map_t * qos_egress_map_find_or_create (qos_egress_map_id_t mid) { qos_egress_map_t *qem; /* * Find the existing or create a new table */ qem = qos_egress_map_find_i (mid); if (NULL == qem) { index_t qemi; pool_get_aligned (qem_pool, qem, CLIB_CACHE_LINE_BYTES); qemi = qem - qem_pool; clib_memset (qem, 0, sizeof (*qem)); hash_set (qem_db, mid, qemi); } return (qem); } void qos_egress_map_update (qos_egress_map_id_t mid, qos_source_t input_source, qos_bits_t * values) { qos_egress_map_t *qem; qem = qos_egress_map_find_or_create (mid); clib_memcpy (qem->qem_output[input_source], values, sizeof (qem->qem_output[input_source])); } void qos_egress_map_delete (qos_egress_map_id_t mid) { qos_egress_map_t *qem; qem = qos_egress_map_find_i (mid); hash_unset (qem_db, mid); if (NULL != qem) { pool_put (qem_pool, qem); } } void qos_egress_map_walk (qos_egress_map_walk_cb_t fn, void *c) { qos_egress_map_id_t qid; index_t qmi; hash_foreach(qid, qmi, qem_db, ({ fn(qid, pool_elt_at_index(qem_pool, qmi), c); })); } static clib_error_t * qos_egress_map_update_cli (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { qos_egress_map_id_t map_id; qos_egress_map_t *qem; u8 add; add = 1; map_id = ~0; qem = NULL; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "delete") || unformat (input, "del")) add = 0; else if (unformat (input, "id %d", &map_id)) qem = qos_egress_map_find_or_create (map_id); else { int qs, qi, qo; if (NULL == qem) return clib_error_return (0, "map-id must be specified"); while (unformat (input, "[%U][%d]=%d", unformat_qos_source, &qs, &qi, &qo)) qem->qem_output[qs][qi] = qo; break; } } if (!add) qos_egress_map_delete (map_id); return (NULL); } /*? * Update a Egress Qos Map table * * @cliexpar * @cliexcmd{qos egress map id 0 [ip][4]=4} ?*/ VLIB_CLI_COMMAND (qos_egress_map_update_command, static) = { .path = "qos egress map", .short_help = "qos egress map id %d [delete] {[SOURCE][INPUT]=OUTPUT}", .function = qos_egress_map_update_cli, .is_mp_safe = 1, }; u8 *format_qos_egress_map (u8 * s, va_list * args) { qos_egress_map_t *qem = va_arg (*args, qos_egress_map_t *); u32 indent = va_arg (*args, u32); int qs; u32 ii; FOR_EACH_QOS_SOURCE (qs) { s = format (s, "%U%U:[", format_white_space, indent, format_qos_source, qs); for (ii = 0; ii < ARRAY_LEN (qem->qem_output[qs]) - 1; ii++) { s = format (s, "%d,", qem->qem_output[qs][ii]); } s = format (s, "%d]\n", qem->qem_output[qs][ii]); } return (s); } static clib_error_t *qos_egress_map_show (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { qos_egress_map_id_t map_id; qos_egress_map_t *qem; clib_error_t *error; map_id = ~0; qem = NULL; error = NULL; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "id %d", &map_id)) ; else { error = unformat_parse_error (input); goto done; } } if (~0 == map_id) { index_t qemi; hash_foreach(map_id, qemi, qem_db, ({ vlib_cli_output (vm, " Map-ID:%d\n%U", map_id, format_qos_egress_map, pool_elt_at_index(qem_pool, qemi), 2); })); } else { qem = qos_egress_map_find_i (map_id); if (NULL == qem) { error = clib_error_return (0, "No Map for ID %d", map_id); } else { vlib_cli_output (vm, " Map-ID:%d\n%U", map_id, format_qos_egress_map, qem, 2); } } done: return (error); } /*? * Show Egress Qos Maps * * @cliexpar * @cliexcmd{show qos egress map} ?*/ VLIB_CLI_COMMAND (qos_egress_map_show_command, static) = { .path = "show qos egress map", .short_help = "show qos egress map id %d", .function = qos_egress_map_show, .is_mp_safe = 1, }; /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */