1*1c60b9acSAndroid Build Coastguard Worker## LWS Allocated Chunks 2*1c60b9acSAndroid Build Coastguard Worker 3*1c60b9acSAndroid Build Coastguard Worker 4*1c60b9acSAndroid Build Coastguard Worker 5*1c60b9acSAndroid Build Coastguard WorkerThese apis provide a way to manage a linked-list of allocated chunks... 6*1c60b9acSAndroid Build Coastguard Worker 7*1c60b9acSAndroid Build Coastguard Worker[ HEAD alloc ] -> [ next alloc ] -> [ next alloc ] -> [ curr alloc ] 8*1c60b9acSAndroid Build Coastguard Worker 9*1c60b9acSAndroid Build Coastguard Worker... and sub-allocate trivially inside the chunks. These sub-allocations are 10*1c60b9acSAndroid Build Coastguard Workernot tracked by lwsac at all, there is a "used" high-water mark for each chunk 11*1c60b9acSAndroid Build Coastguard Workerthat's simply advanced by the amount sub-allocated. If the allocation size 12*1c60b9acSAndroid Build Coastguard Workermatches the platform pointer alignment, there is zero overhead to sub-allocate 13*1c60b9acSAndroid Build Coastguard Worker(otherwise the allocation is padded to the next platform pointer alignment 14*1c60b9acSAndroid Build Coastguard Workerautomatically). 15*1c60b9acSAndroid Build Coastguard Worker 16*1c60b9acSAndroid Build Coastguard WorkerIf you have an unknown amount of relatively little things to allocate, including 17*1c60b9acSAndroid Build Coastguard Workerstrings or other unstructured data, lwsac is significantly more efficient than 18*1c60b9acSAndroid Build Coastguard Workerindividual allocations using malloc or so. 19*1c60b9acSAndroid Build Coastguard Worker 20*1c60b9acSAndroid Build Coastguard Worker[lwsac full public api](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/lws-lwsac.h) 21*1c60b9acSAndroid Build Coastguard Worker 22*1c60b9acSAndroid Build Coastguard Worker## lwsac_use() api 23*1c60b9acSAndroid Build Coastguard Worker 24*1c60b9acSAndroid Build Coastguard Worker``` 25*1c60b9acSAndroid Build Coastguard Worker/** 26*1c60b9acSAndroid Build Coastguard Worker * lwsac_use - allocate / use some memory from a lwsac 27*1c60b9acSAndroid Build Coastguard Worker * 28*1c60b9acSAndroid Build Coastguard Worker * \param head: pointer to the lwsac list object 29*1c60b9acSAndroid Build Coastguard Worker * \param ensure: the number of bytes we want to use 30*1c60b9acSAndroid Build Coastguard Worker * \param chunk_size: 0, or the size of the chunk to (over)allocate if 31*1c60b9acSAndroid Build Coastguard Worker * what we want won't fit in the current tail chunk. If 32*1c60b9acSAndroid Build Coastguard Worker * 0, the default value of 4000 is used. If ensure is 33*1c60b9acSAndroid Build Coastguard Worker * larger, it is used instead. 34*1c60b9acSAndroid Build Coastguard Worker * 35*1c60b9acSAndroid Build Coastguard Worker * This also serves to init the lwsac if *head is NULL. Basically it does 36*1c60b9acSAndroid Build Coastguard Worker * whatever is necessary to return you a pointer to ensure bytes of memory 37*1c60b9acSAndroid Build Coastguard Worker * reserved for the caller. 38*1c60b9acSAndroid Build Coastguard Worker * 39*1c60b9acSAndroid Build Coastguard Worker * Returns NULL if OOM. 40*1c60b9acSAndroid Build Coastguard Worker */ 41*1c60b9acSAndroid Build Coastguard WorkerLWS_VISIBLE LWS_EXTERN void * 42*1c60b9acSAndroid Build Coastguard Workerlwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size); 43*1c60b9acSAndroid Build Coastguard Worker``` 44*1c60b9acSAndroid Build Coastguard Worker 45*1c60b9acSAndroid Build Coastguard WorkerWhen you make an sub-allocation using `lwsac_use()`, you can either 46*1c60b9acSAndroid Build Coastguard Workerset the `chunk_size` arg to zero, defaulting to 4000, or a specific chunk size. 47*1c60b9acSAndroid Build Coastguard WorkerIn the event the requested sub-allocation exceeds the chunk size, the chunk 48*1c60b9acSAndroid Build Coastguard Workersize is increated to match it automatically for this allocation only. 49*1c60b9acSAndroid Build Coastguard Worker 50*1c60b9acSAndroid Build Coastguard WorkerSubsequent `lwsac_use()` calls will advance internal pointers to use up the 51*1c60b9acSAndroid Build Coastguard Workerremaining space inside the current chunk if possible; if not enough remaining 52*1c60b9acSAndroid Build Coastguard Workerspace it is skipped, a new allocation is chained on and the request pointed to 53*1c60b9acSAndroid Build Coastguard Workerthere. 54*1c60b9acSAndroid Build Coastguard Worker 55*1c60b9acSAndroid Build Coastguard WorkerLwsac does not store information about sub-allocations. There is really zero 56*1c60b9acSAndroid Build Coastguard Workeroverhead for individual sub-allocations (unless their size is not 57*1c60b9acSAndroid Build Coastguard Workerpointer-aligned, in which case the actual amount sub-allocated is rounded up to 58*1c60b9acSAndroid Build Coastguard Workerthe next pointer alignment automatically). For structs, which are pointer- 59*1c60b9acSAndroid Build Coastguard Workeraligned naturally, and a chunk size relatively large for the sub-allocation 60*1c60b9acSAndroid Build Coastguard Workersize, lwsac is extremely efficient even for huge numbers of small allocations. 61*1c60b9acSAndroid Build Coastguard Worker 62*1c60b9acSAndroid Build Coastguard WorkerThis makes lwsac very effective when the total amount of allocation needed is 63*1c60b9acSAndroid Build Coastguard Workernot known at the start and may be large... it will simply add on chunks to cope 64*1c60b9acSAndroid Build Coastguard Workerwith whatever happens. 65*1c60b9acSAndroid Build Coastguard Worker 66*1c60b9acSAndroid Build Coastguard Worker## lwsac_free() api 67*1c60b9acSAndroid Build Coastguard Worker 68*1c60b9acSAndroid Build Coastguard Worker``` 69*1c60b9acSAndroid Build Coastguard Worker/** 70*1c60b9acSAndroid Build Coastguard Worker * lwsac_free - deallocate all chunks in the lwsac and set head NULL 71*1c60b9acSAndroid Build Coastguard Worker * 72*1c60b9acSAndroid Build Coastguard Worker * \param head: pointer to the lwsac list object 73*1c60b9acSAndroid Build Coastguard Worker * 74*1c60b9acSAndroid Build Coastguard Worker * This deallocates all chunks in the lwsac, then sets *head to NULL. All 75*1c60b9acSAndroid Build Coastguard Worker * lwsac_use() pointers are invalidated in one hit without individual frees. 76*1c60b9acSAndroid Build Coastguard Worker */ 77*1c60b9acSAndroid Build Coastguard WorkerLWS_VISIBLE LWS_EXTERN void 78*1c60b9acSAndroid Build Coastguard Workerlwsac_free(struct lwsac **head); 79*1c60b9acSAndroid Build Coastguard Worker``` 80*1c60b9acSAndroid Build Coastguard Worker 81*1c60b9acSAndroid Build Coastguard WorkerWhen you are finished with the lwsac, you simply free the chain of allocated 82*1c60b9acSAndroid Build Coastguard Workerchunks using lwsac_free() on the lwsac head. There's no tracking or individual 83*1c60b9acSAndroid Build Coastguard Workerdestruction of suballocations - the whole chain of chunks the suballocations 84*1c60b9acSAndroid Build Coastguard Workerlive in are freed and invalidated all together. 85*1c60b9acSAndroid Build Coastguard Worker 86*1c60b9acSAndroid Build Coastguard WorkerIf the structs stored in the lwsac allocated things **outside** the lwsac, then the 87*1c60b9acSAndroid Build Coastguard Workeruser must unwind through them and perform the frees. But the idea of lwsac is 88*1c60b9acSAndroid Build Coastguard Workerthings stored in the lwsac also suballocate into the lwsac, and point into the 89*1c60b9acSAndroid Build Coastguard Workerlwsac if they need to, avoiding any need to visit them during destroy. It's 90*1c60b9acSAndroid Build Coastguard Workerlike clearing up after a kids' party by gathering up a disposable tablecloth: 91*1c60b9acSAndroid Build Coastguard Workerno matter what was left on the table, it's all gone in one step. 92*1c60b9acSAndroid Build Coastguard Worker 93*1c60b9acSAndroid Build Coastguard Worker## `lws_list_ptr` helpers 94*1c60b9acSAndroid Build Coastguard Worker 95*1c60b9acSAndroid Build Coastguard Worker``` 96*1c60b9acSAndroid Build Coastguard Worker/* sort may be NULL if you don't care about order */ 97*1c60b9acSAndroid Build Coastguard WorkerLWS_VISIBLE LWS_EXTERN void 98*1c60b9acSAndroid Build Coastguard Workerlws_list_ptr_insert(lws_list_ptr *phead, lws_list_ptr *add, 99*1c60b9acSAndroid Build Coastguard Worker lws_list_ptr_sort_func_t sort); 100*1c60b9acSAndroid Build Coastguard Worker``` 101*1c60b9acSAndroid Build Coastguard Worker 102*1c60b9acSAndroid Build Coastguard WorkerA common pattern needed with sub-allocated structs is they are on one or more 103*1c60b9acSAndroid Build Coastguard Workerlinked-list. To make that simple to do cleanly, `lws_list...` apis are provided 104*1c60b9acSAndroid Build Coastguard Workeralong with a generic insertion function that can take a sort callback. These 105*1c60b9acSAndroid Build Coastguard Workerallow a struct to participate on multiple linked-lists simultaneously. 106*1c60b9acSAndroid Build Coastguard Worker 107*1c60b9acSAndroid Build Coastguard Worker## common const string and blob folding 108*1c60b9acSAndroid Build Coastguard Worker 109*1c60b9acSAndroid Build Coastguard WorkerIn some cases the input to be stored in the lwsac may repeat the same tokens 110*1c60b9acSAndroid Build Coastguard Workermultiple times... if the pattern is to store the string or blob in the lwsac 111*1c60b9acSAndroid Build Coastguard Workerand then point to it, you can make use of a helper api 112*1c60b9acSAndroid Build Coastguard Worker 113*1c60b9acSAndroid Build Coastguard Worker``` 114*1c60b9acSAndroid Build Coastguard Workeruint8_t * 115*1c60b9acSAndroid Build Coastguard Workerlwsac_scan_extant(struct lwsac *head, uint8_t *find, size_t len, int nul); 116*1c60b9acSAndroid Build Coastguard Worker``` 117*1c60b9acSAndroid Build Coastguard Worker 118*1c60b9acSAndroid Build Coastguard WorkerThis lets you check in all previous used parts of the lwsac for the same 119*1c60b9acSAndroid Build Coastguard Workerstring or blob, plus optionally a terminal NUL afterwards. If not found, 120*1c60b9acSAndroid Build Coastguard Workerit returns `NULL` and you can copy it into the lwsac as usual. If it is 121*1c60b9acSAndroid Build Coastguard Workerfound, a pointer is returned, and you can use this directly without copying 122*1c60b9acSAndroid Build Coastguard Workerthe string or blob in again. 123*1c60b9acSAndroid Build Coastguard Worker 124*1c60b9acSAndroid Build Coastguard Worker## optimizations to minimize overhead 125*1c60b9acSAndroid Build Coastguard Worker 126*1c60b9acSAndroid Build Coastguard WorkerIf the lwsac will persist in the system for some time, it's desirable to reduce 127*1c60b9acSAndroid Build Coastguard Workerthe memory needed as overhead. Overhead is created 128*1c60b9acSAndroid Build Coastguard Worker 129*1c60b9acSAndroid Build Coastguard Worker - once per chunk... in addition to the malloc overhead, there's an lwsac 130*1c60b9acSAndroid Build Coastguard Worker chunk header of 2 x pointers and 2 x size_t 131*1c60b9acSAndroid Build Coastguard Worker 132*1c60b9acSAndroid Build Coastguard Worker - at the unused part at the end that was allocated but not used 133*1c60b9acSAndroid Build Coastguard Worker 134*1c60b9acSAndroid Build Coastguard WorkerA good strategy is to make the initial allocation reflect the minimum expected 135*1c60b9acSAndroid Build Coastguard Workersize of the overall lwsac in one hit. Then use a chunk size that is a tradeoff 136*1c60b9acSAndroid Build Coastguard Workerbetween the number of chunks that might be needed and the fact that on average, 137*1c60b9acSAndroid Build Coastguard Workeryou can expect to waste half a chunk. For example if the storage is typically 138*1c60b9acSAndroid Build Coastguard Workerbetween 4K - 6K, you could allocate 4K or 4.5K for the first chunk and then fill 139*1c60b9acSAndroid Build Coastguard Workerin using 256 or 512 byte chunks. 140*1c60b9acSAndroid Build Coastguard Worker 141*1c60b9acSAndroid Build Coastguard WorkerYou can measure the overhead in an lwsac using `lwsac_total_overhead()`. 142*1c60b9acSAndroid Build Coastguard Worker 143*1c60b9acSAndroid Build Coastguard WorkerThe lwsac apis look first in the unused part of previous chunks, if any, and 144*1c60b9acSAndroid Build Coastguard Workerwill place new allocations there preferentially if they fit. This helps for the 145*1c60b9acSAndroid Build Coastguard Workercase lwsac was forced to allocate a new chunk because you asked for something 146*1c60b9acSAndroid Build Coastguard Workerlarge, while there was actually significant free space left in the old chunk, 147*1c60b9acSAndroid Build Coastguard Workerjust not enough for that particular allocation. Subsequent lwsac use can then 148*1c60b9acSAndroid Build Coastguard Worker"backfill" smaller things there to make best use of allocated space. 149