f3/libutils.c
2015-09-02 10:43:36 -04:00

97 lines
1.4 KiB
C

#include <stdlib.h> /* For strtoll(). */
#include "libutils.h"
/* Count the number of 1 bits. */
static int pop(uint64_t x)
{
int n = 0;
while (x) {
n++;
x = x & (x - 1);
}
return n;
}
int ilog2(uint64_t x)
{
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
x = x | (x >> 32);
return pop(x) - 1;
}
/* Least power of 2 greater than or equal to x. */
static uint64_t clp2(uint64_t x)
{
x = x - 1;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
x = x | (x >> 32);
return x + 1;
}
int ceiling_log2(uint64_t x)
{
return ilog2(clp2(x));
}
void *align_mem(void *p, int order)
{
uintptr_t ip = (uintptr_t)p;
uintptr_t head = align_head(order);
return (void *)( (ip + head) & ~head );
}
long long arg_to_ll_bytes(const struct argp_state *state,
const char *arg)
{
char *end;
long long ll = strtoll(arg, &end, 0);
if (end == arg)
argp_error(state, "An integer must be provided");
/* Deal with units. */
switch (*end) {
case 's':
case 'S': /* Sectors */
ll <<= 9;
end++;
break;
case 'k':
case 'K': /* KB */
ll <<= 10;
end++;
break;
case 'm':
case 'M': /* MB */
ll <<= 20;
end++;
break;
case 'g':
case 'G': /* GB */
ll <<= 30;
end++;
break;
case 't':
case 'T': /* TB */
ll <<= 40;
end++;
break;
}
if (*end)
argp_error(state, "`%s' is not an integer", arg);
return ll;
}