1 /* 2 * Copyright 2018 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can 5 * be found in the LICENSE file. 6 * 7 */ 8 9 #pragma once 10 11 // 12 // This is a suballocator for a large extent typically less than 4 GB. 13 // 14 // The SKC pipeline will use this for ephemeral host and device memory 15 // allocations. The lifetime of an allocation is typically 16 // milliseconds or less and is associated with either a single kernel 17 // or a sub-pipeline. 18 // 19 // Because of this, a relatively small number of allocations (10's) 20 // will be outstanding at any time so the implementation can 21 // reasonably be very simplistic and optimize for this case. 22 // 23 // Also, if either memory or subbuffer nodes aren't available the 24 // suballocator will block and pump the pipeline's scheduler until it 25 // can proceed. 26 // 27 // Note that this implementation is single-threaded and the 28 // suballocator's state may have been altered after pumping the 29 // scheduler. 30 // 31 32 #include "types.h" 33 34 // 35 // It's practical for the subbuf_id to be either 16 bits or maybe even 36 // 8 bits if the number of outstanding subbufs is in the thousands (16 37 // bits) or under 256 (8 bits). 38 // 39 40 typedef skc_ushort skc_subbuf_id_t; 41 typedef skc_uint skc_subbuf_size_t; // <4GB 42 // typedef size_t skc_subbuf_size_t; // >4GB 43 44 // 45 // 46 // 47 48 struct skc_subbuf 49 { 50 struct skc_subbuf * prev; 51 struct skc_subbuf * next; 52 53 skc_subbuf_size_t size; 54 skc_subbuf_size_t origin; 55 56 skc_uint idx; // ids[] index of subbuf in available state 57 skc_uint inuse; 58 }; 59 60 // 61 // 62 // 63 64 struct skc_suballocator 65 { 66 struct skc_subbuf * subbufs; 67 68 skc_subbuf_id_t * ids; // [<-AVAIL-><-empty-><-SPARE->] 69 70 struct { 71 skc_uint avail; 72 skc_uint spare; 73 } rem; // inuse = count - (avail + spare) 74 75 skc_uint align; // required pow2 alignment 76 skc_uint count; // number of subbufs 77 78 skc_subbuf_size_t size; // size of memory extent 79 skc_subbuf_size_t total; 80 81 char const * name; 82 }; 83 84 // 85 // 86 // 87 88 void 89 skc_suballocator_create(struct skc_runtime * const runtime, 90 struct skc_suballocator * const suballocator, 91 char const * const name, 92 skc_uint const subbufs, 93 size_t const align, 94 size_t const size); 95 96 void 97 skc_suballocator_dispose(struct skc_runtime * const runtime, 98 struct skc_suballocator * const suballocator); 99 100 // 101 // 102 // 103 104 size_t 105 skc_suballocator_subbuf_alloc(struct skc_suballocator * const suballocator, 106 struct skc_scheduler * const scheduler, 107 size_t const size, 108 skc_subbuf_id_t * const subbuf_id, 109 size_t * const subbuf_size); 110 111 void 112 skc_suballocator_subbuf_free(struct skc_suballocator * const suballocator, 113 skc_subbuf_id_t subbuf_id); 114 115 // 116 // 117 // 118