Reviewing the ovn-controller code I started to notice a common pattern:
struct smap ext_ids = SMAP_INITIALIZER(&ext_ids);
smap_add(&ext_ids, "ovn-patch-port", network);
ovsrec_port_set_external_ids(port, &ext_ids);
smap_destroy(&ext_ids);
This seemed like a bit too much code for something as simple as
initializing an smap with a single key-value pair. This commit allows the
code to be reduced to just:
const struct smap ids = SMAP_CONST1(&ids, "ovn-patch-port", network);
ovsrec_port_set_external_ids(port, &ids);
This new form also eliminates multiple memory allocation and free
operations, but I doubt that has any real effect on performance;
the primary goal here is code readability.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Russell Bryant <rbryant@redhat.com>
The HMAP_FOR_EACH_()* macros had a usability issue where the iterator
was only NULL at the completion of iteration if the hmap_node was the
first struct member. This change ensures that the iterator is set to
NULL when iteration ends normally without a 'break'.
Signed-off-by: Russell Bryant <rbryant@redhat.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
GNU C++ isn't too happy with ovs-atomic.h. We could fix that (maybe we
should) but the report I received from a C++ user implied to me that it
would be just as useful to just drop the unnecessary #include
"ovs-atomic.h" from hmap.h.
Reported-by: Michael Hu <humichael@vmware.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
Implementation of OBJECT_OFFSETOF() for non-GNUC compilers like MSVC
causes "uninitialized variable" warnings. Since OBJECT_OFFSETOF() is
indirectly used through all the *_FOR_EACH() (through ASSIGN_CONTAINER()
and OBJECT_CONTAINING()) macros, the OVS build
on Windows gets littered with "uninitialized variable" warnings.
This patch attempts to workaround the problem.
Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
Acked-by: Saurabh Shah <ssaurabh@vmware.com>
Acked-by: Ben Pfaff <blp@nicira.com>
The fence made classifier_lookup() slower. Access to a size_t 'n' is
safe without synchonizing, and if racing with writers matters,
additional syncronization primitives are used anyway.
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Reading the hmap count for determining if it is empty or not is thread
safe, so avoid locking when not necessary.
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
The hmap code has for a long time incremented a counter when a hash bucket
grew to have many entries. This can let a developer know that some hash
function is performing poorly, but doesn't give any hint as to which one.
This commit improves the situation by adding rate-limited debug logging
that points out a particular line of code as the source of the poor hash
behavior. It should make issues easier to track down.
Bug #19926.
Signed-off-by: Ben Pfaff <blp@nicira.com>
Lauded-by: Keith Amidon <keith@nicira.com>
Acked-by: Justin Pettit <jpettit@nicira.com>
This commit makes macro function "ASSIGN_CONTAINER()" evaluates
to "(void)0". This is to avoid the 'clang' warning: "expression
result unused", since most of time, the final evaluated value
is not used.
Signed-off-by: Alex Wang <alexw@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
It seems that 'clang' compiler applies strict protection on pointer
dereference. And it causes unexpected execution in macro functions
like "HMAP_FOR_EACH()" and unit test failures. This commit fixes
this issue and pass all unit tests.
Co-authored-by: Ethan Jackson <ethan@nicira.com>
Signed-off-by: Alex Wang <alexw@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Without this change, an initialization such as
const struct hmap map = HMAP_INITIALIZER(&map);
yields a compiler warning "initialization discards qualifiers from pointer
target type".
Signed-off-by: Ben Pfaff <blp@nicira.com>
Casts are sometimes necessary. One common reason that they are necessary
is for discarding a "const" qualifier. However, this can impede
maintenance: if the type of the expression being cast changes, then the
presence of the cast can hide a necessary change in the code that does the
cast. Using CONST_CAST, instead of a bare cast, makes these changes
visible.
Inspired by my own work elsewhere:
http://git.savannah.gnu.org/cgit/pspp.git/tree/src/libpspp/cast.h#n80
Signed-off-by: Ben Pfaff <blp@nicira.com>
Replaced all instances of Nicira Networks(, Inc) to Nicira, Inc.
Feature #10593
Signed-off-by: Raju Subramanian <rsubramanian@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
This is useful in a situation where one knows that an hmap_node is in some
hmap, but it's not certain which one, and one needs to know whether it is
in a particular one. This is not a very common case; I don't see any
potential users in the current tree, although an upcoming commit will add
one.
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit makes several library headers suitable for inclusion in C++.
It adds [extern "C"] guards and makes minor changes to fix casting and
keyword issues.
This function offers a way to iterate through an hmap in situations where
it is not safe to retain a node pointer.
Acked-by: Jesse Gross <jesse@nicira.com>
This prepares for adding a new function that deals with a "struct hmap"
moving, as opposed to a "struct hmap_node".
Since there was only a single call to this in the whole tree, and its
caller didn't have any callers of its own at all, also move this function
from hmap.h to hmap.c.
This is useful in cases where one might want to know whether an hmap_node
is actually part of an hmap, without using a separate variable to indicate
it.
Usually, the hash comparison that HMAP_FOR_EACH_WITH_HASH does is an
optimization, because comparing a hash value is usually cheaper than
comparing an entire hash map key. But for simple hash map keys, it makes
sense to just compare the key directly, because it avoids doing two
comparisons when a single simple comparison suffices. This commit adds new
functions and macros to support this simple case.
When hmap_replace() replaces one hash table node by another, it must
ensure that any nodes following the old node also follow the new node,
by copying the "next" pointer from "old" to "new".