netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / lib / util.h
index cbaa3ac..afd8e37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 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.
 #endif
 OVS_NO_RETURN void ovs_assert_failure(const char *, const char *, const char *);
 
+/* This is a void expression that issues a compiler error if POINTER cannot be
+ * compared for equality with the given pointer TYPE.  This generally means
+ * that POINTER is a qualified or unqualified TYPE.  However,
+ * BUILD_ASSERT_TYPE(POINTER, void *) will accept any pointer to object type,
+ * because any pointer to object can be compared for equality with "void *".
+ *
+ * POINTER can be any expression.  The use of "sizeof" ensures that the
+ * expression is not actually evaluated, so that any side effects of the
+ * expression do not occur.
+ *
+ * The cast to int is present only to suppress an "expression using sizeof
+ * bool" warning from "sparse" (see
+ * http://permalink.gmane.org/gmane.comp.parsers.sparse/2967). */
+#define BUILD_ASSERT_TYPE(POINTER, TYPE) \
+    ((void) sizeof ((int) ((POINTER) == (TYPE) (POINTER))))
+
 /* Casts 'pointer' to 'type' and issues a compiler warning if the cast changes
  * anything other than an outermost "const" or "volatile" qualifier.
  *
@@ -86,7 +102,7 @@ OVS_NO_RETURN void ovs_assert_failure(const char *, const char *, const char *);
  * bool" warning from "sparse" (see
  * http://permalink.gmane.org/gmane.comp.parsers.sparse/2967). */
 #define CONST_CAST(TYPE, POINTER)                               \
-    ((void) sizeof ((int) ((POINTER) == (TYPE) (POINTER))),     \
+    (BUILD_ASSERT_TYPE(POINTER, TYPE),                          \
      (TYPE) (POINTER))
 
 extern char *program_name;
@@ -199,6 +215,13 @@ ovs_prefetch_range(const void *start, size_t size)
     ((char *) &(OBJECT)->MEMBER - (char *) (OBJECT))
 #endif
 
+/* Yields the size of MEMBER within STRUCT. */
+#define MEMBER_SIZEOF(STRUCT, MEMBER) (sizeof(((STRUCT *) NULL)->MEMBER))
+
+/* Yields the offset of the end of MEMBER within STRUCT. */
+#define OFFSETOFEND(STRUCT, MEMBER) \
+        (offsetof(STRUCT, MEMBER) + MEMBER_SIZEOF(STRUCT, MEMBER))
+
 /* Given POINTER, the address of the given MEMBER in a STRUCT object, returns
    the STRUCT object. */
 #define CONTAINER_OF(POINTER, STRUCT, MEMBER)                           \
@@ -263,7 +286,7 @@ extern "C" {
         ovs_set_program_name(name, OVS_PACKAGE_VERSION)
 
 const char *get_subprogram_name(void);
-void set_subprogram_name(const char *format, ...) OVS_PRINTF_FORMAT(1, 2);
+    void set_subprogram_name(const char *);
 
 void ovs_print_version(uint8_t min_ofp, uint8_t max_ofp);
 
@@ -314,6 +337,9 @@ bool str_to_double(const char *, double *);
 int hexit_value(int c);
 uintmax_t hexits_value(const char *s, size_t n, bool *ok);
 
+int parse_int_string(const char *s, uint8_t *valuep, int field_width,
+                     char **tail);
+
 const char *english_list_delimiter(size_t index, size_t total);
 
 char *get_cwd(void);
@@ -352,11 +378,11 @@ static inline int
 raw_ctz(uint64_t n)
 {
 #ifdef _WIN64
-    uint32_t r = 0;
+    unsigned long r = 0;
     _BitScanForward64(&r, n);
     return r;
 #else
-    uint32_t low = n, high, r = 0;
+    unsigned long low = n, high, r = 0;
     if (_BitScanForward(&r, low)) {
         return r;
     }
@@ -370,11 +396,11 @@ static inline int
 raw_clz64(uint64_t n)
 {
 #ifdef _WIN64
-    uint32_t r = 0;
+    unsigned long r = 0;
     _BitScanReverse64(&r, n);
     return 63 - r;
 #else
-    uint32_t low, high = n >> 32, r = 0;
+    unsigned long low, high = n >> 32, r = 0;
     if (_BitScanReverse(&r, high)) {
         return 31 - r;
     }
@@ -500,25 +526,20 @@ zero_rightmost_1bit(uintmax_t x)
     return x & (x - 1);
 }
 
-/* Returns the index of the rightmost 1-bit in 'x' (e.g. 01011000 => 3), or 32
- * if 'x' is 0.
- *
- * Unlike the other functions for rightmost 1-bits, this function only works
- * with 32-bit integers. */
+/* Returns the index of the rightmost 1-bit in 'x' (e.g. 01011000 => 3), or an
+ * undefined value if 'x' is 0. */
 static inline int
-rightmost_1bit_idx(uint32_t x)
+rightmost_1bit_idx(uint64_t x)
 {
-    return ctz32(x);
+    return ctz64(x);
 }
 
-/* Returns the index of the leftmost 1-bit in 'x' (e.g. 01011000 => 6), or 32
- * if 'x' is 0.
- *
- * This function only works with 32-bit integers. */
+/* Returns the index of the leftmost 1-bit in 'x' (e.g. 01011000 => 6), or an
+ * undefined value if 'x' is 0. */
 static inline uint32_t
-leftmost_1bit_idx(uint32_t x)
+leftmost_1bit_idx(uint64_t x)
 {
-    return x ? log_2_floor(x) : 32;
+    return log_2_floor(x);
 }
 
 /* Return a ovs_be32 prefix in network byte order with 'plen' highest bits set.
@@ -542,11 +563,53 @@ bool bitwise_is_all_zeros(const void *, unsigned int len, unsigned int ofs,
                           unsigned int n_bits);
 unsigned int bitwise_scan(const void *, unsigned int len,
                           bool target, unsigned int start, unsigned int end);
+int bitwise_rscan(const void *, unsigned int len, bool target,
+                  int start, int end);
 void bitwise_put(uint64_t value,
                  void *dst, unsigned int dst_len, unsigned int dst_ofs,
                  unsigned int n_bits);
 uint64_t bitwise_get(const void *src, unsigned int src_len,
                      unsigned int src_ofs, unsigned int n_bits);
+bool bitwise_get_bit(const void *src, unsigned int len, unsigned int ofs);
+void bitwise_put0(void *dst, unsigned int len, unsigned int ofs);
+void bitwise_put1(void *dst, unsigned int len, unsigned int ofs);
+void bitwise_put_bit(void *dst, unsigned int len, unsigned int ofs, bool);
+void bitwise_toggle_bit(void *dst, unsigned int len, unsigned int ofs);
+
+/* Returns non-zero if the parameters have equal value. */
+static inline int
+ovs_u128_equals(const ovs_u128 *a, const ovs_u128 *b)
+{
+    return (a->u64.hi == b->u64.hi) && (a->u64.lo == b->u64.lo);
+}
+
+/* Returns true if 'val' is 0. */
+static inline bool
+ovs_u128_is_zero(const ovs_u128 *val)
+{
+    return !(val->u64.hi || val->u64.lo);
+}
+
+/* Returns true if 'val' is all ones. */
+static inline bool
+ovs_u128_is_ones(const ovs_u128 *val)
+{
+    return ovs_u128_equals(val, &OVS_U128_MAX);
+}
+
+/* Returns non-zero if the parameters have equal value. */
+static inline int
+ovs_be128_equals(const ovs_be128 *a, const ovs_be128 *b)
+{
+    return (a->be64.hi == b->be64.hi) && (a->be64.lo == b->be64.lo);
+}
+
+/* Returns true if 'val' is 0. */
+static inline bool
+ovs_be128_is_zero(const ovs_be128 *val)
+{
+    return !(val->be64.hi || val->be64.lo);
+}
 
 void xsleep(unsigned int seconds);