Commit 4e7b51c9 authored by Andreas Schmidt's avatar Andreas Schmidt

Migrate performance enhancements from other branch.

parent a7483af8
Pipeline #798 passed with stages
in 1 minute and 7 seconds
......@@ -5,7 +5,8 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_CXX_FLAGS "-fstack-protector -fstack-protector-all -Wall -pedantic " )
SET(CMAKE_C_FLAGS "-O2 -Wall -std=c11 -D_XOPEN_SOURCE=600" )
set(CMAKE_CXX_FLAGS "-fstack-protector -fstack-protector-all -Wall -std=c++11 -D_XOPEN_SOURCE=600" )
set(CMAKE_CXX_FLAGS_DEBUG "-O2 -Wall -ggdb" )
set(CMAKE_CXX_FLAGS_RELEASE "-Os -Wall" )
......
......@@ -7,7 +7,7 @@
#include "block.h"
#include "codingParams.h"
void gather_redundancy_packets(const PrrtBlock *block_ptr, gf *const *fec, int *idx_p)
static void gather_redundancy_packets(const PrrtBlock *block_ptr, gf *const *fec, int *idx_p)
{
uint32_t i;
uint32_t m = 0;
......@@ -27,7 +27,7 @@ void gather_redundancy_packets(const PrrtBlock *block_ptr, gf *const *fec, int *
}
}
void gather_data_packets(PrrtBlock *block_ptr, gf *const *fec, int *idx_p)
static void gather_data_packets(PrrtBlock *block_ptr, gf *const *fec, int *idx_p)
{
LIST_FOREACH(block_ptr->dataPackets, first, next, current) {
PrrtPacket *packet = current->value;
......@@ -36,7 +36,7 @@ void gather_data_packets(PrrtBlock *block_ptr, gf *const *fec, int *idx_p)
}
}
void clear_list(gf *const *src, uint8_t k)
static void clear_list(gf *const *src, uint8_t k)
{
int j = 0;
for(j = 0; j < k; j++) {
......
......@@ -10,19 +10,19 @@
#include "packet.h"
#include "clock.h"
void *encode_general_header(void *buf_ptr, const PrrtPacket *packet);
static void *encode_general_header(void *buf_ptr, const PrrtPacket *packet);
void *encode_data_header(void *buf_ptr, const void *payload);
static void *encode_data_header(void *buf_ptr, const void *payload);
void *encode_redundancy_header(void *buf_ptr, const void *payload);
static void *encode_redundancy_header(void *buf_ptr, const void *payload);
void *encode_feedback_header(void *buf_ptr, const void *payload);
static void *encode_feedback_header(void *buf_ptr, const void *payload);
void *decode_data_header(void *dstBuffer, const void *srcBuffer);
static void *decode_data_header(void *dstBuffer, const void *srcBuffer);
void *decode_redundancy_header(void *dstBuffer, const void *srcBuffer);
static void *decode_redundancy_header(void *dstBuffer, const void *srcBuffer);
void *decode_feedback_header(void *dstBuffer, const void *srcBuffer);
static void *decode_feedback_header(void *dstBuffer, const void *srcBuffer);
prrtPacketType_t PrrtPacket_type(PrrtPacket *packet_ptr)
{
......@@ -131,7 +131,7 @@ PrrtPacket *PrrtPacket_copy(PrrtPacket *original)
return NULL;
}
PrrtPacket *create_header(uint8_t priority, prrtSequenceNumber_t seqno, prrtPacketLength_t size, uint8_t type, uint8_t index)
static PrrtPacket *create_header(uint8_t priority, prrtSequenceNumber_t seqno, prrtPacketLength_t size, uint8_t type, uint8_t index)
{
PrrtPacket *packet = calloc(1, sizeof(PrrtPacket));
check_mem(packet);
......@@ -504,4 +504,4 @@ PrrtPacket *PrrtPacket_create_feedback_packet(uint8_t priority, uint8_t index, p
error:
return NULL;
}
\ No newline at end of file
}
......@@ -9,7 +9,7 @@
#include "../socket.h"
#include "dataReceiver.h"
void retrieve_data_blocks(PrrtSocket *sock_ptr, prrtSequenceNumber_t base_seqno, uint8_t k, const PrrtBlock *block)
static void retrieve_data_blocks(PrrtSocket *sock_ptr, prrtSequenceNumber_t base_seqno, uint8_t k, const PrrtBlock *block)
{
List *res = List_create();
......@@ -27,7 +27,7 @@ void retrieve_data_blocks(PrrtSocket *sock_ptr, prrtSequenceNumber_t base_seqno,
List_destroy(res);
}
void decode_block(PrrtSocket *socket, PrrtBlock *block)
static void decode_block(PrrtSocket *socket, PrrtBlock *block)
{
if(block != NULL && PrrtBlock_decode_ready(block)) {
check(PrrtBlock_decode(block), "Decoding failed");
......@@ -54,7 +54,7 @@ void decode_block(PrrtSocket *socket, PrrtBlock *block)
PERROR("Decoding failed.%s", "")
}
bool send_feedback(const PrrtSocket *sock_ptr, struct sockaddr_in remote)
static bool send_feedback(const PrrtSocket *sock_ptr, struct sockaddr_in remote)
{
uint16_t remote_port = ntohs(remote.sin_port);
char *remote_host = inet_ntoa(remote.sin_addr);
......@@ -94,7 +94,7 @@ bool send_feedback(const PrrtSocket *sock_ptr, struct sockaddr_in remote)
return false;
}
void handle_data_packet(PrrtSocket *sock_ptr, PrrtPacket *packet, struct sockaddr_in remote)
static void handle_data_packet(PrrtSocket *sock_ptr, PrrtPacket *packet, struct sockaddr_in remote)
{
PrrtPacketDataPayload *payload = packet->payload;
......@@ -146,7 +146,7 @@ void handle_data_packet(PrrtSocket *sock_ptr, PrrtPacket *packet, struct sockadd
return;
}
void handle_redundancy_packet(PrrtSocket *socket, PrrtPacket *packet)
static void handle_redundancy_packet(PrrtSocket *socket, PrrtPacket *packet)
{
PrrtPacketRedundancyPayload *redundancyPayload = packet->payload;
......
......@@ -11,7 +11,7 @@
#include "dataTransmitter.h"
bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet)
static bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet)
{
uint8_t buf[MAX_PAYLOAD_LENGTH];
memset(buf, 0, sizeof(buf));
......@@ -24,19 +24,8 @@ bool send_packet(PrrtSocket *sock_ptr, PrrtPacket *packet)
LIST_FOREACH(sock_ptr->receivers, first, next, cur) {
PrrtReceiver *recv = cur->value;
struct hostent *hp;
struct sockaddr_in targetaddr;
memset((char *) &targetaddr, 0, sizeof(targetaddr));
targetaddr.sin_family = AF_INET;
targetaddr.sin_port = htons(recv->port);
hp = gethostbyname(recv->host_name);
check(hp != NULL, "Could not resolve host '%s'.", recv->host_name)
memcpy((void *) &targetaddr.sin_addr, hp->h_addr_list[0], (size_t) hp->h_length);
// TODO: [LATENCY] By knowing the time encoding etc. that happens upfront, one could make an adjustment here.
check(sendto(sock_ptr->dataSocketFd, buf, length, 0, (struct sockaddr *) &targetaddr, sizeof(targetaddr)) ==
check(sendto(sock_ptr->dataSocketFd, buf, length, 0, recv->ai->ai_addr, recv->ai->ai_addrlen) ==
length, "Sendto failed.");
usleep(1);
}
......@@ -61,17 +50,14 @@ void *send_data_loop(void *ptr)
while(1) {
check(pthread_mutex_lock(&sock_ptr->outQueueFilledMutex) == 0, "Lock failed.");
while(List_count(sock_ptr->outQueue) == 0) {
check(pthread_mutex_lock(&sock_ptr->closingMutex) == 0, "Lock failed.");
if(sock_ptr->closing) {
if (atomic_load_explicit(&sock_ptr->closing, memory_order_acquire)) {
PrrtCodingParams_destroy(cpar);
if(block != NULL) {
PrrtBlock_destroy(block);
}
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
check(pthread_mutex_unlock(&sock_ptr->outQueueFilledMutex) == 0, "Unlock failed.");
return NULL;
}
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
check(pthread_cond_wait(&sock_ptr->outQueueFilledCv, &sock_ptr->outQueueFilledMutex) == 0,
"Cond wait failed.");
}
......
......@@ -10,7 +10,7 @@
#include "../socket.h"
#include "feedbackReceiver.h"
void handle_feedback(PrrtSocket *prrtSocket, const size_t length)
static void handle_feedback(PrrtSocket *prrtSocket, const size_t length)
{
char bufin[MAX_PAYLOAD_LENGTH];
PrrtPacket *prrtPacket = NULL;
......@@ -50,18 +50,14 @@ void *receive_feedback_loop(void *ptr)
{
PrrtSocket *sock_ptr = ptr;
check(pthread_mutex_lock(&sock_ptr->closingMutex) == 0, "Lock failed.");
while(sock_ptr->closing == false) {
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
while (!atomic_load_explicit(&sock_ptr->closing, memory_order_acquire)) {
handle_feedback(sock_ptr, MAX_PAYLOAD_LENGTH);
usleep(1);
check(pthread_mutex_lock(&sock_ptr->closingMutex) == 0, "Lock failed.");
}
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
return NULL;
error:
PERROR("Feedback reception failed.%s","");
return NULL;
}
\ No newline at end of file
// error:
// PERROR("Feedback reception failed.%s","");
// return NULL;
}
......@@ -8,18 +8,34 @@ PrrtReceiver *PrrtReceiver_create(const char *host, uint16_t port)
PrrtReceiver *recv = calloc(1, sizeof(PrrtReceiver));
check_mem(recv);
recv->host_name = strdup(host);
check_mem(recv->host_name);
recv->port = port;
struct addrinfo *info;
struct addrinfo hints;
char portstr[sizeof(port)*8+1];
snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port);
memset(&hints, 0x0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
check(0 == getaddrinfo(host, portstr, &hints, &info), "getaddrinfo");
recv->ai = info;
return recv;
error:
if(recv != NULL) { free(recv); }
PERROR("Memory issue.%s","");
if (recv != NULL) {
free((void *) recv->host_name);
free(recv);
}
//PERROR("Memory issue.%s","");
return NULL;
}
bool PrrtReceiver_destroy(PrrtReceiver *receiver)
{
freeaddrinfo(receiver->ai);
free((void *) receiver->host_name);
free(receiver);
return true;
......
......@@ -3,10 +3,14 @@
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
typedef struct prrtReceiver {
const char* host_name;
uint16_t port;
struct addrinfo *ai;
} PrrtReceiver;
PrrtReceiver* PrrtReceiver_create(const char *host, uint16_t port);
......
......@@ -47,11 +47,6 @@ PrrtSocket *PrrtSocket_create(const bool is_sender)
check(sock_ptr->feedbackSocketFd = socket(AF_INET, SOCK_DGRAM, 0), "Cannot create feedback socket.");
check(setsockopt(sock_ptr->feedbackSocketFd, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled)) == EXIT_SUCCESS, "Socket option set failed.");
pthread_mutexattr_t attr;
check(pthread_mutexattr_init(&attr) == 0, "Mutex attr init failed.");
check(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) == 0, "Setting type failed.");
check(pthread_mutex_init(&sock_ptr->closingMutex, &attr) == 0, "Mutex init failed.");
if (is_sender) {
check(pthread_mutex_init(&sock_ptr->outQueueFilledMutex, NULL) == 0, "Mutex init failed.");
check(pthread_cond_init(&sock_ptr->outQueueFilledCv, NULL) == 0, "Cond init failed.");
......@@ -143,13 +138,10 @@ int32_t PrrtSocket_recv(PrrtSocket *sock_ptr, void *buf_ptr) {
while (1) {
check(pthread_mutex_lock(&sock_ptr->inQueueFilledMutex) == 0, "Lock failed.");
while (List_count(sock_ptr->inQueue) == 0) {
check(pthread_mutex_lock(&sock_ptr->closingMutex) == 0, "Lock failed.");
if (sock_ptr->closing) {
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
if (atomic_load_explicit(&sock_ptr->closing, memory_order_acquire)) {
check(pthread_mutex_unlock(&sock_ptr->inQueueFilledMutex) == 0, "Unlock failed.");
return -1;
}
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
check(pthread_cond_wait(&sock_ptr->inQueueFilledCv, &sock_ptr->inQueueFilledMutex) == 0, "Wait failed.");
}
PrrtPacket *packet = List_shift(sock_ptr->inQueue);
......@@ -169,9 +161,7 @@ int32_t PrrtSocket_recv(PrrtSocket *sock_ptr, void *buf_ptr) {
}
int PrrtSocket_interrupt(PrrtSocket *sock_ptr) {
check(pthread_mutex_lock(&sock_ptr->closingMutex) == 0, "Lock failed.");
sock_ptr->closing = true;
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
atomic_store_explicit(&sock_ptr->closing, true, memory_order_release);
void **res = NULL;
if (sock_ptr->sendDataThread != 0) {
......@@ -215,12 +205,8 @@ int PrrtSocket_interrupt(PrrtSocket *sock_ptr) {
int PrrtSocket_close(PrrtSocket *sock_ptr) {
debug("Closing socket.");
check(pthread_mutex_lock(&sock_ptr->closingMutex) == 0, "Lock failed.");
if (!sock_ptr->closing) {
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
if (!atomic_load_explicit(&sock_ptr->closing, memory_order_acquire)) {
check(PrrtSocket_interrupt(sock_ptr) == EXIT_SUCCESS, "Interrupt failed.");
} else {
check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed.");
}
if(sock_ptr->dataPacketStore != NULL) {
......@@ -266,8 +252,6 @@ int PrrtSocket_close(PrrtSocket *sock_ptr) {
sock_ptr->packetTimeoutTable = NULL;
}
check(pthread_mutex_destroy(&sock_ptr->closingMutex) == 0, "Mutex destroy failed.");
if(sock_ptr->address != NULL) {
free(sock_ptr->address);
}
......
#ifndef PRRT_SOCKET_H
#define PRRT_SOCKET_H
#include <stdatomic.h>
#include "../defines.h"
#include "packet.h"
#include "stores/forwardPacketTable.h"
......@@ -45,8 +47,7 @@ typedef struct prrtSocket {
List* receivers;
pthread_mutex_t closingMutex;
bool closing;
atomic_bool closing;
prrtSequenceNumber_t packetsCount;
prrtSequenceNumber_t sequenceNumberSource;
......
......@@ -314,7 +314,7 @@ static int invert_mat(PrrtCoder *cod, gf *src, int k) {
goto fail;
}
bzero(id_row, k * sizeof(gf));
memset(id_row, 0x0, k * sizeof(gf));
/*
* ipiv marks elements already used as pivots.
*/
......@@ -391,7 +391,7 @@ static int invert_mat(PrrtCoder *cod, gf *src, int k) {
* we can optimize the addmul).
*/
id_row[icol] = 1;
if (bcmp(pivot_row, id_row, k * sizeof(gf)) != 0) {
if (memcmp(pivot_row, id_row, k * sizeof(gf)) != 0) {
for (p = src, ix = 0; ix < k; ix++, p += k) {
if (ix != icol) {
c = p[icol];
......@@ -435,7 +435,7 @@ static int invert_mat(PrrtCoder *cod, gf *src, int k) {
* q = values of the polynomial (known)
*/
int invert_vdm(PrrtCoder *cod, gf *src, int k) {
static int invert_vdm(PrrtCoder *cod, gf *src, int k) {
int i, j, row, col;
gf *b, *c, *p;
gf t, xx;
......@@ -617,7 +617,7 @@ int prrt_coder_create(PrrtCoder **cod, uint8_t k, uint8_t n) {
/*
* the upper matrix is I so do not bother with a slow multiply
*/
bzero((*cod)->params.enc_matrix, k * k * sizeof(gf));
memset((*cod)->params.enc_matrix, 0x0, k * k * sizeof(gf));
for (p = (*cod)->params.enc_matrix, col = 0; col < k; col++, p += k + 1) {
*p = 1;
}
......@@ -645,11 +645,11 @@ void PrrtCoder_encode(PrrtCoder *cod, gf **src, gf *fec, int index, int sz) {
}
if (index < k) {
bcopy(src[index], fec, sz * sizeof(gf));
memcpy(fec, src[index], sz * sizeof(gf));
}
else if (index < cod->params.n) {
p = &(cod->params.enc_matrix[index * k]);
bzero(fec, sz * sizeof(gf));
memset(fec, 0x0, sz * sizeof(gf));
for (i = 0; i < k; i++) {
addmul(cod, fec, src[i], p[i], sz);
}
......@@ -672,12 +672,12 @@ static gf *prrt_coder_build_matrix(PrrtCoder *cod, int *index) {
for (i = 0, p = matrix; i < k; i++, p += k) {
#if 1 /* this is simply an optimization, not very useful indeed */
if (index[i] < k) {
bzero(p, k * sizeof(gf));
memset(p, 0x0, k * sizeof(gf));
p[i] = 1;
} else
#endif
if (index[i] < cod->params.n) {
bcopy(&(cod->params.enc_matrix[index[i] * k]), p, k * sizeof(gf));
memcpy(p, &(cod->params.enc_matrix[index[i] * k]), k * sizeof(gf));
}
else {
PERROR("decode: invalid index %d (max %d)\n",
......@@ -729,7 +729,7 @@ int PrrtCoder_decode(PrrtCoder *cod, gf **pkt, int *index, int sz) {
err = -1;
goto error;
}
bzero(new_pkt, k * sizeof(gf *));
memset(new_pkt, 0x0, k * sizeof(gf *));
for (row = 0; row < k; row++) {
if (index[row] >= k) {
......@@ -738,7 +738,7 @@ int PrrtCoder_decode(PrrtCoder *cod, gf **pkt, int *index, int sz) {
PERROR("No memory for packet row\n");
goto free_rows;
}
bzero(new_pkt[row], sz * sizeof(gf));
memset(new_pkt[row], 0x0, sz * sizeof(gf));
for (col = 0; col < k; col++) {
addmul(cod, new_pkt[row], pkt[col], m_dec[row * k + col], sz);
}
......@@ -749,7 +749,7 @@ int PrrtCoder_decode(PrrtCoder *cod, gf **pkt, int *index, int sz) {
*/
for (row = 0; row < k; row++) {
if (index[row] >= k) {
bcopy(new_pkt[row], pkt[row], sz * sizeof(gf));
memcpy(pkt[row], new_pkt[row], sz * sizeof(gf));
free(new_pkt[row]);
}
}
......@@ -771,4 +771,4 @@ int PrrtCoder_decode(PrrtCoder *cod, gf **pkt, int *index, int sz) {
free(m_dec);
return -1;
}
\ No newline at end of file
}
......@@ -12,9 +12,10 @@ Bitmap *Bitmap_create(bool initialValue, uint32_t elementCount)
check_mem(bitmap);
bitmap->count = elementCount;
uint32_t blockCount = (uint32_t) ceil(elementCount / 32.0);
uint32_t blockCount = (elementCount + 31) / 32;
bitmap->data = calloc(blockCount, sizeof(uint32_t));
check_mem(bitmap->data);
if(initialValue == true) {
memset(bitmap->data, -1, blockCount * sizeof(uint32_t));
}
......@@ -25,32 +26,22 @@ Bitmap *Bitmap_create(bool initialValue, uint32_t elementCount)
return NULL;
}
bool Bitmap_get(Bitmap *bitmap, uint32_t position)
void Bitmap_set_range_0(Bitmap *bitmap, uint32_t start, uint32_t length)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
return (bool) ((bitmap->data[byte_offset] & (1 << bit_offset)) != 0);
}
bool Bitmap_set(Bitmap *bitmap, uint32_t position, bool value)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
if(value) {
bitmap->data[byte_offset] |= (1 << bit_offset);
} else {
bitmap->data[byte_offset] &= ~(1 << bit_offset);
}
return true;
uint32_t i = 0;
// TODO: highly inefficient - optimize
for(i = 0; i < length; i++) {
Bitmap_set_0(bitmap, start + i);
}
}
void Bitmap_set_range(Bitmap *bitmap, uint32_t start, uint32_t length, bool value)
void Bitmap_set_range_1(Bitmap *bitmap, uint32_t start, uint32_t length)
{
uint32_t i = 0;
// TODO: highly inefficient - optimize
for(i = 0; i < length; i++) {
Bitmap_set(bitmap, start + i, value);
}
for(i = 0; i < length; i++) {
Bitmap_set_1(bitmap, start + i);
}
}
uint32_t Bitmap_sum_ones(Bitmap *bitmap, uint32_t start, uint32_t length)
......@@ -66,13 +57,7 @@ uint32_t Bitmap_sum_ones(Bitmap *bitmap, uint32_t start, uint32_t length)
uint32_t Bitmap_sum_zeros(Bitmap *bitmap, uint32_t start, uint32_t length)
{
uint32_t sum = 0;
uint32_t i = 0;
// TODO: highly inefficient - optimize
for(i = 0; i < length; i++) {
sum += (Bitmap_get(bitmap, start + i) == false);
}
return sum;
return length - Bitmap_sum_ones(bitmap, start, length);
}
bool Bitmap_destroy(Bitmap *bitmap)
......
......@@ -10,11 +10,56 @@ typedef struct bitmap {
} Bitmap;
Bitmap *Bitmap_create(bool initialValue, uint32_t elementCount);
bool Bitmap_get(Bitmap* bitmap, uint32_t position);
bool Bitmap_set(Bitmap* bitmap, uint32_t position, bool value);
void Bitmap_set_range(Bitmap *bitmap, uint32_t start, uint32_t length, bool value);
void Bitmap_set_range_0(Bitmap *bitmap, uint32_t start, uint32_t length);
void Bitmap_set_range_1(Bitmap *bitmap, uint32_t start, uint32_t length);
uint32_t Bitmap_sum_ones(Bitmap *bitmap, uint32_t start, uint32_t length);
uint32_t Bitmap_sum_zeros(Bitmap *bitmap, uint32_t start, uint32_t length);
bool Bitmap_destroy(Bitmap* bitmap);
#ifdef __GNUC__
# define BITMAP_EXPOSED_FUNCTION static inline __attribute__((__always_inline__,__unused__))
#else
# define BITMAP_EXPOSED_FUNCTION static inline
#endif
BITMAP_EXPOSED_FUNCTION bool Bitmap_get(Bitmap *bitmap, uint32_t position)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
return (bool) ((bitmap->data[byte_offset] & (1 << bit_offset)) != 0);
}
BITMAP_EXPOSED_FUNCTION bool Bitmap_set_0(Bitmap *bitmap, uint32_t position)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
bitmap->data[byte_offset] &= ~(1 << bit_offset);
return true;
}
BITMAP_EXPOSED_FUNCTION bool Bitmap_set_1(Bitmap *bitmap, uint32_t position)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
bitmap->data[byte_offset] |= (1 << bit_offset);
return true;
}
BITMAP_EXPOSED_FUNCTION bool Bitmap_set(Bitmap *bitmap, uint32_t position, bool value)
{
if (value)
Bitmap_set_1(bitmap, position);
else
Bitmap_set_0(bitmap, position);
return true;
}
BITMAP_EXPOSED_FUNCTION void Bitmap_set_range(Bitmap *bitmap, uint32_t start, uint32_t length, bool value)
{
if (value)
Bitmap_set_range_1(bitmap, start, length);
else
Bitmap_set_range_0(bitmap, start, length);
}
#endif //PRRT_BITMAP_H
This diff is collapsed.
......@@ -11,6 +11,7 @@ int print_buffer(const char *buf, const int length) {
printf("%2x", buf[i]);
}
printf("\n");
return 0;
}
void print_gf(const gf *start, const int len) {
......@@ -24,4 +25,4 @@ void print_gf(const gf *start, const int len) {
}
}
printf("\n");
}
\ No newline at end of file
}
#include "timestamp.h"
#include <stdatomic.h>
void PrrtTimestampTableDumpHeader(FILE *out)
{
fprintf(out, "SeqNo" );
# define OUT(id) fprintf(out, ",%s_T,%s_C", #id, #id);
PP_foreach(PP_join_space, OUT, TIMESTAMP_ID_LIST)
# undef OUT
fprintf(out, "\n");
}
static inline unsigned long long timestampByTime(struct timespec *ts)
{
// convert timespec to microseconds
unsigned long long x = ts->tv_sec;
x *= 1000000ULL;
x += ts->tv_nsec / 1000;
return x;
}
void PrrtTimestampTableDump(FILE *out, unsigned int seqno, PrrtTimestampTable *table)
{
fprintf(out, "%u", seqno);
# define OUT(id) fprintf(out, ",%llu,%llu", timestampByTime(&table->time[ts_##id].actual.t), (unsigned long long) table->time[ts_##id].actual.c);
PP_foreach(PP_join_space, OUT, TIMESTAMP_ID_LIST)
# undef OUT
fprintf(out, "\n");
}
#ifndef PRRT_TIMESTAMP_H
#define PRRT_TIMESTAMP_H
#include <stdio.h>
#include <stdint.h>
#include <time.h>
/*
* Each timestamp contains both a cycle value and a time value, but some values
* might remain zero
*/
typedef union PrrtTimestamp {
struct PrrtActualTimestamp {
uint64_t c;
struct timespec t;
} actual;
char _cacheline[64];
} PrrtTimestamp;
#include "../util/pp.h"
/*
* Comma-separated list of timestamp IDs
*/
#define TIMESTAMP_ID_LIST \
PrrtSendStart, \
PrrtSendEnd, \
PrrtEncodeStart, \
PrrtEncodeEnd, \
LinkTransmitStart, \
LinkTransmitEnd, \
LinkReceive, \
PrrtDeliver \
#define TIMESSTAMP_ID_TO_NAME(id) ts_##id
/*
* enum containing all timestamp IDs
*/
typedef enum PrrtTimestampId {
PP_foreach(PP_join_comma, TIMESSTAMP_ID_TO_NAME, TIMESTAMP_ID_LIST),
ts_count
} PrrtTimestampId;
/*
* Table that stores timestamps for each timestamp ID
*/
typedef struct PrrtTimestampTable {
PrrtTimestamp time[ts_count];
} PrrtTimestampTable;
/*
* update the clock value of a timestamp
*
* This macro will cause a SIGSEGV if the application does not install a
* timestamp table to the prrt socket.
*/
#define PrrtTimeStampClock(sck, id) do { \
clock_gettime(CLOCK_MONOTONIC, &atomic_load_explicit(&(sck)->tstable, memory_order_acquire)->time[ts_##id].actual.t); \
} while (0);
/*
* update the cycle value of a timestamp
*
* This macro will cause a SIGSEGV if the application does not install a
* timestamp table to the prrt socket.
*/
#define PrrtTimeStampCycle(sck, id) do { \
atomic_load_explicit(&(sck)->tstable, memory_order_acquire)->time[ts_##id].actual.c = __builtin_ia32_rdtsc(); \
} while (0);
/*
* install a time stamp table to a socket
*/
#define PrrtTimestampTableInstall(sck, tstp) do { \
PrrtTimestampTable *__tstp = (tstp); \
memset(__tstp, 0, sizeof(PrrtTimestampTable)); \
atomic_store_explicit(&(sck)->tstable, __tstp, memory_order_release); \
} while (0)
/*
* print a timestamp dump header
*/
extern void PrrtTimestampTableDumpHeader(FILE *);
/*
* dump a timestamp table
*/
extern void PrrtTimestampTableDump(FILE *, unsigned int, PrrtTimestampTable *);
/*
* use a specific timestamp table
*/
extern void PrrtTimestampTableUse(PrrtTimestampTable *);
#endif // PRRT_TIMESTAMP_H
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment