#define OVS_PACKED(DECL) __pragma(pack(push, 1)) DECL __pragma(pack(pop))
#endif
-/* For defining a structure whose instances should aligned on an N-byte
- * boundary.
- *
- * e.g. The following:
+/* OVS_ALIGNED_STRUCT may be used to define a structure whose instances should
+ * aligned on an N-byte boundary. This:
* OVS_ALIGNED_STRUCT(64, mystruct) { ... };
* is equivalent to the following except that it specifies 64-byte alignment:
* struct mystruct { ... };
+ *
+ * OVS_ALIGNED_VAR defines a variable aligned on an N-byte boundary. For
+ * example,
+ * OVS_ALIGNED_VAR(64) int x;
+ * defines a "int" variable that is aligned on a 64-byte boundary.
*/
#ifndef _MSC_VER
#define OVS_ALIGNED_STRUCT(N, TAG) struct __attribute__((aligned(N))) TAG
+#define OVS_ALIGNED_VAR(N) __attribute__((aligned(N)))
#else
#define OVS_ALIGNED_STRUCT(N, TAG) __declspec(align(N)) struct TAG
+#define OVS_ALIGNED_VAR(N) __declspec(align(N))
#endif
/* Supplies code to be run at startup time before invoking main().
/*
- * Copyright (c) 2014 Nicira, Inc.
+ * Copyright (c) 2014, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
unsigned int min_n; /* Min elements before shrinking. */
uint32_t mask; /* Number of 'buckets', minus one. */
uint32_t basis; /* Basis for rehashing client's hash values. */
-
- /* Padding to make cmap_impl exactly one cache line long. */
- uint8_t pad[CACHE_LINE_SIZE - sizeof(unsigned int) * 5];
-
- struct cmap_bucket buckets[];
+ uint8_t pad[CACHE_LINE_SIZE - 4 * 5]; /* Pad to end of cache line. */
+ struct cmap_bucket buckets[1];
};
-BUILD_ASSERT_DECL(sizeof(struct cmap_impl) == CACHE_LINE_SIZE);
+BUILD_ASSERT_DECL(sizeof(struct cmap_impl) == CACHE_LINE_SIZE * 2);
+
+/* An empty cmap. */
+OVS_ALIGNED_VAR(CACHE_LINE_SIZE) const struct cmap_impl empty_cmap;
static struct cmap_impl *cmap_rehash(struct cmap *, uint32_t mask);
ovs_assert(is_pow2(mask + 1));
- impl = xzalloc_cacheline(sizeof *impl
- + (mask + 1) * sizeof *impl->buckets);
+ /* There are 'mask + 1' buckets but struct cmap_impl has one bucket built
+ * in, so we only need to add space for the extra 'mask' buckets. */
+ impl = xzalloc_cacheline(sizeof *impl + mask * sizeof *impl->buckets);
impl->n = 0;
impl->max_n = calc_max_n(mask);
impl->min_n = calc_min_n(mask);
void
cmap_init(struct cmap *cmap)
{
- ovsrcu_set(&cmap->impl, cmap_impl_create(0));
+ ovsrcu_set(&cmap->impl, CONST_CAST(struct cmap_impl *, &empty_cmap));
}
/* Destroys 'cmap'.
cmap_destroy(struct cmap *cmap)
{
if (cmap) {
- ovsrcu_postpone(free_cacheline, cmap_get_impl(cmap));
+ struct cmap_impl *impl = cmap_get_impl(cmap);
+ if (impl != &empty_cmap) {
+ ovsrcu_postpone(free_cacheline, impl);
+ }
}
}
new->n = old->n;
ovsrcu_set(&cmap->impl, new);
- ovsrcu_postpone(free_cacheline, old);
+ if (old != &empty_cmap) {
+ ovsrcu_postpone(free_cacheline, old);
+ }
return new;
}
/*
- * Copyright (c) 2014 Nicira, Inc.
+ * Copyright (c) 2014, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
OVSRCU_TYPE(struct cmap_impl *) impl;
};
+/* Initializer for an empty cmap. */
+#define CMAP_INITIALIZER { \
+ .impl = OVSRCU_INITIALIZER((struct cmap_impl *) &empty_cmap) \
+ }
+extern OVS_ALIGNED_VAR(CACHE_LINE_SIZE) const struct cmap_impl empty_cmap;
+
/* Initialization. */
void cmap_init(struct cmap *);
void cmap_destroy(struct cmap *);
/*
- * Copyright (c) 2014, 2015 Nicira, Inc.
+ * Copyright (c) 2014, 2015, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
char br_name[IFNAMSIZ];
};
-static struct cmap table;
+static struct cmap table = CMAP_INITIALIZER;
static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
static uint32_t
void
tnl_neigh_cache_init(void)
{
- cmap_init(&table);
-
unixctl_command_register("tnl/arp/show", "", 0, 0, tnl_neigh_cache_show, NULL);
unixctl_command_register("tnl/arp/set", "BRIDGE IP MAC", 3, 3, tnl_neigh_cache_add, NULL);
unixctl_command_register("tnl/arp/flush", "", 0, 0, tnl_neigh_cache_flush, NULL);
VLOG_DEFINE_THIS_MODULE(ofproto_dpif_rid);
-static struct ovs_mutex mutex;
+static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
-static struct cmap id_map;
-static struct cmap metadata_map;
+static struct cmap id_map = CMAP_INITIALIZER;
+static struct cmap metadata_map = CMAP_INITIALIZER;
-static struct ovs_list expiring OVS_GUARDED_BY(mutex);
-static struct ovs_list expired OVS_GUARDED_BY(mutex);
+static struct ovs_list expiring OVS_GUARDED_BY(mutex)
+ = OVS_LIST_INITIALIZER(&expiring);
+static struct ovs_list expired OVS_GUARDED_BY(mutex)
+ = OVS_LIST_INITIALIZER(&expired);
-static uint32_t next_id OVS_GUARDED_BY(mutex); /* Possible next free id. */
+static uint32_t next_id OVS_GUARDED_BY(mutex) = 1; /* Possible next free id. */
#define RECIRC_POOL_STATIC_IDS 1024
static void recirc_id_node_free(struct recirc_id_node *);
-void
-recirc_init(void)
-{
- static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
-
- if (ovsthread_once_start(&once)) {
- ovs_mutex_init(&mutex);
- ovs_mutex_lock(&mutex);
- next_id = 1; /* 0 is not a valid ID. */
- cmap_init(&id_map);
- cmap_init(&metadata_map);
- ovs_list_init(&expiring);
- ovs_list_init(&expired);
- ovs_mutex_unlock(&mutex);
-
- ovsthread_once_done(&once);
- }
-
-}
-
/* This should be called by the revalidator once at each round (every 500ms or
* more). */
void
struct flow_tnl state_metadata_tunnel;
};
-void recirc_init(void);
-
/* This is only used for bonds and will go away when bonds implementation is
* updated to use this mechanism instead of internal rules. */
uint32_t recirc_alloc_id(struct ofproto_dpif *);
const char *name;
int error;
- recirc_init();
-
backer = shash_find_data(&all_dpif_backers, type);
if (backer) {
backer->refcount++;
/*
- * Copyright (c) 2008, 2009, 2010, 2013, 2014 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2013, 2014, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
struct element elements[N_ELEMS];
struct element copies[N_ELEMS];
int values[N_ELEMS];
- struct cmap cmap;
+ struct cmap cmap = CMAP_INITIALIZER;
size_t i;
- cmap_init(&cmap);
for (i = 0; i < N_ELEMS; i++) {
elements[i].value = i;
cmap_insert(&cmap, &elements[i].node, hash(i));