2009-07-08 13:19:16 -07:00
|
|
|
/*
|
2012-05-02 15:21:36 -07:00
|
|
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
|
2009-07-08 13:19:16 -07:00
|
|
|
*
|
2009-06-15 15:11:30 -07:00
|
|
|
* 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:
|
2009-07-08 13:19:16 -07:00
|
|
|
*
|
2009-06-15 15:11:30 -07:00
|
|
|
* 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.
|
2009-07-08 13:19:16 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef UTIL_H
|
|
|
|
#define UTIL_H 1
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "compiler.h"
|
|
|
|
|
|
|
|
#ifndef va_copy
|
|
|
|
#ifdef __va_copy
|
|
|
|
#define va_copy __va_copy
|
|
|
|
#else
|
|
|
|
#define va_copy(dst, src) ((dst) = (src))
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2011-05-06 11:43:04 -07:00
|
|
|
#ifdef __CHECKER__
|
|
|
|
#define BUILD_ASSERT(EXPR) ((void) 0)
|
|
|
|
#define BUILD_ASSERT_DECL(EXPR) extern int (*build_assert(void))[1]
|
|
|
|
#elif !defined(__cplusplus)
|
2009-07-08 13:19:16 -07:00
|
|
|
/* Build-time assertion building block. */
|
|
|
|
#define BUILD_ASSERT__(EXPR) \
|
|
|
|
sizeof(struct { unsigned int build_assert_failed : (EXPR) ? 1 : -1; })
|
|
|
|
|
|
|
|
/* Build-time assertion for use in a statement context. */
|
|
|
|
#define BUILD_ASSERT(EXPR) (void) BUILD_ASSERT__(EXPR)
|
|
|
|
|
|
|
|
/* Build-time assertion for use in a declaration context. */
|
|
|
|
#define BUILD_ASSERT_DECL(EXPR) \
|
|
|
|
extern int (*build_assert(void))[BUILD_ASSERT__(EXPR)]
|
|
|
|
#else /* __cplusplus */
|
|
|
|
#include <boost/static_assert.hpp>
|
|
|
|
#define BUILD_ASSERT BOOST_STATIC_ASSERT
|
|
|
|
#define BUILD_ASSERT_DECL BOOST_STATIC_ASSERT
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
dpif-linux: Fix build with certain 64-bit kernel/userspace combinations.
Unix 64-bit ABIs have two 64-bit types: "long" and "long long". Either of
these is a reasonable choice for uint64_t (the userspace type) and for
__u64 (the kernel type). Unfortunately, kernel and userspace don't
necessarily agree on the choice, and in fact the choice varies across
kernel versions and architectures.
Now that OVS is actually using kernel types in its kernel header, this
can make a difference: when __u64 and uint64_t differ, passing a pointer
to __u64 to OVS function get_unaligned_u64() yields a compiler warning
or error.
This commit fixes up the problems of this type found in OVS, by making
get_unaligned_u64() accept all 64-bit unsigned integer types, not just
whichever one happens to be uint64_t. I didn't do the same thing for
put_unaligned_u64() because it is less likely to be a problem in
practice: usually, when userspace writes to kernel data structures it
does so with copies that it knows to be aligned, so that it's not
necessary to use put_unaligned_u64().
This problem won't occur for uint8_t, uint16_t, or uint32_t, since there is
only one reasonable choice of type for each. It won't occur for ovs_be<N>
because OVS always defines those as aliases for the kernel's __be<N> types
when those are available.
This compiled cleanly for me in Scientific Linux 6.0 x86-64.
Reported-by: Pravin Shelar <pshelar@nicira.com>
2011-10-14 09:39:48 -07:00
|
|
|
#ifdef __GNUC__
|
|
|
|
#define BUILD_ASSERT_GCCONLY(EXPR) BUILD_ASSERT(EXPR)
|
|
|
|
#define BUILD_ASSERT_DECL_GCCONLY(EXPR) BUILD_ASSERT_DECL(EXPR)
|
|
|
|
#else
|
|
|
|
#define BUILD_ASSERT_GCCONLY(EXPR) ((void) 0)
|
|
|
|
#define BUILD_ASSERT_DECL_GCCONLY(EXPR) ((void) 0)
|
|
|
|
#endif
|
|
|
|
|
2012-07-13 16:00:29 -07:00
|
|
|
/* Casts 'pointer' to 'type' and issues a compiler warning if the cast changes
|
|
|
|
* anything other than an outermost "const" or "volatile" qualifier.
|
|
|
|
*
|
|
|
|
* 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 CONST_CAST(TYPE, POINTER) \
|
|
|
|
((void) sizeof ((int) ((POINTER) == (TYPE) (POINTER))), \
|
|
|
|
(TYPE) (POINTER))
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
extern const char *program_name;
|
2012-07-18 10:30:47 -07:00
|
|
|
extern const char *subprogram_name;
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2009-09-17 15:12:34 -07:00
|
|
|
/* Returns the number of elements in ARRAY. */
|
2009-07-08 13:19:16 -07:00
|
|
|
#define ARRAY_SIZE(ARRAY) (sizeof ARRAY / sizeof *ARRAY)
|
2009-09-17 15:12:34 -07:00
|
|
|
|
|
|
|
/* Returns X / Y, rounding up. X must be nonnegative to round correctly. */
|
2009-09-17 14:45:18 -07:00
|
|
|
#define DIV_ROUND_UP(X, Y) (((X) + ((Y) - 1)) / (Y))
|
2009-09-17 15:12:34 -07:00
|
|
|
|
|
|
|
/* Returns X rounded up to the nearest multiple of Y. */
|
2009-09-17 14:45:18 -07:00
|
|
|
#define ROUND_UP(X, Y) (DIV_ROUND_UP(X, Y) * (Y))
|
2009-09-17 15:12:34 -07:00
|
|
|
|
|
|
|
/* Returns X rounded down to the nearest multiple of Y. */
|
2009-07-08 13:19:16 -07:00
|
|
|
#define ROUND_DOWN(X, Y) ((X) / (Y) * (Y))
|
2009-09-17 15:12:34 -07:00
|
|
|
|
|
|
|
/* Returns true if X is a power of 2, otherwise false. */
|
2009-07-08 13:19:16 -07:00
|
|
|
#define IS_POW2(X) ((X) && !((X) & ((X) - 1)))
|
|
|
|
|
2012-02-10 13:30:23 -08:00
|
|
|
static inline bool
|
|
|
|
is_pow2(uintmax_t x)
|
|
|
|
{
|
|
|
|
return IS_POW2(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns the rightmost 1-bit in 'x' (e.g. 01011000 => 00001000), or 0 if 'x'
|
|
|
|
* is 0. */
|
|
|
|
static inline uintmax_t
|
|
|
|
rightmost_1bit(uintmax_t x)
|
|
|
|
{
|
|
|
|
return x & -x;
|
|
|
|
}
|
|
|
|
|
2012-07-20 11:45:33 -07:00
|
|
|
/* Returns 'x' with its rightmost 1-bit changed to a zero (e.g. 01011000 =>
|
|
|
|
* 01010000), or 0 if 'x' is 0. */
|
|
|
|
static inline uintmax_t
|
|
|
|
zero_rightmost_1bit(uintmax_t x)
|
|
|
|
{
|
|
|
|
return x & (x - 1);
|
|
|
|
}
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
#ifndef MIN
|
|
|
|
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef MAX
|
|
|
|
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define NOT_REACHED() abort()
|
|
|
|
|
poll-loop: Make wakeup logging more portable and easier to understand.
Until now, when the poll_loop module's log level was turned up to "debug",
it would log a backtrace of the call stack for the event that caused poll()
to wake up in poll_block(). This was pretty useful from time to time to
find out why ovs-vswitchd was using more CPU than expected, because we
could find out what was causing it to wake up.
But there were some issues. One is simply that the backtrace was printed
as a series of hexadecimal numbers, so GDB or another debugger was needed
to translate it into human-readable format. Compiler optimizations meant
that even the human-readable backtrace wasn't, in my experience, as helpful
as it could have been. And, of course, one needed to have the binary to
interpret the backtrace. When the backtrace couldn't be interpreted or
wasn't meaningful, there was essentially nothing to fall back on.
This commit changes the way that "debug" logging for poll_block() wakeups
works. Instead of logging a backtrace, it logs the source code file name
and line number of the call to a poll_loop function, using __FILE__ and
__LINE__. This is by itself much more meaningful than a sequence of
hexadecimal numbers, since no additional interpretation is necessary. It
can be useful even if the Open vSwitch version is only approximately known.
In addition to the file and line, this commit adds, for wakeups caused by
file descriptors, information about the file descriptor itself: what kind
of file it is (regular file, directory, socket, etc.), the name of the file
(on Linux only), and the local and remote endpoints for socket file
descriptors.
Here are a few examples of the new output format:
932-ms timeout at ../ofproto/in-band.c:507
[POLLIN] on fd 20 (192.168.0.20:35388<->192.168.0.3:6633) at ../lib/stream-fd.c:149
[POLLIN] on fd 7 (FIFO pipe:[48049]) at ../lib/fatal-signal.c:168
2011-05-13 13:06:49 -07:00
|
|
|
/* Expands to a string that looks like "<file>:<line>", e.g. "tmp.c:10".
|
|
|
|
*
|
|
|
|
* See http://c-faq.com/ansi/stringize.html for an explanation of STRINGIZE and
|
|
|
|
* STRINGIZE2. */
|
|
|
|
#define SOURCE_LOCATOR __FILE__ ":" STRINGIZE(__LINE__)
|
|
|
|
#define STRINGIZE(ARG) STRINGIZE2(ARG)
|
|
|
|
#define STRINGIZE2(ARG) #ARG
|
|
|
|
|
2010-11-17 12:34:42 -08:00
|
|
|
/* Given a pointer-typed lvalue OBJECT, expands to a pointer type that may be
|
|
|
|
* assigned to OBJECT. */
|
|
|
|
#ifdef __GNUC__
|
|
|
|
#define OVS_TYPEOF(OBJECT) typeof(OBJECT)
|
|
|
|
#else
|
|
|
|
#define OVS_TYPEOF(OBJECT) void *
|
|
|
|
#endif
|
|
|
|
|
2011-02-24 15:33:57 -08:00
|
|
|
/* Given OBJECT of type pointer-to-structure, expands to the offset of MEMBER
|
|
|
|
* within an instance of the structure.
|
|
|
|
*
|
|
|
|
* The GCC-specific version avoids the technicality of undefined behavior if
|
|
|
|
* OBJECT is null, invalid, or not yet initialized. This makes some static
|
|
|
|
* checkers (like Coverity) happier. But the non-GCC version does not actually
|
|
|
|
* dereference any pointer, so it would be surprising for it to cause any
|
|
|
|
* problems in practice.
|
|
|
|
*/
|
|
|
|
#ifdef __GNUC__
|
|
|
|
#define OBJECT_OFFSETOF(OBJECT, MEMBER) offsetof(typeof(*(OBJECT)), MEMBER)
|
|
|
|
#else
|
|
|
|
#define OBJECT_OFFSETOF(OBJECT, MEMBER) \
|
|
|
|
((char *) &(OBJECT)->MEMBER - (char *) (OBJECT))
|
|
|
|
#endif
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
/* Given POINTER, the address of the given MEMBER in a STRUCT object, returns
|
|
|
|
the STRUCT object. */
|
|
|
|
#define CONTAINER_OF(POINTER, STRUCT, MEMBER) \
|
2010-05-06 17:04:11 -07:00
|
|
|
((STRUCT *) (void *) ((char *) (POINTER) - offsetof (STRUCT, MEMBER)))
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2010-07-19 13:46:52 -07:00
|
|
|
/* Given POINTER, the address of the given MEMBER within an object of the type
|
2010-11-17 12:34:42 -08:00
|
|
|
* that that OBJECT points to, returns OBJECT as an assignment-compatible
|
|
|
|
* pointer type (either the correct pointer type or "void *"). OBJECT must be
|
|
|
|
* an lvalue.
|
2010-07-19 13:46:52 -07:00
|
|
|
*
|
|
|
|
* This is the same as CONTAINER_OF except that it infers the structure type
|
|
|
|
* from the type of '*OBJECT'. */
|
|
|
|
#define OBJECT_CONTAINING(POINTER, OBJECT, MEMBER) \
|
2010-11-17 12:34:42 -08:00
|
|
|
((OVS_TYPEOF(OBJECT)) (void *) \
|
2011-02-24 15:33:57 -08:00
|
|
|
((char *) (POINTER) - OBJECT_OFFSETOF(OBJECT, MEMBER)))
|
2010-07-19 13:46:52 -07:00
|
|
|
|
2010-11-17 14:25:33 -08:00
|
|
|
/* Given POINTER, the address of the given MEMBER within an object of the type
|
|
|
|
* that that OBJECT points to, assigns the address of the outer object to
|
|
|
|
* OBJECT, which must be an lvalue.
|
|
|
|
*
|
|
|
|
* Evaluates to 1. */
|
|
|
|
#define ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER) \
|
|
|
|
((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), 1)
|
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2012-04-06 11:47:51 -07:00
|
|
|
void set_program_name__(const char *name, const char *version,
|
|
|
|
const char *date, const char *time);
|
2011-08-02 12:16:44 -07:00
|
|
|
#define set_program_name(name) \
|
2012-04-06 11:47:51 -07:00
|
|
|
set_program_name__(name, VERSION, __DATE__, __TIME__)
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2011-08-02 12:16:44 -07:00
|
|
|
const char *get_program_version(void);
|
|
|
|
void ovs_print_version(uint8_t min_ofp, uint8_t max_ofp);
|
2009-07-08 13:19:16 -07:00
|
|
|
|
|
|
|
void out_of_memory(void) NO_RETURN;
|
|
|
|
void *xmalloc(size_t) MALLOC_LIKE;
|
|
|
|
void *xcalloc(size_t, size_t) MALLOC_LIKE;
|
2009-09-28 13:56:42 -07:00
|
|
|
void *xzalloc(size_t) MALLOC_LIKE;
|
2009-07-08 13:19:16 -07:00
|
|
|
void *xrealloc(void *, size_t);
|
|
|
|
void *xmemdup(const void *, size_t) MALLOC_LIKE;
|
|
|
|
char *xmemdup0(const char *, size_t) MALLOC_LIKE;
|
|
|
|
char *xstrdup(const char *) MALLOC_LIKE;
|
|
|
|
char *xasprintf(const char *format, ...) PRINTF_FORMAT(1, 2) MALLOC_LIKE;
|
|
|
|
char *xvasprintf(const char *format, va_list) PRINTF_FORMAT(1, 0) MALLOC_LIKE;
|
|
|
|
void *x2nrealloc(void *p, size_t *n, size_t s);
|
|
|
|
|
|
|
|
void ovs_strlcpy(char *dst, const char *src, size_t size);
|
2011-02-22 10:58:36 -08:00
|
|
|
void ovs_strzcpy(char *dst, const char *src, size_t size);
|
2009-07-08 13:19:16 -07:00
|
|
|
|
2011-02-23 15:43:34 -08:00
|
|
|
void ovs_abort(int err_no, const char *format, ...)
|
|
|
|
PRINTF_FORMAT(2, 3) NO_RETURN;
|
2012-05-22 11:36:50 -07:00
|
|
|
void ovs_abort_valist(int err_no, const char *format, va_list)
|
|
|
|
PRINTF_FORMAT(2, 0) NO_RETURN;
|
2009-07-08 13:19:16 -07:00
|
|
|
void ovs_fatal(int err_no, const char *format, ...)
|
|
|
|
PRINTF_FORMAT(2, 3) NO_RETURN;
|
2011-03-31 14:50:58 -07:00
|
|
|
void ovs_fatal_valist(int err_no, const char *format, va_list)
|
|
|
|
PRINTF_FORMAT(2, 0) NO_RETURN;
|
2009-07-08 13:19:16 -07:00
|
|
|
void ovs_error(int err_no, const char *format, ...) PRINTF_FORMAT(2, 3);
|
2011-02-23 15:43:34 -08:00
|
|
|
void ovs_error_valist(int err_no, const char *format, va_list)
|
|
|
|
PRINTF_FORMAT(2, 0);
|
2011-01-30 11:29:14 -08:00
|
|
|
const char *ovs_retval_to_string(int);
|
2009-07-08 13:19:16 -07:00
|
|
|
void ovs_hex_dump(FILE *, const void *, size_t, uintptr_t offset, bool ascii);
|
|
|
|
|
|
|
|
bool str_to_int(const char *, int base, int *);
|
|
|
|
bool str_to_long(const char *, int base, long *);
|
|
|
|
bool str_to_llong(const char *, int base, long long *);
|
|
|
|
bool str_to_uint(const char *, int base, unsigned int *);
|
|
|
|
bool str_to_ulong(const char *, int base, unsigned long *);
|
|
|
|
bool str_to_ullong(const char *, int base, unsigned long long *);
|
|
|
|
|
2009-11-04 14:55:53 -08:00
|
|
|
bool str_to_double(const char *, double *);
|
|
|
|
|
|
|
|
int hexit_value(int c);
|
2010-11-15 10:18:10 -08:00
|
|
|
unsigned int hexits_value(const char *s, size_t n, bool *ok);
|
2009-11-04 14:55:53 -08:00
|
|
|
|
2011-06-02 10:47:18 -07:00
|
|
|
const char *english_list_delimiter(size_t index, size_t total);
|
|
|
|
|
2010-03-16 15:06:11 -07:00
|
|
|
char *get_cwd(void);
|
2009-10-19 14:04:14 -07:00
|
|
|
char *dir_name(const char *file_name);
|
2010-11-09 14:38:28 -08:00
|
|
|
char *base_name(const char *file_name);
|
2010-03-16 15:06:11 -07:00
|
|
|
char *abs_file_name(const char *dir, const char *file_name);
|
2009-10-19 14:04:14 -07:00
|
|
|
|
2012-07-30 11:36:06 -07:00
|
|
|
char *xreadlink(const char *filename);
|
|
|
|
char *follow_symlinks(const char *filename);
|
|
|
|
|
2010-02-11 11:11:23 -08:00
|
|
|
void ignore(bool x OVS_UNUSED);
|
2011-08-17 10:55:15 -07:00
|
|
|
int log_2_floor(uint32_t);
|
2011-12-27 13:37:43 -08:00
|
|
|
int log_2_ceil(uint32_t);
|
2011-08-17 10:55:15 -07:00
|
|
|
int ctz(uint32_t);
|
2009-12-14 23:08:10 -08:00
|
|
|
|
2011-09-12 16:19:57 -07:00
|
|
|
bool is_all_zeros(const uint8_t *, size_t);
|
|
|
|
bool is_all_ones(const uint8_t *, size_t);
|
2012-01-17 16:38:23 -08:00
|
|
|
void bitwise_copy(const void *src, unsigned int src_len, unsigned int src_ofs,
|
|
|
|
void *dst, unsigned int dst_len, unsigned int dst_ofs,
|
|
|
|
unsigned int n_bits);
|
2012-01-17 16:53:29 -08:00
|
|
|
void bitwise_zero(void *dst_, unsigned int dst_len, unsigned dst_ofs,
|
|
|
|
unsigned int n_bits);
|
2012-04-11 12:07:51 -07:00
|
|
|
void bitwise_one(void *dst_, unsigned int dst_len, unsigned dst_ofs,
|
|
|
|
unsigned int n_bits);
|
2012-04-13 21:12:37 -07:00
|
|
|
bool bitwise_is_all_zeros(const void *, unsigned int len, unsigned int ofs,
|
|
|
|
unsigned int n_bits);
|
2012-01-17 16:38:23 -08:00
|
|
|
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);
|
2011-09-12 16:19:57 -07:00
|
|
|
|
2009-07-08 13:19:16 -07:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* util.h */
|