summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2017-02-21 12:04:57 +0100
committerJérémy Zurcher <jeremy@asynk.ch>2017-02-21 12:04:57 +0100
commit260131c35f7f1b68b66e5b29916ec05a38c4ca56 (patch)
treee00a2df2f76475ceaf56e9fbdb49757d4159c763
parentc3892aedf180a9fbc0742f5e1829346985c4a6b0 (diff)
downloadshare-260131c35f7f1b68b66e5b29916ec05a38c4ca56.zip
share-260131c35f7f1b68b66e5b29916ec05a38c4ca56.tar.gz
c : add bit_array, bit_compose, malloc_hook
-rw-r--r--c/bit_array.c105
-rw-r--r--c/bit_compose.c32
-rwxr-xr-xc/do6
-rw-r--r--c/malloc_hook.c37
4 files changed, 180 insertions, 0 deletions
diff --git a/c/bit_array.c b/c/bit_array.c
new file mode 100644
index 0000000..26c05f6
--- /dev/null
+++ b/c/bit_array.c
@@ -0,0 +1,105 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+typedef uint32_t bitfield_t;
+enum { BITFIELD_BITS = sizeof(bitfield_t) * 8 };
+
+static inline int bindex(int b) { return b / BITFIELD_BITS; }
+static inline int boffset(int b) { return b % BITFIELD_BITS; }
+#define bptr(st) (&((st)->bits))
+
+struct _Bits
+{
+ uint32_t nw;
+ bitfield_t bits;
+};
+
+typedef struct _Bits * Bits;
+
+static inline Bits bits_alloc(int n)
+{
+ uint32_t nw = (n / BITFIELD_BITS);
+ if (nw * BITFIELD_BITS < n) nw += 1;
+ int sz = sizeof(int) + (nw * sizeof(bitfield_t));
+ /* printf("wants %d bits : alloc %d bytes (1 uint32_t[%lu] + %d bitfields[%lu])\n", n, sz, sizeof(uint32_t), nw, (nw * sizeof(bitfield_t))); */
+ Bits b = calloc(1, sz);
+ /* memset(b, 0, sz); */
+ b->nw = nw;
+ return b;
+}
+
+static inline void bits_free(Bits bits)
+{
+ free(bits);
+}
+
+static inline void set_bit(Bits bits, int b)
+{
+ bptr(bits)[bindex(b)] |= (bitfield_t)(1 << boffset(b));
+}
+
+static inline void reset_bit(Bits bits, int b)
+{
+ bptr(bits)[bindex(b)] &= ~(1 << boffset(b));
+}
+
+static inline int get_bit(Bits bits, int b)
+{
+ int of = boffset(b);
+ return (bptr(bits)[bindex(b)] & (1 << of)) >> of;
+}
+
+static inline Bits bits_copy(Bits dst, Bits src)
+{
+ if (dst->nw != src->nw) return 0;
+ return memcpy(&dst->bits, &src->bits, (sizeof(bitfield_t) * src->nw));
+}
+
+static void assert(int value, int expected, char*msg)
+{
+ if (value != expected) {
+ fprintf(stderr, "Error %s\n", msg);
+ exit(1);
+ }
+}
+
+int main(int argc, char **argv, char **env)
+{
+ printf("bits in an bitfield_t : %d\n", BITFIELD_BITS);
+ Bits a = bits_alloc(33);
+ Bits b = bits_alloc(33);
+ set_bit(a, 31);
+ set_bit(a, 32);
+ set_bit(a, 33);
+ assert(get_bit(a, 30), 0, "bit 30 is not 0");
+ assert(get_bit(a, 31), 1, "bit 31 is not 1");
+ assert(get_bit(a, 32), 1, "bit 32 is not 1");
+ assert(get_bit(a, 33), 1, "bit 33 is not 1");
+ assert(get_bit(a, 34), 0, "bit 34 is not 0");
+ reset_bit(a, 32);
+ assert(get_bit(a, 30), 0, "bit 30 is not 0");
+ assert(get_bit(a, 31), 1, "bit 31 is not 1");
+ assert(get_bit(a, 32), 0, "bit 32 is not 0");
+ assert(get_bit(a, 33), 1, "bit 33 is not 1");
+ assert(get_bit(a, 34), 0, "bit 34 is not 0");
+ set_bit(a, 32);
+ reset_bit(a, 33);
+ reset_bit(a, 31);
+ assert(get_bit(a, 30), 0, "bit 30 is not 0");
+ assert(get_bit(a, 31), 0, "bit 31 is not 0");
+ assert(get_bit(a, 32), 1, "bit 32 is not 1");
+ assert(get_bit(a, 33), 0, "bit 33 is not 0");
+ assert(get_bit(a, 34), 0, "bit 34 is not 0");
+ bits_copy(b, a);
+ assert(get_bit(b, 30), 0, "bit 30 is not 0");
+ assert(get_bit(b, 31), 0, "bit 31 is not 0");
+ assert(get_bit(b, 32), 1, "bit 32 is not 1");
+ assert(get_bit(b, 33), 0, "bit 33 is not 0");
+ assert(get_bit(b, 34), 0, "bit 34 is not 0");
+ bits_free(a);
+ bits_free(b);
+ printf("Success\n");
+ return 0;
+}
diff --git a/c/bit_compose.c b/c/bit_compose.c
new file mode 100644
index 0000000..bd250db
--- /dev/null
+++ b/c/bit_compose.c
@@ -0,0 +1,32 @@
+#include <stdint.h>
+#include <stdio.h>
+
+typedef union __attribute__ ((__packed__))
+{
+ struct __attribute__ ((__packed__))
+ {
+ unsigned int table_id : 11;
+ unsigned int int_table_id : 11;
+ unsigned int entry_id : 12;
+ unsigned int generation : 30;
+ };
+ uintptr_t i;
+} BITS;
+
+uintptr_t compose(uintptr_t a, uintptr_t b, uintptr_t c, uintptr_t d)
+{
+ BITS i;
+ i.table_id = a;
+ i.int_table_id = b;
+ i.entry_id = c;
+ i.generation = d;
+ return i.i;
+}
+
+int main(int argc, char **argv, char **env)
+{
+ uintptr_t t = compose(666,777,888,999);
+ printf("%d %d %d %d -> 0x%lu\n", 666, 777, 888, 999, t);
+
+ return 0;
+}
diff --git a/c/do b/c/do
new file mode 100755
index 0000000..661ebd2
--- /dev/null
+++ b/c/do
@@ -0,0 +1,6 @@
+#! /bin/sh
+for c in *.c
+do
+ echo "############" && clang -pedantic -Wall -ldl $c -o ./bin && ./bin
+done
+rm ./bin
diff --git a/c/malloc_hook.c b/c/malloc_hook.c
new file mode 100644
index 0000000..aa22379
--- /dev/null
+++ b/c/malloc_hook.c
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#define __USE_GNU
+#include <dlfcn.h>
+
+typedef void* (*real_malloc_t) (size_t);
+
+static real_malloc_t real_malloc = NULL;
+
+static void __mtrace_init(void)
+{
+ real_malloc = (real_malloc_t) dlsym(RTLD_NEXT, "malloc");
+ if (NULL == real_malloc) {
+ fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
+ return;
+ }
+}
+
+void *malloc(size_t size)
+{
+ if(real_malloc == NULL)
+ __mtrace_init();
+
+ void *p = NULL;
+ fprintf(stderr, "malloc(%zu) = ", size);
+ p = real_malloc(size);
+ fprintf(stderr, "%p\n", p);
+ return p;
+}
+
+
+int main(int argc, char **argv, char **env)
+{
+ void * nothing = malloc(666);
+ free(nothing);
+}