static void SCCPackFun(c4snet_data_t *data, void *buf) { SNetDistribPack(data, buf, sizeof(c4snet_data_t), false); if (data->vtype == VTYPE_array) { SNetDistribPack(data->data.ptr, buf, AllocatedSpace(data), true); } }
Buffer::~Buffer() { if (buffer_start_ != nullptr) { LOG_DEBUG("Releasing %.2lf KB of memory", AllocatedSpace() / 1024.0); auto &backend_manager = storage::BackendManager::GetInstance(); backend_manager.Release(BackendType::MM, buffer_start_); } buffer_start_ = buffer_pos_ = buffer_end_ = nullptr; }
c4snet_data_t *C4SNetCreate(c4snet_type_t type, size_t size, const void *data) { c4snet_data_t *c = SNetMemAlloc(sizeof(c4snet_data_t)); c->type = type; c->size = size; c->ref_count = 1; if (size == 1) { c->vtype = VTYPE_simple; memcpy(&c->data, data, C4SNetSizeof(c)); } else { c->vtype = VTYPE_array; c->data.ptr = MemAlloc(AllocatedSpace(c)); memcpy(c->data.ptr, data, AllocatedSpace(c)); } return c; }
/* Decodes binary data from a file. */ static c4snet_data_t *C4SNetDecode(FILE *file) { c4snet_data_t *c = SNetMemAlloc(sizeof(c4snet_data_t)); Base64decodeDataType(file, (int*) &c->vtype); Base64decode(file, &c->size, sizeof(int)); Base64decodeDataType(file, (int*) &c->type); c->ref_count = 1; if(c->vtype == VTYPE_array) { c->data.ptr = MemAlloc(AllocatedSpace(c)); Base64decode(file, c->data.ptr, AllocatedSpace(c)); } else { Base64decode(file, &c->data, C4SNetSizeof(c)); } return c; }
/* Binary encodes data to a file. */ static void C4SNetEncode(FILE *file, c4snet_data_t *data) { Base64encodeDataType(file, (int) data->vtype); Base64encode(file, &data->size, sizeof(int)); Base64encodeDataType(file, (int) data->type); if (data->vtype == VTYPE_array) { Base64encode(file, data->data.ptr, AllocatedSpace(data)); } else { Base64encode(file, &data->data, C4SNetSizeof(data)); } }
/* Deserializes textual data from a file. */ static c4snet_data_t *C4SNetDeserialise(FILE *file) { char buf[16]; c4snet_data_t *temp = SNetMemAlloc(sizeof(c4snet_data_t)); temp->size = 0; temp->ref_count = 1; if (fscanf(file, "(%15[^[)][%lu])", buf, &temp->size) == 2) { temp->vtype = VTYPE_array; } else { temp->vtype = VTYPE_simple; (void) fscanf(file, ")"); } int size = strlen(buf); if (strncmp(buf, "unsigned char", size) == 0) temp->type = CTYPE_uchar; else if(strncmp(buf, "char", size) == 0) temp->type = CTYPE_char; else if(strncmp(buf, "unsigned short", size) == 0) temp->type = CTYPE_ushort; else if(strncmp(buf, "short", size) == 0) temp->type = CTYPE_short; else if(strncmp(buf, "unsigned int", size) == 0) temp->type = CTYPE_uint; else if(strncmp(buf, "int", size) == 0) temp->type = CTYPE_int; else if(strncmp(buf, "unsigned long", size) == 0) temp->type = CTYPE_ulong; else if(strncmp(buf, "long", size) == 0) temp->type = CTYPE_long; else if(strncmp(buf, "float", size) == 0) temp->type = CTYPE_float; else if(strncmp(buf, "double", size) == 0) temp->type = CTYPE_double; else if(strncmp(buf, "long double", size) == 0) temp->type = CTYPE_ldouble; else if(strncmp(buf, "pointer", size) == 0) temp->type = CTYPE_pointer; else SNetUtilDebugFatal("[%s]: C4SNet interface encountered an unknown type.", __func__); if (temp->vtype == VTYPE_simple) { DeserialiseData(file, temp->type, &temp->data); } else { temp->data.ptr = MemAlloc(AllocatedSpace(temp)); for (int i = 0; i < temp->size; i++) { if (i > 0 && fgetc(file) != ',') { SNetUtilDebugFatal("[%s]: Parse error deserialising data.", __func__); } DeserialiseData(file, temp->type, (char*) temp->data.ptr + i * C4SNetSizeof(temp)); } } return temp; }
/* Creates a new c4snet_data_t struct. */ c4snet_data_t *C4SNetAlloc(c4snet_type_t type, size_t size, void **data) { c4snet_data_t *c = SNetMemAlloc(sizeof(c4snet_data_t)); c->type = type; c->size = size; c->ref_count = 1; if (size == 1) { c->vtype = VTYPE_simple; *data = &c->data; } else { c->vtype = VTYPE_array; c->data.ptr = MemAlloc(AllocatedSpace(c)); *data = c->data.ptr; } return c; }
void Buffer::MakeRoomForBytes(uint64_t num_bytes) { bool has_room = (buffer_start_ != nullptr && buffer_pos_ + num_bytes < buffer_end_); if (has_room) { return; } // Need to allocate some space uint64_t curr_alloc_size = AllocatedSpace(); uint64_t curr_used_size = UsedSpace(); // Ensure the current size is a power of two PELOTON_ASSERT(curr_alloc_size % 2 == 0); // Allocate double the buffer room uint64_t next_alloc_size = curr_alloc_size; do { next_alloc_size *= 2; } while (next_alloc_size < num_bytes); LOG_DEBUG("Resizing buffer from %.2lf bytes to %.2lf KB ...", curr_alloc_size / 1024.0, next_alloc_size / 1024.0); auto &backend_manager = storage::BackendManager::GetInstance(); auto *new_buffer = reinterpret_cast<char *>( backend_manager.Allocate(BackendType::MM, next_alloc_size)); // Now copy the previous buffer into the new area PELOTON_MEMCPY(new_buffer, buffer_start_, curr_used_size); // Set pointers char *old_buffer_start = buffer_start_; buffer_start_ = new_buffer; buffer_pos_ = buffer_start_ + curr_used_size; buffer_end_ = buffer_start_ + next_alloc_size; // Release old buffer backend_manager.Release(BackendType::MM, old_buffer_start); }