diff options
Diffstat (limited to 'ccan/alignof')
| l--------- | ccan/alignof/LICENSE | 1 | ||||
| -rw-r--r-- | ccan/alignof/_info | 51 | ||||
| -rw-r--r-- | ccan/alignof/alignof.h | 20 | ||||
| -rw-r--r-- | ccan/alignof/test/run.c | 61 |
4 files changed, 133 insertions, 0 deletions
diff --git a/ccan/alignof/LICENSE b/ccan/alignof/LICENSE new file mode 120000 index 0000000..b7951da --- /dev/null +++ b/ccan/alignof/LICENSE @@ -0,0 +1 @@ +../../licenses/CC0
\ No newline at end of file diff --git a/ccan/alignof/_info b/ccan/alignof/_info new file mode 100644 index 0000000..ee2b7ad --- /dev/null +++ b/ccan/alignof/_info @@ -0,0 +1,51 @@ +#include "config.h" +#include <stdio.h> +#include <string.h> + +/** + * alignof - ALIGNOF() macro to determine alignment of a type. + * + * Many platforms have requirements that certain types must be aligned + * to certain address boundaries, such as ints needing to be on 4-byte + * boundaries. Attempting to access variables with incorrect + * alignment may cause performance loss or even program failure (eg. a + * bus signal). + * + * There are times which it's useful to be able to programatically + * access these requirements, such as for dynamic allocators. + * + * Example: + * #include <stdio.h> + * #include <stdlib.h> + * #include <ccan/alignof/alignof.h> + * + * // Output contains "ALIGNOF(char) == 1" + * // Will also print out whether an onstack char array can hold a long. + * int main(void) + * { + * char arr[sizeof(int)]; + * + * printf("ALIGNOF(char) == %zu\n", ALIGNOF(char)); + * if ((unsigned long)arr % ALIGNOF(int)) { + * printf("arr %p CANNOT hold an int\n", arr); + * exit(1); + * } else { + * printf("arr %p CAN hold an int\n", arr); + * exit(0); + * } + * } + * + * License: CC0 (Public domain) + * Author: Rusty Russell <rusty@rustcorp.com.au> + */ +int main(int argc, char *argv[]) +{ + if (argc != 2) + return 1; + + if (strcmp(argv[1], "depends") == 0) { + return 0; + } + + return 1; +} diff --git a/ccan/alignof/alignof.h b/ccan/alignof/alignof.h new file mode 100644 index 0000000..9a02f18 --- /dev/null +++ b/ccan/alignof/alignof.h @@ -0,0 +1,20 @@ +/* CC0 (Public domain) - see LICENSE file for details */ +#ifndef CCAN_ALIGNOF_H +#define CCAN_ALIGNOF_H +#include "config.h" + +/** + * ALIGNOF - get the alignment of a type + * @t: the type to test + * + * This returns a safe alignment for the given type. + */ +#if HAVE_ALIGNOF +/* A GCC extension. */ +#define ALIGNOF(t) __alignof__(t) +#else +/* Alignment by measuring structure padding. */ +#define ALIGNOF(t) ((char *)(&((struct { char c; t _h; } *)0)->_h) - (char *)0) +#endif + +#endif /* CCAN_ALIGNOF_H */ diff --git a/ccan/alignof/test/run.c b/ccan/alignof/test/run.c new file mode 100644 index 0000000..5e3216f --- /dev/null +++ b/ccan/alignof/test/run.c @@ -0,0 +1,61 @@ +#include <ccan/alignof/alignof.h> +#include <stdlib.h> +#include <stddef.h> +#include <ccan/tap/tap.h> + +/* Alignment is remarkably difficult to test. The rules may be more + * complex than ALIGNOF() can know: eg. on i386 __alignof__(double) == 8, but + * __alignof__(struct containing double) == 4. + * + * Technically, we can only test that we give *at least* the alignment which + * naturally occurs, and that accesses work. + * + * For the moment, we work around double. */ +struct lots_of_types +{ + char c; + short s; + char c2; + int i; + char c3; + float f; + char c4; + double d; + char c5; +}; + +int main(void) +{ + struct lots_of_types lots_of_types, *lp = malloc(sizeof(*lp)); + char c; + short s; + char c2; + int i; + char c3; + float f; + char c4; + double d; + + /* Make sure we use all the variables. */ + c = c2 = c3 = c4 = 0; + + plan_tests(15); + ok1((unsigned long)&c % ALIGNOF(char) == 0); + ok1((unsigned long)&s % ALIGNOF(short) == 0); + ok1((unsigned long)&i % ALIGNOF(int) == 0); + ok1((unsigned long)&f % ALIGNOF(float) == 0); + ok1((unsigned long)&d % ALIGNOF(double) == 0); + + ok1((unsigned long)&lots_of_types.c % ALIGNOF(char) == 0); + ok1((unsigned long)&lots_of_types.s % ALIGNOF(short) == 0); + ok1((unsigned long)&lots_of_types.i % ALIGNOF(int) == 0); + ok1((unsigned long)&lots_of_types.f % ALIGNOF(float) == 0); + ok1(offsetof(struct lots_of_types, d) % ALIGNOF(double) == 0); + + ok1((unsigned long)&lp->c % ALIGNOF(char) == 0); + ok1((unsigned long)&lp->s % ALIGNOF(short) == 0); + ok1((unsigned long)&lp->i % ALIGNOF(int) == 0); + ok1((unsigned long)&lp->f % ALIGNOF(float) == 0); + ok1((unsigned long)&lp->d % ALIGNOF(double) == 0); + exit(exit_status()); +} |
