TEST(RoutingTableTests, Functors) { using ArgList = gallocy::vector<gallocy::string>; RoutingTable<std::function<gallocy::http::Response *(ArgList *, gallocy::http::Request *)> > t; gallocy::http::Response *response = new (internal_malloc(sizeof(gallocy::http::Response))) gallocy::http::Response(); auto f = [response](ArgList *a, gallocy::http::Request *request) { gallocy::stringstream s; s << a->size(); response->body = s.str(); return response; }; t.register_handler("/foo", f); t.register_handler("/foo/<x>", f); t.register_handler("/foo/<x>/bar", f); t.register_handler("/foo/<x>/bar/<y>", f); t.register_handler("/foo/<x>/baz", f); t.register_handler("/foo/<x>/baz/<y>", f); ASSERT_EQ(t.match("/foo")(nullptr)->body, "0"); ASSERT_EQ(t.match("/foo/arg1")(nullptr)->body, "1"); ASSERT_EQ(t.match("/foo/arg1/bar")(nullptr)->body, "1"); ASSERT_EQ(t.match("/foo/arg1/bar/arg2")(nullptr)->body, "2"); ASSERT_EQ(t.match("/foo/arg1/baz")(nullptr)->body, "1"); ASSERT_EQ(t.match("/foo/arg1/baz/arg2")(nullptr)->body, "2"); internal_free(response); }
void* debug_malloc(size_t size) { if (DebugCallsDisabled()) { return g_dispatch->malloc(size); } ScopedDisableDebugCalls disable; return internal_malloc(size); }
inline void *precise_malloc (size_t size_in_bytes) { return TAG_HEAP_PTR(internal_malloc(size_in_bytes)); /* void *result = TAG_HEAP_PTR(internal_malloc(size_in_bytes)); error_gc("Returning tagged heap ptr: %p\n", result); return result; */ }
TEST(DiffTests, DiffGeneral_2) { // NOTE(sholsapp): at 1024 this raises a SIGSEGV, presumably because we run // out of memory. Hypothesis was tested by increasing available memory, which // remedies the situation. int mem_sz = 512; char* str1 = (char*) internal_malloc(sizeof(char) * mem_sz); char* str2 = (char*) internal_malloc(sizeof(char) * mem_sz); char* str1align = NULL; char* str2align = NULL; for (int i = 0; i < mem_sz; i++) { str1[i] = rand() % 255; } memcpy(str2, str1, mem_sz); for (int i = 0; i < mem_sz; i++) { if (rand() % 10 == 1) str2[i] = rand() % 255; } int ret = diff(str1, mem_sz, str1align, str2, mem_sz, str2align); ASSERT_EQ(ret, 0); }
Request *GallocyServer::get_request(int client_socket) { gallocy::stringstream request; int n; char buf[512] = {0}; n = recv(client_socket, buf, 16, 0); request << buf; while (n > 0) { memset(buf, 0, 512); n = recv(client_socket, buf, 512, MSG_DONTWAIT); request << buf; } return new (internal_malloc(sizeof(Request))) Request(request.str()); }
Response *GallocyServer::route_append_entries(RouteArguments *args, Request *request) { gallocy::json request_json = request->get_json(); gallocy::vector<LogEntry> leader_entries; uint64_t leader_commit_index = request_json["leader_commit"]; uint64_t leader_prev_log_index = request_json["previous_log_index"]; uint64_t leader_prev_log_term = request_json["previous_log_term"]; uint64_t leader_term = request_json["term"]; uint64_t local_term = gallocy_state->get_current_term(); bool success = false; for (auto entry_json : request_json["entries"]) { // TODO(sholsapp): Implicit conversion issue. gallocy::string tmp = entry_json["command"]; uint64_t term = entry_json["term"]; Command command(tmp); LogEntry entry(command, term); leader_entries.push_back(entry); } if (leader_term < local_term) { LOG_INFO("Rejecting leader " << request->peer_ip << " because term is outdated (" << leader_term << ")"); success = false; } else { // if (leader_entries.size() > 0) { // LOG_INFO("Appending " << leader_entries.size() << " new entries!"); // } success = true; gallocy_state->set_current_term(leader_term); gallocy_state->set_state(RaftState::FOLLOWER); gallocy_state->set_voted_for(request->peer_ip); gallocy_state->get_timer()->reset(); } gallocy::json response_json = { { "peer", gallocy_config->address.c_str() }, { "term", gallocy_state->get_current_term() }, { "success", success }, }; Response *response = new (internal_malloc(sizeof(Response))) Response(); response->headers["Server"] = "Gallocy-Httpd"; response->headers["Content-Type"] = "application/json"; response->status_code = 200; response->body = response_json.dump(); args->~RouteArguments(); internal_free(args); return response; }
/** ** Allocation d'une zone dans le segment de memoire partagee **/ void * smMemMalloc(size_t nBytes) { void *result; if (smMemFreeList == NULL) { if (smMemAttach() == ERROR) { return NULL; } } result = internal_malloc(nBytes); LOGDBG(("comLib:smMemLib: alloc %u -> 0x%lx\n", nBytes, (unsigned long)result)); return result; }
static inline Tree* tmalloc() { ++allallocs; if(freelist) { Tree* t = freelist; freelist = freelist->left; return t; } else if(use < 1024) { ++use; return &initmem[use-1]; } else { Tree * tmp = internal_malloc(sizeof(Tree)); if (!tmp) poolcheckfatal ("LLVA: tmalloc: Failed to allocate\n", 0); return (Tree*) tmp; } }
// TODO(sholsapp): This is just a route that we can hit to trigger an append // entries action. Once we're done testing, we can remove this route. Response *GallocyServer::route_request(RouteArguments *args, Request *request) { Command command("hello world"); LogEntry entry(command, gallocy_state->get_current_term()); gallocy::vector<LogEntry> entries; entries.push_back(entry); gallocy_client->send_append_entries(entries); Response *response = new (internal_malloc(sizeof(Response))) Response(); response->headers["Server"] = "Gallocy-Httpd"; response->headers["Content-Type"] = "application/json"; response->status_code = 200; response->body = "GOOD"; args->~RouteArguments(); internal_free(args); return response; }
Response *GallocyServer::route_request_vote(RouteArguments *args, Request *request) { gallocy::json request_json = request->get_json(); uint64_t candidate_commit_index = request_json["commit_index"]; uint64_t candidate_current_term = request_json["term"]; uint64_t candidate_last_applied = request_json["last_applied"]; uint64_t candidate_voted_for = request->peer_ip; uint64_t local_commit_index = gallocy_state->get_commit_index(); uint64_t local_current_term = gallocy_state->get_current_term(); uint64_t local_last_applied = gallocy_state->get_last_applied(); uint64_t local_voted_for = gallocy_state->get_voted_for(); bool granted = false; if (candidate_current_term < local_current_term) { granted = false; } else if (local_voted_for == 0 || local_voted_for == candidate_voted_for) { if (candidate_last_applied >= local_last_applied && candidate_commit_index >= local_commit_index) { LOG_INFO("Granting vote to " << utils::unparse_internet_address(candidate_voted_for) << " in term " << candidate_current_term); gallocy_state->set_current_term(candidate_current_term); gallocy_state->set_voted_for(candidate_voted_for); gallocy_state->get_timer()->reset(); granted = true; } else { // TODO(sholsapp): Implement logic to reject candidates that don't have // an up to date log. LOG_ERROR("Handling of out-of-date log is unimplemented"); } } gallocy::json response_json = { { "peer", gallocy_config->address.c_str() }, { "term", gallocy_state->get_current_term() }, { "vote_granted", granted }, }; Response *response = new (internal_malloc(sizeof(Response))) Response(); response->headers["Server"] = "Gallocy-Httpd"; response->headers["Content-Type"] = "application/json"; response->status_code = 200; response->body = response_json.dump(); args->~RouteArguments(); internal_free(args); return response; }
Response *GallocyServer::route_admin(RouteArguments *args, Request *request) { Response *response = new (internal_malloc(sizeof(Response))) Response(); response->status_code = 200; response->headers["Server"] = "Gallocy-Httpd"; response->headers["Content-Type"] = "application/json"; #if 0 gallocy::json j = { {"status", "GOOD" }, {"master", is_master}, {"peers", { } }, {"diagnostics", { // TODO(sholsapp): These names suck.. we should indicate that they are allocators. { "local_internal_memory", reinterpret_cast<uint64_t>(&local_internal_memory) }, { "shared_page_table", reinterpret_cast<uint64_t>(&shared_page_table) }, // TODO(sholsapp): Add the main application allocator here. } }, }; for (auto p : peer_info_table.all()) { gallocy::json peer_info = { {"id", p.id}, {"ip_address", p.ip_address}, {"first_seen", p.first_seen}, {"last_seen", p.last_seen}, }; j["peers"].push_back(peer_info); } response->body = j.dump(); #endif response->body = "GOOD"; args->~RouteArguments(); internal_free(args); return response; }
static inline struct memory_chunk * chunk_alloc() { struct memory_chunk *chunk; if (unlikely(list_need_init(&free_chunk))) { list_init(&free_chunk); } if (unlikely(list_empty(&free_chunk))) { chunk = (struct memory_chunk*) internal_malloc(OPEN_MAPPING, sizeof(struct memory_chunk)); #ifdef USE_ASSERT assert(!!chunk); #endif /* USE_ASSERT */ } else { chunk = next_entry(&free_chunk, struct memory_chunk, p); list_del(&chunk->p); } chunk->llc_victim_ref = 0; chunk->llc_pollutor_ref = 0; chunk->total_ref = 0; chunk->i_victim_ref = 0; chunk->i_pollutor_ref = 0; chunk->i_total_ref = 0; chunk->sample_cycle = 0; chunk->nr_sample = 0; list_init(&chunk->sample); list_init(&chunk->sibling); return chunk; }
static inline struct alloc_context * context_alloc() { struct alloc_context *context; if (unlikely(list_need_init(&free_context))) { list_init(&free_context); } if (unlikely(list_empty(&free_context))) { context = (struct alloc_context*) internal_malloc(OPEN_MAPPING, sizeof(struct alloc_context)); #ifdef USE_ASSERT assert(!!context); #endif /* USE_ASSERT */ } else { context = next_entry(&free_context, struct alloc_context, p); list_del(&context->p); } list_init(&context->chunk); list_init(&context->s2t_set); return context; }
/* Dimensions: retarray(x,y) a(x, count) b(count,y). Either a or b can be rank 1. In this case x or y is 1. */ void __matmul_c8 (gfc_array_c8 * retarray, gfc_array_c8 * a, gfc_array_c8 * b) { GFC_COMPLEX_8 *abase; GFC_COMPLEX_8 *bbase; GFC_COMPLEX_8 *dest; GFC_COMPLEX_8 res; index_type rxstride; index_type rystride; index_type xcount; index_type ycount; index_type xstride; index_type ystride; index_type x; index_type y; GFC_COMPLEX_8 *pa; GFC_COMPLEX_8 *pb; index_type astride; index_type bstride; index_type count; index_type n; assert (GFC_DESCRIPTOR_RANK (a) == 2 || GFC_DESCRIPTOR_RANK (b) == 2); if (retarray->data == NULL) { if (GFC_DESCRIPTOR_RANK (a) == 1) { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = b->dim[1].ubound - b->dim[1].lbound; retarray->dim[0].stride = 1; } else if (GFC_DESCRIPTOR_RANK (b) == 1) { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = a->dim[0].ubound - a->dim[0].lbound; retarray->dim[0].stride = 1; } else { retarray->dim[0].lbound = 0; retarray->dim[0].ubound = a->dim[0].ubound - a->dim[0].lbound; retarray->dim[0].stride = 1; retarray->dim[1].lbound = 0; retarray->dim[1].ubound = b->dim[1].ubound - b->dim[1].lbound; retarray->dim[1].stride = retarray->dim[0].ubound+1; } retarray->data = internal_malloc (sizeof (GFC_COMPLEX_8) * size0 (retarray)); retarray->base = 0; } abase = a->data; bbase = b->data; dest = retarray->data; if (retarray->dim[0].stride == 0) retarray->dim[0].stride = 1; if (a->dim[0].stride == 0) a->dim[0].stride = 1; if (b->dim[0].stride == 0) b->dim[0].stride = 1; if (GFC_DESCRIPTOR_RANK (retarray) == 1) { rxstride = retarray->dim[0].stride; rystride = rxstride; } else { rxstride = retarray->dim[0].stride; rystride = retarray->dim[1].stride; } /* If we have rank 1 parameters, zero the absent stride, and set the size to one. */ if (GFC_DESCRIPTOR_RANK (a) == 1) { astride = a->dim[0].stride; count = a->dim[0].ubound + 1 - a->dim[0].lbound; xstride = 0; rxstride = 0; xcount = 1; } else { astride = a->dim[1].stride; count = a->dim[1].ubound + 1 - a->dim[1].lbound; xstride = a->dim[0].stride; xcount = a->dim[0].ubound + 1 - a->dim[0].lbound; } if (GFC_DESCRIPTOR_RANK (b) == 1) { bstride = b->dim[0].stride; assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound); ystride = 0; rystride = 0; ycount = 1; } else { bstride = b->dim[0].stride; assert(count == b->dim[0].ubound + 1 - b->dim[0].lbound); ystride = b->dim[1].stride; ycount = b->dim[1].ubound + 1 - b->dim[1].lbound; } for (y = 0; y < ycount; y++) { for (x = 0; x < xcount; x++) { /* Do the summation for this element. For real and integer types this is the same as DOT_PRODUCT. For complex types we use do a*b, not conjg(a)*b. */ pa = abase; pb = bbase; res = 0; for (n = 0; n < count; n++) { res += *pa * *pb; pa += astride; pb += bstride; } *dest = res; dest += rxstride; abase += xstride; } abase -= xstride * xcount; bbase += ystride; dest += rystride - (rxstride * xcount); } }
void __maxloc1_8_r8 (gfc_array_i8 * retarray, gfc_array_r8 *array, index_type *pdim) { index_type count[GFC_MAX_DIMENSIONS - 1]; index_type extent[GFC_MAX_DIMENSIONS - 1]; index_type sstride[GFC_MAX_DIMENSIONS - 1]; index_type dstride[GFC_MAX_DIMENSIONS - 1]; GFC_REAL_8 *base; GFC_INTEGER_8 *dest; index_type rank; index_type n; index_type len; index_type delta; index_type dim; /* Make dim zero based to avoid confusion. */ dim = (*pdim) - 1; rank = GFC_DESCRIPTOR_RANK (array) - 1; assert (rank == GFC_DESCRIPTOR_RANK (retarray)); if (array->dim[0].stride == 0) array->dim[0].stride = 1; if (retarray->dim[0].stride == 0) retarray->dim[0].stride = 1; len = array->dim[dim].ubound + 1 - array->dim[dim].lbound; delta = array->dim[dim].stride; for (n = 0; n < dim; n++) { sstride[n] = array->dim[n].stride; extent[n] = array->dim[n].ubound + 1 - array->dim[n].lbound; } for (n = dim; n < rank; n++) { sstride[n] = array->dim[n + 1].stride; extent[n] = array->dim[n + 1].ubound + 1 - array->dim[n + 1].lbound; } if (retarray->data == NULL) { for (n = 0; n < rank; n++) { retarray->dim[n].lbound = 0; retarray->dim[n].ubound = extent[n]-1; if (n == 0) retarray->dim[n].stride = 1; else retarray->dim[n].stride = retarray->dim[n-1].stride * extent[n-1]; } retarray->data = internal_malloc (sizeof (GFC_INTEGER_8) * (retarray->dim[rank-1].stride * extent[rank-1])); retarray->base = 0; } for (n = 0; n < rank; n++) { count[n] = 0; dstride[n] = retarray->dim[n].stride; if (extent[n] <= 0) len = 0; } base = array->data; dest = retarray->data; while (base) { GFC_REAL_8 *src; GFC_INTEGER_8 result; src = base; { GFC_REAL_8 maxval; maxval = -GFC_REAL_8_HUGE; result = 1; if (len <= 0) *dest = 0; else { for (n = 0; n < len; n++, src += delta) { if (*src > maxval) { maxval = *src; result = (GFC_INTEGER_8)n + 1; } } *dest = result; } } /* Advance to the next element. */ count[0]++; base += sstride[0]; dest += dstride[0]; n = 0; while (count[n] == extent[n]) { /* When we get to the end of a dimension, reset it and increment the next dimension. */ count[n] = 0; /* We could precalculate these products, but this is a less frequently used path so proabably not worth it. */ base -= sstride[n] * extent[n]; dest -= dstride[n] * extent[n]; n++; if (n == rank) { /* Break out of the look. */ base = NULL; break; } else { count[n]++; base += sstride[n]; dest += dstride[n]; } } } }
int initialize_gallocy_framework(const char* config_path) { void *start; void *end; LOG_DEBUG("Initializing gallocy framework!"); // // Fail early if a configuration file wasn't found. // if (!config_path) { LOG_ERROR("No configuration file provided!"); abort(); } // // Share where heaps have been placed. // start = get_heap_location(PURPOSE_INTERNAL_HEAP); end = reinterpret_cast<uint8_t *>(start) + ZONE_SZ; LOG_DEBUG("Set internal heap " << "[" << start << " - " << end << "]"); start = get_heap_location(PURPOSE_SHARED_HEAP); end = reinterpret_cast<uint8_t *>(start) + ZONE_SZ; LOG_DEBUG("Set shared heap " << "[" << start << " - " << end << "]"); start = get_heap_location(PURPOSE_APPLICATION_HEAP); end = reinterpret_cast<uint8_t *>(start) + ZONE_SZ; LOG_DEBUG("Set application heap " << "[" << start << " - " << end << "]"); // // Initialize libcurl memory allocator. // curl_global_init(CURL_GLOBAL_NOTHING); #if 0 if (curl_global_init_mem( // CURL_GLOBAL_ALL, CURL_GLOBAL_NOTHING, malloc, free, realloc, strdup, calloc)) { LOG_ERROR("Failed to set curl global initiatilization settings."); } #endif char *error; void *handle; // // Seed random number generator // std::srand(std::time(0)); #if __linux__ const char* libpthread = "/lib/x86_64-linux-gnu/libpthread.so.0"; #else const char* libpthread = "/lib/x86_64-linux-gnu/libpthread.so.0"; LOG_ERROR("We don't know how to find libpthread.so on this platform."); #endif dlerror(); handle = dlopen(libpthread, RTLD_LAZY); if (!handle) { LOG_ERROR("Failed to open " << libpthread << ": " << dlerror()); } // // pthread_create // dlerror(); __gallocy_pthread_create = reinterpret_cast<pthread_create_function> (reinterpret_cast<uint64_t *>(dlsym(handle, "pthread_create"))); if ((error = dlerror()) != NULL) { LOG_ERROR("Failed to set pthread_create: " << error); } LOG_DEBUG("Initialized __gallocy_pthread_create [" << &__gallocy_pthread_create << "] from pthread_create [" << reinterpret_cast<uint64_t *>(*__gallocy_pthread_create) << "]"); // // pthread_join // dlerror(); __gallocy_pthread_join = reinterpret_cast<pthread_join_function> (reinterpret_cast<uint64_t *>(dlsym(handle, "pthread_join"))); if ((error = dlerror()) != NULL) { LOG_ERROR("Failed to set pthread_join: " << error); } LOG_DEBUG("Initialized __gallocy_pthread_join [" << &__gallocy_pthread_join << "] from pthread_join [" << reinterpret_cast<uint64_t *>(*__gallocy_pthread_join) << "]"); // // Initialize SQLite memory allocator. // e.initialize(); e.execute(PeerInfo::CREATE_STATEMENT); // // Load configuration file. // gallocy_config = load_config(config_path); // // Create the state object. // gallocy_state = new (internal_malloc(sizeof(GallocyState))) GallocyState(); // // Create the client object. // gallocy_client = new (internal_malloc(sizeof(GallocyClient))) GallocyClient(*gallocy_config); // // // Start the client thread. // gallocy_machine = new (internal_malloc(sizeof(GallocyMachine))) GallocyMachine(*gallocy_config); gallocy_machine->start(); // // Start the server thread. // gallocy_server = new (internal_malloc(sizeof(GallocyServer))) GallocyServer(*gallocy_config); gallocy_server->start(); // // Yield to the application. // return 0; }
void* debug_realloc(void* pointer, size_t bytes) { if (DebugCallsDisabled()) { return g_dispatch->realloc(pointer, bytes); } ScopedDisableDebugCalls disable; if (pointer == nullptr) { return internal_malloc(bytes); } if (bytes == 0) { internal_free(pointer); return nullptr; } size_t real_size = bytes; if (g_debug->config().options & EXPAND_ALLOC) { real_size += g_debug->config().expand_alloc_bytes; if (real_size < bytes) { // Overflow. errno = ENOMEM; return nullptr; } } void* new_pointer; size_t prev_size; if (g_debug->need_header()) { if (bytes > Header::max_size()) { errno = ENOMEM; return nullptr; } Header* header = g_debug->GetHeader(pointer); if (header->tag != DEBUG_TAG) { LogTagError(header, pointer, "realloc"); return nullptr; } // Same size, do nothing. if (real_size == header->real_size()) { // Do not bother recording, this is essentially a nop. return pointer; } // Allocation is shrinking. if (real_size < header->usable_size) { header->size = real_size; if (*g_malloc_zygote_child) { header->set_zygote(); } if (g_debug->config().options & REAR_GUARD) { // Don't bother allocating a smaller pointer in this case, simply // change the header usable_size and reset the rear guard. header->usable_size = header->real_size(); memset(g_debug->GetRearGuard(header), g_debug->config().rear_guard_value, g_debug->config().rear_guard_bytes); } // Do not bother recording, this is essentially a nop. return pointer; } // Allocate the new size. new_pointer = internal_malloc(bytes); if (new_pointer == nullptr) { errno = ENOMEM; return nullptr; } prev_size = header->usable_size; memcpy(new_pointer, pointer, prev_size); internal_free(pointer); } else { prev_size = g_dispatch->malloc_usable_size(pointer); new_pointer = g_dispatch->realloc(pointer, real_size); if (new_pointer == nullptr) { return nullptr; } } if (g_debug->config().options & FILL_ON_ALLOC) { size_t bytes = internal_malloc_usable_size(new_pointer); if (bytes > g_debug->config().fill_on_alloc_bytes) { bytes = g_debug->config().fill_on_alloc_bytes; } if (bytes > prev_size) { memset(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(new_pointer) + prev_size), g_debug->config().fill_alloc_value, bytes - prev_size); } } return new_pointer; }
void *GallocyServer::work() { LOG_DEBUG("Starting HTTP server on " << address << ":" << port); struct sockaddr_in name; int optval = 1; server_socket = socket(PF_INET, SOCK_STREAM, 0); if (server_socket == -1) { error_die("socket"); } #ifdef __APPLE__ setsockopt(server_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); #else setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); #endif memset(&name, 0, sizeof(name)); name.sin_family = AF_INET; name.sin_port = htons(port); // name.sin_addr.s_addr = htonl(INADDR_ANY); name.sin_addr.s_addr = inet_addr(address.c_str()); if (bind(server_socket, (struct sockaddr *) &name, sizeof(name)) < 0) { error_die("bind"); } if (listen(server_socket, 5) < 0) { error_die("listen"); } int64_t client_sock = -1; struct sockaddr_in client_name; uint64_t client_name_len = sizeof(client_name); pthread_t newthread; while (alive) { client_sock = accept(server_socket, reinterpret_cast<struct sockaddr *>(&client_name), reinterpret_cast<socklen_t *>(&client_name_len)); if (client_sock == -1) { error_die("accept"); } struct RequestContext *ctx = new (internal_malloc(sizeof(struct RequestContext))) struct RequestContext; ctx->server = this; ctx->client_socket = client_sock; ctx->client_name = client_name; if (get_pthread_create_impl()(&newthread, NULL, handle_entry, reinterpret_cast<void *>(ctx)) != 0) { perror("pthread_create1"); } // TODO(sholsapp): This shouldn't block, and we shouldn't just try to // join this thread. if (get_pthread_join_impl()(newthread, nullptr)) { perror("pthread_join1"); } } close(server_socket); return nullptr; }