1 // Copyright 2021 gRPC authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <grpc/support/port_platform.h> 16 17 #include <stdint.h> 18 #include <stdlib.h> 19 20 #include <memory> 21 #include <new> 22 #include <utility> 23 24 #include <grpc/event_engine/memory_allocator.h> 25 #include <grpc/event_engine/memory_request.h> 26 #include <grpc/slice.h> 27 28 #include "src/core/lib/slice/slice_refcount.h" 29 30 namespace grpc_event_engine { 31 namespace experimental { 32 33 namespace { 34 35 // Reference count for a slice allocated by MemoryAllocator::MakeSlice. 36 // Takes care of releasing memory back when the slice is destroyed. 37 class SliceRefCount : public grpc_slice_refcount { 38 public: SliceRefCount(std::shared_ptr<internal::MemoryAllocatorImpl> allocator,size_t size)39 SliceRefCount(std::shared_ptr<internal::MemoryAllocatorImpl> allocator, 40 size_t size) 41 : grpc_slice_refcount(Destroy), 42 allocator_(std::move(allocator)), 43 size_(size) { 44 // Nothing to do here. 45 } ~SliceRefCount()46 ~SliceRefCount() { allocator_->Release(size_); } 47 48 private: Destroy(grpc_slice_refcount * p)49 static void Destroy(grpc_slice_refcount* p) { 50 auto* rc = static_cast<SliceRefCount*>(p); 51 rc->~SliceRefCount(); 52 free(rc); 53 } 54 55 std::shared_ptr<internal::MemoryAllocatorImpl> allocator_; 56 size_t size_; 57 }; 58 59 } // namespace 60 MakeSlice(MemoryRequest request)61grpc_slice MemoryAllocator::MakeSlice(MemoryRequest request) { 62 auto size = Reserve(request.Increase(sizeof(SliceRefCount))); 63 void* p = malloc(size); 64 new (p) SliceRefCount(allocator_, size); 65 grpc_slice slice; 66 slice.refcount = static_cast<SliceRefCount*>(p); 67 slice.data.refcounted.bytes = 68 static_cast<uint8_t*>(p) + sizeof(SliceRefCount); 69 slice.data.refcounted.length = size - sizeof(SliceRefCount); 70 return slice; 71 } 72 73 } // namespace experimental 74 } // namespace grpc_event_engine 75