Skip to contentSkip to conversation

Move adjust_power_of_2() to integer.h

PATCH In review Steffan Karger 5 participants 10 messages Jun 19, 2017 – Jun 27, 2017

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Move adjust_power_of_2() to integer.h

misc.c it a mess of incoherent functions, and is therefore included by virtually all our source files. That makes testing harder than it should be. As a first step of cleaning up misc.c, move adjust_power_of_2() to integer.h, which is a more suitable place for a function like this.

This allows us to remove the duplicate implementation from test_argv.c.

---
 src/openvpn/integer.h                | 17 +++++++++++++++++
 src/openvpn/misc.c                   | 18 ------------------
 src/openvpn/misc.h                   |  2 --
 tests/unit_tests/openvpn/test_argv.c | 19 +------------------
 4 files changed, 18 insertions(+), 38 deletions(-)
src/openvpn/integer.h +17 -0
index 240781b..882322a 100644
@@ -118,6 +118,23 @@ modulo_add(int x, int y, int mod)
     return sum;
 }
 
+/*
+ * Return the next largest power of 2
+ * or u if u is a power of 2.
+ */
+static inline size_t adjust_power_of_2(size_t u)
+{
+    size_t ret = 1;
+
+    while (ret < u)
+    {
+        ret <<= 1;
+        ASSERT(ret > 0);
+    }
+
+    return ret;
+}
+
 static inline int
 index_verify(int index, int size, const char *file, int line)
 {
src/openvpn/misc.c +0 -18
index df108b0..561f80f 100644
@@ -1641,24 +1641,6 @@ openvpn_sleep(const int n)
 }
 
 /*
- * Return the next largest power of 2
- * or u if u is a power of 2.
- */
-size_t
-adjust_power_of_2(size_t u)
-{
-    size_t ret = 1;
-
-    while (ret < u)
-    {
-        ret <<= 1;
-        ASSERT(ret > 0);
-    }
-
-    return ret;
-}
-
-/*
  * Remove security-sensitive strings from control message
  * so that they will not be output to log file.
  */
src/openvpn/misc.h +0 -2
index 94573b2..f55186f 100644
@@ -325,8 +325,6 @@ extern const char *iproute_path;
 #define SSEC_PW_ENV    3 /* allow calling of built-in programs and user-defined scripts that may receive a password as an environmental variable */
 extern int script_security; /* GLOBAL */
 
-/* return the next largest power of 2 */
-size_t adjust_power_of_2(size_t u);
 
 #define COMPAT_FLAG_QUERY         0       /** compat_flags operator: Query for a flag */
 #define COMPAT_FLAG_SET           (1<<0)  /** compat_flags operator: Set a compat flag */
tests/unit_tests/openvpn/test_argv.c +1 -18
index 8c90eb9..c5ebc09 100644
@@ -12,24 +12,7 @@
 
 #include "argv.h"
 #include "buffer.h"
-
-/*
- * This is defined here to prevent #include'ing misc.h
- * which makes things difficult beyond any recognition
- */
-size_t
-adjust_power_of_2(size_t u)
-{
-    size_t ret = 1;
-
-    while (ret < u)
-    {
-        ret <<= 1;
-        assert(ret > 0);
-    }
-
-    return ret;
-}
+#include "integer.h"
 
 /* Defines for use in the tests and the mock parse_line() */
 #define PATH1       "/s p a c e"
Signature · 1 line
2.7.4
#1 lore raw
Quoted 1 line · Steffan Karger

misc.c it a mess of incoherent functions, and is therefore included by

little typ0 here: s/it/is/

Quoted 101 lines

virtually all our source files. That makes testing harder than it should be. As a first step of cleaning up misc.c, move adjust_power_of_2() to integer.h, which is a more suitable place for a function like this.

This allows us to remove the duplicate implementation from test_argv.c.

---
 src/openvpn/integer.h                | 17 +++++++++++++++++
 src/openvpn/misc.c                   | 18 ------------------
 src/openvpn/misc.h                   |  2 --
 tests/unit_tests/openvpn/test_argv.c | 19 +------------------
 4 files changed, 18 insertions(+), 38 deletions(-)
src/openvpn/integer.h +17 -0
index 240781b..882322a 100644
@@ -118,6 +118,23 @@ modulo_add(int x, int y, int mod)
     return sum;
 }
 
+/*
+ * Return the next largest power of 2
+ * or u if u is a power of 2.
+ */
+static inline size_t adjust_power_of_2(size_t u)
+{
+    size_t ret = 1;
+
+    while (ret < u)
+    {
+        ret <<= 1;
+        ASSERT(ret > 0);
+    }
+
+    return ret;
+}
+
 static inline int
 index_verify(int index, int size, const char *file, int line)
 {
src/openvpn/misc.c +0 -18
index df108b0..561f80f 100644
@@ -1641,24 +1641,6 @@ openvpn_sleep(const int n)
 }
 
 /*
- * Return the next largest power of 2
- * or u if u is a power of 2.
- */
-size_t
-adjust_power_of_2(size_t u)
-{
-    size_t ret = 1;
-
-    while (ret < u)
-    {
-        ret <<= 1;
-        ASSERT(ret > 0);
-    }
-
-    return ret;
-}
-
-/*
  * Remove security-sensitive strings from control message
  * so that they will not be output to log file.
  */
src/openvpn/misc.h +0 -2
index 94573b2..f55186f 100644
@@ -325,8 +325,6 @@ extern const char *iproute_path;
 #define SSEC_PW_ENV    3 /* allow calling of built-in programs and user-defined scripts that may receive a password as an environmental variable */
 extern int script_security; /* GLOBAL */
 
-/* return the next largest power of 2 */
-size_t adjust_power_of_2(size_t u);
 
 #define COMPAT_FLAG_QUERY         0       /** compat_flags operator: Query for a flag */
 #define COMPAT_FLAG_SET           (1<<0)  /** compat_flags operator: Set a compat flag */
tests/unit_tests/openvpn/test_argv.c +0 -9
index 8c90eb9..c5ebc09 100644
@@ -12,24 +12,7 @@
 
 #include "argv.h"
 #include "buffer.h"
-
-/*
- * This is defined here to prevent #include'ing misc.h
- * which makes things difficult beyond any recognition
- */
-size_t
-adjust_power_of_2(size_t u)
-{
-    size_t ret = 1;

tests/unit_tests/openvpn/test_argv.c line 15

Quoted 10 lines
tests/unit_tests/openvpn/test_argv.c +1 -9
-
-    while (ret < u)
-    {
-        ret <<= 1;
-        assert(ret > 0);
-    }
-
-    return ret;
-}
+#include "integer.h"

This duplication was really ugly :-P Thanks for getting rid of it.

However, now that adjust_power_of_2() has been moved to integer.h, shouldn't this file be included by every .c where the function is used? Or do we have some other rule about header files inclusion?

Personally I prefer when every .c file directly includes the .h it relies on, without assuming any indirect inclusion. What's the common habit here?

Cheers,

Quoted 6 lines
tests/unit_tests/openvpn/test_argv.c +0 -0
 /* Defines for use in the tests and the mock parse_line() */
 #define PATH1       "/s p a c e"
Signature · 1 line
2.7.4
Signature · 1 line
Antonio Quartulli
#2 lore raw

Hi,

Quoted 6 lines · Antonio Quartulli

However, now that adjust_power_of_2() has been moved to integer.h, shouldn't this file be included by every .c where the function is used? Or do we have some other rule about header files inclusion?

Personally I prefer when every .c file directly includes the .h it relies on, without assuming any indirect inclusion. What's the common habit here?

We have no consistent rule or habit that I know of, but I fully agree with you. So thanks for paying attention, will send a v2 in a minute.

-Steffan

#3 lore raw

PATCH v2 1/1 Move adjust_power_of_2() to integer.h

From: Steffan Karger <[email protected]...>

misc.c is a mess of incoherent functions, and is therefore included by virtually all our source files. That makes testing harder than it should be. As a first step of cleaning up misc.c, move adjust_power_of_2() to integer.h, which is a more suitable place for a function like this.

This allows us to remove the duplicate implementation from test_argv.c.

---
v2: fix includes, fix typo in commit msg

 src/openvpn/argv.c                   |  1 +
 src/openvpn/integer.h                | 18 ++++++++++++++++++
 src/openvpn/list.c                   |  1 +
 src/openvpn/mbuf.c                   |  1 +
 src/openvpn/misc.c                   | 18 ------------------
 src/openvpn/misc.h                   |  2 --
 tests/unit_tests/openvpn/test_argv.c | 18 ------------------
 7 files changed, 21 insertions(+), 38 deletions(-)
src/openvpn/argv.c +1 -0
index a71d261c..95bdfeac 100644
@@ -36,6 +36,7 @@
 #include "syshead.h"
 
 #include "argv.h"
+#include "integer.h"
 #include "options.h"
 
 static void
src/openvpn/integer.h +18 -0
index 884b849f..600e1384 100644
@@ -114,6 +114,24 @@ modulo_add(int x, int y, int mod)
     return sum;
 }
 
+/*
+ * Return the next largest power of 2
+ * or u if u is a power of 2.
+ */
+static inline size_t
+adjust_power_of_2(size_t u)
+{
+    size_t ret = 1;
+
+    while (ret < u)
+    {
+        ret <<= 1;
+        ASSERT(ret > 0);
+    }
+
+    return ret;
+}
+
 static inline int
 index_verify(int index, int size, const char *file, int line)
 {
src/openvpn/list.c +1 -0
index edca6f79..91765d20 100644
@@ -31,6 +31,7 @@
 
 #if P2MP_SERVER
 
+#include "integer.h"
 #include "list.h"
 #include "misc.h"
 
src/openvpn/mbuf.c +1 -0
index fafbce01..f969a2b5 100644
@@ -33,6 +33,7 @@
 
 #include "buffer.h"
 #include "error.h"
+#include "integer.h"
 #include "misc.h"
 #include "mbuf.h"
 
src/openvpn/misc.c +0 -18
index 608204ee..0b65e6e2 100644
@@ -1646,24 +1646,6 @@ openvpn_sleep(const int n)
 }
 
 /*
- * Return the next largest power of 2
- * or u if u is a power of 2.
- */
-size_t
-adjust_power_of_2(size_t u)
-{
-    size_t ret = 1;
-
-    while (ret < u)
-    {
-        ret <<= 1;
-        ASSERT(ret > 0);
-    }
-
-    return ret;
-}
-
-/*
  * Remove security-sensitive strings from control message
  * so that they will not be output to log file.
  */
src/openvpn/misc.h +0 -2
index d504e68a..c9fa97ab 100644
@@ -328,8 +328,6 @@ extern const char *iproute_path;
 #define SSEC_PW_ENV    3 /* allow calling of built-in programs and user-defined scripts that may receive a password as an environmental variable */
 extern int script_security; /* GLOBAL */
 
-/* return the next largest power of 2 */
-size_t adjust_power_of_2(size_t u);
 
 #define COMPAT_FLAG_QUERY         0       /** compat_flags operator: Query for a flag */
 #define COMPAT_FLAG_SET           (1<<0)  /** compat_flags operator: Set a compat flag */
tests/unit_tests/openvpn/test_argv.c +0 -18
index 8c90eb9c..4a3ba559 100644
@@ -13,24 +13,6 @@
 #include "argv.h"
 #include "buffer.h"
 
-/*
- * This is defined here to prevent #include'ing misc.h
- * which makes things difficult beyond any recognition
- */
-size_t
-adjust_power_of_2(size_t u)
-{
-    size_t ret = 1;
-
-    while (ret < u)
-    {
-        ret <<= 1;
-        assert(ret > 0);
-    }
-
-    return ret;
-}
-
 /* Defines for use in the tests and the mock parse_line() */
 #define PATH1       "/s p a c e"
 #define PATH2       "/foo bar/baz"
Signature · 1 line
2.11.0
Acked-by on v2 1/1
#4 lore raw

Thanks for sending v2 Steffan,

Quoted 10 lines · Steffan Karger

From: Steffan Karger <[email protected]...>

misc.c is a mess of incoherent functions, and is therefore included by virtually all our source files. That makes testing harder than it should be. As a first step of cleaning up misc.c, move adjust_power_of_2() to integer.h, which is a more suitable place for a function like this.

This allows us to remove the duplicate implementation from test_argv.c.

This change is quite simple and passes basic tests. Thanks also for adding explicit #include statements.

Cheers,

Signature · 1 line
Antonio Quartulli
#5 lore raw

Hi Antonio, Steffan,

Quoted 12 lines · Antonio Quartulli

Thanks for sending v2 Steffan,

Quoted 9 lines · Steffan Karger

From: Steffan Karger <[email protected]...>

misc.c is a mess of incoherent functions, and is therefore included by virtually all our source files. That makes testing harder than it should be. As a first step of cleaning up misc.c, move adjust_power_of_2() to integer.h, which is a more suitable place for a function like this.

This allows us to remove the duplicate implementation from test_argv.c.

Quoted 9 lines
Quoted 1 line

This change is quite simple and passes basic tests. Thanks also for adding explicit #include statements.

​Since the code is moved, would it be interesting to use a less greedy algorithm to do the same thing? I know the function is not used very often, so it does not look like it's necessary (it's a suggestion, not a commentary on your patch Steffan :))

For example, this code:

size_t
adjust_power_of_2(size_t v)
{
if (!v)
return 1;
v--;

v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;

if (sizeof(size_t) == 8)
v |= v >> 32;
v++;

return v;
}

does the exact same work on a 64 size_t but will be far faster than the loop-based one on many situation (the sizeof() test should be optimized away if it's never true, so the code will work even with a 32 bit size_t).

Why it works:
* if (v - 1) has 0 bits set, then v = 1 and the function will return 1 ((0 | 0 | ... | 0) + 1)
* if (v - 1) has at least one bit set (let's say it's bit n), then the first iteration will set bit (n-1). The next iteration will set bits (n-2) and (n-3). We goes on for a few steps. Before the last iteration, v has bits (n...(n-32)) set (with sizeof(size_t) == 8), so the very last operation fills the remaining bits and v has bits (n...0) set. Adding one to this value will yield the desired result.

Again, the function is not used extensively, so you can ignore this suggestion as it will not speed up openvpn at all :)

Quoted 3 lines

Cheers,
​​

​BR,

-- Emmanuel Deloget​

#6 lore raw
Quoted 22 lines · Emmanuel Deloget

Hi Antonio, Steffan,

Quoted 18 lines · Antonio Quartulli

Thanks for sending v2 Steffan,

Quoted 10 lines · Steffan Karger

From: Steffan Karger <[email protected]...>

misc.c is a mess of incoherent functions, and is therefore included by virtually all our source files. That makes testing harder than it should be. As a first step of cleaning up misc.c, move adjust_power_of_2() to integer.h, which is a more suitable place for a function like this.

This allows us to remove the duplicate implementation from test_argv.c.

This change is quite simple and passes basic tests. Thanks also for adding explicit #include statements.

Quoted 7 lines
Quoted 3 lines

Since the code is moved, would it be interesting to use a less greedy algorithm to do the same thing? I know the function is not used very often, so it does not look like it's necessary (it's a suggestion, not a commentary on your patch Steffan :))

My personal opinion: *never* mix code refactoring with functional changes (like what you are suggesting).

Therefore we'd still need another patch.

Quoted 35 lines

For example, this code:

size_t
adjust_power_of_2(size_t v)
{
if (!v)
return 1;
v--;

v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;

if (sizeof(size_t) == 8)
v |= v >> 32;
v++;

return v;
}

does the exact same work on a 64 size_t but will be far faster than the loop-based one on many situation (the sizeof() test should be optimized away if it's never true, so the code will work even with a 32 bit size_t).

Why it works:
* if (v - 1) has 0 bits set, then v = 1 and the function will return 1 ((0 | 0 | ... | 0) + 1)
* if (v - 1) has at least one bit set (let's say it's bit n), then the first iteration will set bit (n-1). The next iteration will set bits (n-2) and (n-3). We goes on for a few steps. Before the last iteration, v has bits (n...(n-32)) set (with sizeof(size_t) == 8), so the very last operation fills the remaining bits and v has bits (n...0) set. Adding one to this value will yield the desired result.

Quoted 2 lines

Again, the function is not used extensively, so you can ignore this suggestion as it will not speed up openvpn at all :)

yeah...not sure we need to make some code a bit "obscure" if there is really no need.

Still, I'd suggest to prepare a second patch and propose it over the list.

Cheers,

Signature · 1 line
Antonio Quartulli
#7 lore raw
Quoted 32 lines · Antonio Quartulli
Quoted 22 lines · Emmanuel Deloget

Hi Antonio, Steffan,

Quoted 18 lines · Antonio Quartulli

Thanks for sending v2 Steffan,

Quoted 10 lines · Steffan Karger

From: Steffan Karger <[email protected]...>

misc.c is a mess of incoherent functions, and is therefore included by virtually all our source files. That makes testing harder than it should be. As a first step of cleaning up misc.c, move adjust_power_of_2() to integer.h, which is a more suitable place for a function like this.

This allows us to remove the duplicate implementation from test_argv.c.

This change is quite simple and passes basic tests. Thanks also for adding explicit #include statements.

Quoted 7 lines
Quoted 3 lines

Since the code is moved, would it be interesting to use a less greedy algorithm to do the same thing? I know the function is not used very often, so it does not look like it's necessary (it's a suggestion, not a commentary on your patch Steffan :))

Quoted 4 lines

My personal opinion: *never* mix code refactoring with functional changes (like what you are suggesting).

Therefore we'd still need another patch.

Fair enough :)

Quoted 11 lines
Quoted 5 lines

<snip>

Again, the function is not used extensively, so you can ignore this suggestion as it will not speed up openvpn at all :)

yeah...not sure we need to make some code a bit "obscure" if there is really no need.

Still, I'd suggest to prepare a second patch and propose it over the list.

I'll wait until I see Steffan's patch on master . But as you said, /coda obscura est/ so the commit message will make that very clear.

Quoted 4 lines

Cheers,
--
Antonio Quartulli

BR,

-- Emmanuel Deloget

#8 lore raw
In reply to Antonio Quartulli

Hi,

Quoted 2 lines · Antonio Quartulli

yeah...not sure we need to make some code a bit "obscure" if there is really no need.

It's only obscure if you forget that 2^0+2^1+2^(n-1) = (2^n)-1... :-)

(Admittedly, it needed quite a bit of thinking at first glance)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#9 lore raw
In reply to Steffan Karger

Your patch has been applied to the master and release/2.4 branch.

(After some deliberation wrt release/2.4 - normally, a refactoring patch would not go to 2.4, but this improves our testing infrastructure and is not *rewriting* any code, just *moving* it - so I decided it makes much sense to have it in 2.4, and the stability risk is minimal)

commit 9fc0e963c757ffec3cc9fbf797fb7609f409c370 (master) commit 8b55a445385ce55244cb659b8cdd0dc3156550af (release/2.4)

Author: Steffan Karger
Date:   Wed Jun 21 23:10:43 2017 +0200
     Move adjust_power_of_2() to integer.h

     Signed-off-by: Steffan Karger <[email protected]...>
     Acked-by: Antonio Quartulli <[email protected]...>
     Message-Id: <[email protected]...>
     URL: https://www.mail-archive.com/[email protected]/msg14940.html
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering