New Makefile, day 1 solution (C)

This commit is contained in:
2021-12-03 16:58:08 +01:00
parent 7a1a200a73
commit ad032df481
25 changed files with 2728 additions and 194 deletions

85
2021/libsrc/bits.c Normal file
View File

@@ -0,0 +1,85 @@
/* bits.c - bits.h tests
*
* Copyright (C) 2021 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.htmlL>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include "bits.h"
#ifdef BIN_bits
#include <stdio.h>
#include <stdlib.h>
static inline int _popcount64(u64 n)
{
int count = 0;
while (n) {
count++;
n &= (n - 1);
}
return count;
}
static inline int _ctz64(u64 n)
{
return _popcount64((n & -n) - 1);
}
static inline int _clz64(u64 n)
{
u64 r, q;
r = (n > 0xFFFFFFFF) << 5; n >>= r;
q = (n > 0xFFFF) << 4; n >>= q; r |= q;
q = (n > 0xFF ) << 3; n >>= q; r |= q;
q = (n > 0xF ) << 2; n >>= q; r |= q;
q = (n > 0x3 ) << 1; n >>= q; r |= q;
r |= (n >> 1);
return __WORDSIZE - r - 1;
}
static inline int _ffs64(u64 n)
{
if (n == 0)
return (0);
return _popcount64(n ^ ~-n);
}
int main(int ac, char **av)
{
u64 u = 123, _tmp;
int curbit;
int base = 10;
debug_init(0);
if (ac > 2)
base = atoi(*(av+2));
if (ac > 1) {
u = strtoul(*(av+1), NULL, base);
printf("base=%d input=%#lx\n", base, u);
printf("popcount64(%lu) = %d/%d\n", u, popcount64(u), _popcount64(u));
printf("ctz64(%lu) = %d/%d\n", u, ctz64(u), _ctz64(u));
printf("clz64(%lu) = %d/%d\n", u, clz64(u), _clz64(u));
printf("ffs64(%lu) = %d/%d\n", u, ffs64(u), _ffs64(u));
printf("\n");
bit_for_each64(curbit, _tmp, u) {
printf("loop: curbit=%d tmp=%ld\n", curbit, _tmp);
}
printf("\n");
bit_for_each64_2(curbit, _tmp, u) {
printf("loop2: curbit=%d tmp=%ld\n", curbit, _tmp);
}
}
return 0;
}
#endif /* BIN_bits */

BIN
2021/libsrc/bits.o Normal file

Binary file not shown.

106
2021/libsrc/debug.c Normal file
View File

@@ -0,0 +1,106 @@
/* debug.c - debug/log management
*
* Copyright (C) 2021 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.htmlL>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "debug.h"
#define NANOSEC 1000000000 /* nano sec in sec */
#define MILLISEC 1000000 /* milli sec in sec */
static s64 timer_start; /* in nanosecond */
static u32 debug_level=0;
void debug_level_set(u32 level)
{
debug_level = level;;
log(0, "debug level set to %u\n", level);
}
void debug_init(u32 level)
{
struct timespec timer;
debug_level_set(level);
if (!clock_gettime(CLOCK_MONOTONIC, &timer)) {
timer_start = timer.tv_sec * NANOSEC + timer.tv_nsec;
}
else {
timer_start = 0;
}
log(0, "timer started.\n");
}
inline static s64 timer_elapsed()
{
struct timespec timer;
clock_gettime(CLOCK_MONOTONIC, &timer);
return (timer.tv_sec * NANOSEC + timer.tv_nsec) - timer_start;
}
/* void debug - log function
* @timestamp : boolean
* @indent : indent level (2 spaces each)
* @src : source file/func name (or NULL)
* @line : line number
*/
void debug(u32 level, bool timestamp, u32 indent, const char *src,
u32 line, const char *fmt, ...)
{
if (level > debug_level)
return;
va_list ap;
if (indent)
printf("%*s", 2*(indent-1), "");
if (timestamp) {
s64 diff = timer_elapsed();
printf("%ld.%03ld ", diff/NANOSEC, (diff/1000000)%1000);
printf("%010ld ", diff);
}
if (src) {
if (line)
printf("[%s:%u] ", src, line);
else
printf("[%s] ", src);
}
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
#ifdef BIN_debug
#include <unistd.h>
int main()
{
int foo=1;
debug_init(5);
log(0, "log0=%d\n", foo++);
log(1, "log1=%d\n", foo++);
log(2, "log2=%d\n", foo++);
log_i(2, "log_i 2=%d\n", foo++);
log_i(5, "log_i 5=%d\n", foo++);
log_i(6, "log_i 6=%d\n", foo++);
log_it(4, "log_it 4=%d\n", foo++);
log_f(1, "log_f 5=%d\n", foo++);
}
#endif

BIN
2021/libsrc/debug.o Normal file

Binary file not shown.

180
2021/libsrc/pool.c Normal file
View File

@@ -0,0 +1,180 @@
/* pool.c - A simple pool manager.
*
* Copyright (C) 2021 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.htmlL>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
/*
#include <stdbool.h>
#include <ctype.h>
*/
#include <stddef.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include "list.h"
#include "pool.h"
#include "debug.h"
#include "bits.h"
void pool_stats(pool_t *pool)
{
if (pool) {
# ifdef DEBUG_POOL
log_f(1, "[%s] pool [%p]: avail:%u alloc:%u grow:%u eltsize:%lu\n",
pool->name, (void *)pool, pool->available, pool->allocated,
pool->growsize, pool->eltsize);
# endif
}
}
pool_t *pool_init(const char *name, u32 growsize, size_t eltsize)
{
pool_t *pool;
# ifdef DEBUG_POOL
log_f(1, "name=[%s] growsize=%u eltsize=%lu\n",
name, growsize, eltsize);
# endif
/* we need at least this space in struct */
if (eltsize < sizeof (struct list_head))
return NULL;
if ((pool = malloc(sizeof (*pool)))) {
pool->name = strdup(name);
pool->growsize = growsize;
pool->eltsize = eltsize;
pool->available = 0;
pool->allocated = 0;
INIT_LIST_HEAD(&pool->head);
}
return pool;
}
static u32 _pool_add(pool_t *pool, struct list_head *elt)
{
# ifdef DEBUG_POOL
log_f(10, "pool=%p &head=%p elt=%p off1=%lu off2=%lu\n",
(void *)pool,
(void *)&pool->head,
(void *)elt,
(void *)&pool->head-(void *)pool,
offsetof(pool_t, head));
# endif
list_add(elt, &pool->head);
return ++pool->available;
}
u32 pool_add(pool_t *pool, void *elt)
{
return _pool_add(pool, elt);
}
static struct list_head *_pool_get(pool_t *pool)
{
struct list_head *res = pool->head.next;
pool->available--;
list_del(res);
return res;
}
void *pool_get(pool_t *pool)
{
if (!pool)
return NULL;
if (!pool->available) {
void *alloc = malloc(pool->eltsize * pool->growsize);
void *cur;
u32 i;
# ifdef DEBUG_POOL
log_f(1, "[%s]: growing pool from %u to %u elements.\n",
pool->name,
pool->allocated,
pool->allocated + pool->growsize);
# endif
if (!alloc)
return NULL;
# ifdef DEBUG_POOL
log_f(5, " (old=%u)\n", pool->allocated);
# endif
pool->allocated += pool->growsize;
# ifdef DEBUG_POOL
log_f(5, " (new=%u)\n", pool->allocated);
# endif
for (i = 0; i < pool->growsize; ++i) {
cur = alloc + i * pool->eltsize;
# ifdef DEBUG_POOL
log_f(5, "alloc=%p cur=%p\n", alloc, cur);
# endif
_pool_add(pool, (struct list_head *)cur);
}
pool_stats(pool);
}
/* this is the effective address if the object (and also the
* pool list_head address)
*/
return _pool_get(pool);
}
#ifdef BIN_pool
struct d {
u16 data1;
char c;
struct list_head list;
};
static LIST_HEAD (head);
int main(int ac, char**av)
{
pool_t *pool;
int total;
int action=0;
u16 icur=0;
char ccur='z';
struct d *elt;
debug_init(3);
log_f(1, "%s: sizeof(d)=%lu sizeof(*d)=%lu off=%lu\n", *av, sizeof(elt),
sizeof(*elt), offsetof(struct d, list));
if ((pool = pool_init("dummy", 3, sizeof(*elt)))) {
pool_stats(pool);
for (int cur=1; cur<ac; ++cur) {
total = atoi(av[cur]);
if (action == 0) { /* add elt to list */
log_f(2, "adding %d elements\n", total);
for (int i = 0; i < total; ++i) {
elt = pool_get(pool);
elt->data1 = icur++;
elt->c = ccur--;
list_add(&elt->list, &head);
}
pool_stats(pool);
action = 1;
} else { /* remove one elt from list */
log_f(2, "deleting %d elements\n", total);
for (int i = 0; i < total; ++i) {
if (!list_empty(&head)) {
elt = list_last_entry(&head, struct d, list);
printf("elt=[%d, %c]\n", elt->data1, elt->c);
list_del(&elt->list);
pool_add(pool, elt);
}
}
pool_stats(pool);
action = 0;
}
}
}
pool_stats(pool);
}
#endif

BIN
2021/libsrc/pool.o Normal file

Binary file not shown.