X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Futil.c;h=cbcf693e1b6bf6e78c9e4e5d0baba40400ada371;hb=d41d4b714d29091dd502dd8705ef489467e11a43;hp=810d766dc7fbe0be9d93e2d2539f1e5b7e0467d3;hpb=e385ef551a09abcba77810bcea0eb3ca559c09a3;p=openvswitch diff --git a/lib/util.c b/lib/util.c index 810d766d..cbcf693e 100644 --- a/lib/util.c +++ b/lib/util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,14 @@ VLOG_DEFINE_THIS_MODULE(util); COVERAGE_DEFINE(util_xalloc); +/* argv[0] without directory names. */ const char *program_name; + +/* Ordinarily "" but set to "monitor" for a monitor process or "worker" for a + * worker process. */ +const char *subprogram_name = ""; + +/* --version option output. */ static char *program_version; void @@ -192,9 +199,14 @@ ovs_abort(int err_no, const char *format, ...) va_list args; va_start(args, format); - ovs_error_valist(err_no, format, args); - va_end(args); + ovs_abort_valist(err_no, format, args); +} +/* Same as ovs_abort() except that the arguments are supplied as a va_list. */ +void +ovs_abort_valist(int err_no, const char *format, va_list args) +{ + ovs_error_valist(err_no, format, args); abort(); } @@ -243,7 +255,12 @@ ovs_error_valist(int err_no, const char *format, va_list args) { int save_errno = errno; - fprintf(stderr, "%s: ", program_name); + if (subprogram_name[0]) { + fprintf(stderr, "%s(%s): ", program_name, subprogram_name); + } else { + fprintf(stderr, "%s: ", program_name); + } + vfprintf(stderr, format, args); if (err_no != 0) { fprintf(stderr, " (%s)", ovs_retval_to_string(err_no)); @@ -865,6 +882,110 @@ bitwise_zero(void *dst_, unsigned int dst_len, unsigned dst_ofs, } } +/* Sets to 1 all of the 'n_bits' bits starting from bit 'dst_ofs' in 'dst'. + * 'dst' is 'dst_len' bytes long. + * + * If you consider all of 'dst' to be a single unsigned integer in network byte + * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit + * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is + * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len - + * 2], and so on. + * + * Required invariant: + * dst_ofs + n_bits <= dst_len * 8 + */ +void +bitwise_one(void *dst_, unsigned int dst_len, unsigned dst_ofs, + unsigned int n_bits) +{ + uint8_t *dst = dst_; + + if (!n_bits) { + return; + } + + dst += dst_len - (dst_ofs / 8 + 1); + dst_ofs %= 8; + + if (dst_ofs) { + unsigned int chunk = MIN(n_bits, 8 - dst_ofs); + + *dst |= ((1 << chunk) - 1) << dst_ofs; + + n_bits -= chunk; + if (!n_bits) { + return; + } + + dst--; + } + + while (n_bits >= 8) { + *dst-- = 0xff; + n_bits -= 8; + } + + if (n_bits) { + *dst |= (1 << n_bits) - 1; + } +} + +/* Scans the 'n_bits' bits starting from bit 'dst_ofs' in 'dst' for 1-bits. + * Returns false if any 1-bits are found, otherwise true. 'dst' is 'dst_len' + * bytes long. + * + * If you consider all of 'dst' to be a single unsigned integer in network byte + * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit + * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is + * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len - + * 2], and so on. + * + * Required invariant: + * dst_ofs + n_bits <= dst_len * 8 + */ +bool +bitwise_is_all_zeros(const void *p_, unsigned int len, unsigned int ofs, + unsigned int n_bits) +{ + const uint8_t *p = p_; + + if (!n_bits) { + return true; + } + + p += len - (ofs / 8 + 1); + ofs %= 8; + + if (ofs) { + unsigned int chunk = MIN(n_bits, 8 - ofs); + + if (*p & (((1 << chunk) - 1) << ofs)) { + return false; + } + + n_bits -= chunk; + if (!n_bits) { + return true; + } + + p--; + } + + while (n_bits >= 8) { + if (*p) { + return false; + } + n_bits -= 8; + p--; + } + + if (n_bits && *p & ((1 << n_bits) - 1)) { + return false; + } + + return true; +} + /* Copies the 'n_bits' low-order bits of 'value' into the 'n_bits' bits * starting at bit 'dst_ofs' in 'dst', which is 'dst_len' bytes long. *