Last active
August 31, 2019 20:27
-
-
Save adrianparvino/1d3f1fabb8262735aa8d3748bf8231b8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef BUF_HANDLE_H | |
#define BUF_HANDLE_H | |
#include<stdlib.h> | |
#include<stdint.h> | |
struct buf_handle | |
{ | |
uint8_t *tail; | |
ssize_t remaining; | |
uint16_t byte; | |
}; | |
struct buf_handle *buf_handle_new(uint8_t *buf); | |
void buf_handle_close(struct buf_handle *handle); | |
void buf_handle_write(struct buf_handle *handle, | |
uint32_t x, ssize_t bits); | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "buf_handle.h" | |
#include<stdlib.h> | |
#include<stdio.h> | |
#include <assert.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <time.h> | |
#include <stdio.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdbool.h> | |
#include<string.h> | |
#define likely(x) __builtin_expect((x),1) | |
#define unlikely(x) __builtin_expect((x),0) | |
static inline uint16_t | |
movl(uint16_t x, uint8_t s) | |
{ | |
return (x & 0xff00) | s; | |
} | |
static inline uint16_t | |
movu(uint16_t x, uint8_t s) | |
{ | |
return (s << 8) | (x & 0xff); | |
} | |
static inline uint16_t | |
rot16l(uint16_t x, ssize_t s) | |
{ | |
return x << s | x >> (16 - s); | |
} | |
static inline uint16_t | |
rot16r(uint16_t x, ssize_t s) | |
{ | |
return x >> s | x << (16 - s); | |
} | |
static inline uint8_t | |
rot8r(uint8_t x, ssize_t s) | |
{ | |
return x >> s | x << (8 - s); | |
} | |
struct buf_handle * | |
buf_handle_new(uint8_t *buf) | |
{ | |
struct buf_handle *buf_handle = malloc(sizeof *buf_handle); | |
buf_handle->tail = buf; | |
buf_handle->remaining = 8; | |
buf_handle->byte = 0; | |
return buf_handle; | |
} | |
void | |
buf_handle_close(struct buf_handle *handle) | |
{ | |
*handle->tail = handle->byte; | |
free(handle); | |
} | |
void | |
buf_handle_write(struct buf_handle *handle, | |
uint32_t x, ssize_t bits) | |
{ | |
if (handle->remaining <= bits) | |
{ | |
handle->byte = movl(handle->byte, x); | |
handle->byte = rot16r(handle->byte, handle->remaining); | |
x >>= handle->remaining; | |
bits -= handle->remaining; | |
*handle->tail++ = handle->byte >> 8; | |
handle->remaining = 8; | |
handle->byte = 0; | |
switch (bits/8) | |
{ | |
case 3: | |
*handle->tail++ = x; | |
x >>= 8; | |
case 2: | |
*handle->tail++ = x; | |
x >>= 8; | |
case 1: | |
*handle->tail++ = x; | |
x >>= 8; | |
} | |
bits %= 8; | |
} | |
handle->byte = movl(handle->byte, x); | |
handle->byte = rot16r(handle->byte, bits); | |
handle->remaining -= bits; | |
} | |
typedef struct { | |
uint8_t *buf; | |
size_t offset; | |
uint8_t byte; | |
size_t bit; | |
} rwb; | |
void wbit(rwb *ctx, uint32_t x, int bits) | |
{ | |
for (int i = 0; i < bits; i++) { | |
ctx->byte |= (x & 1) << ctx->bit++; | |
x >>= 1; | |
if (ctx->bit >= 8) { | |
ctx->buf[ctx->offset++] = ctx->byte; | |
ctx->byte = ctx->bit = 0; | |
} | |
} | |
} | |
void wflush(rwb *ctx) | |
{ | |
ctx->buf[ctx->offset++] = ctx->byte; | |
ctx->byte = ctx->bit = 0; | |
} | |
int main(int argc, char *argv[argc]) | |
{ | |
const bool show_induvidual = true; | |
const int runs = 128 * 16; | |
uint64_t total = 0; | |
uint8_t *buf = malloc(256*4); | |
uint8_t *buf2 = malloc(256*4); | |
uint8_t *lengths = calloc(256, sizeof(int)); | |
uint32_t *codes = calloc(256, sizeof(uint32_t)); | |
rwb wctx = { | |
.buf = buf2, | |
.offset = 0, | |
.byte = 0, | |
.bit = 0, | |
}; | |
for (int run = 0; run < runs; run++) { | |
srand(time(NULL)); | |
for (int i = 0; i < 256; i++) { | |
lengths[i] = rand() % ((32 + 1) - 1) + 1; | |
} | |
int fd = open("/dev/urandom", O_RDONLY); | |
read(fd, codes, 256 * sizeof(uint32_t)); | |
close(fd); | |
clock_t start = clock(); | |
for (int j = 0; j < 1024; j++) { | |
wctx.offset = 0; | |
struct buf_handle *handle = buf_handle_new(buf); | |
for (int i = 0; i < 256; i++) { | |
buf_handle_write(handle, codes[i], lengths[i]); | |
// wbit(&wctx, codes[i], lengths[i]); | |
} | |
buf_handle_close(handle); | |
wflush(&wctx); | |
// assert(memcmp(buf, buf2, 32) == 0); | |
} | |
clock_t runtime = clock() - start; | |
if (show_induvidual) | |
printf("%lu\n", runtime); | |
total += runtime; | |
} | |
free(buf); | |
free(lengths); | |
free(codes); | |
printf("average: %f\n", (double)total / runs); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment