| ... | @@ -6277,10 +6277,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val | ... | @@ -6277,10 +6277,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 6277 | </li> | 6277 | </li> |
| 6278 | <li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely | 6278 | <li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely |
| 6279 | the right choice, at least for your main allocator.</li> | 6279 | the right choice, at least for your main allocator.</li> |
| 6280 | <li> | | |
| 6281 | Need to use the same allocator in multiple threads? Use one of your choice | | |
| 6282 | wrapped around {#syntax#}std.heap.ThreadSafeAllocator{#endsyntax#} | | |
| 6283 | </li> | | |
| 6284 | <li> | 6280 | <li> |
| 6285 | Is the maximum number of bytes that you will need bounded by a number known at | 6281 | Is the maximum number of bytes that you will need bounded by a number known at |
| 6286 | {#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#}. | 6282 | {#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#}. |
| ... | @@ -6290,7 +6286,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val | ... | @@ -6290,7 +6286,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 6290 | cyclical pattern (such as a video game main loop, or a web server request handler), | 6286 | cyclical pattern (such as a video game main loop, or a web server request handler), |
| 6291 | such that it would make sense to free everything at once at the end? | 6287 | such that it would make sense to free everything at once at the end? |
| 6292 | In this case, it is recommended to follow this pattern: | 6288 | In this case, it is recommended to follow this pattern: |
| 6293 | {#code|cli_allocation.zig#} | 6289 | {#code|cli_allocation.zig#} |
| 6294 | | 6290 | |
| 6295 | When using this kind of allocator, there is no need to free anything manually. Everything | 6291 | When using this kind of allocator, there is no need to free anything manually. Everything |
| 6296 | gets freed at once with the call to {#syntax#}arena.deinit(){#endsyntax#}. | 6292 | gets freed at once with the call to {#syntax#}arena.deinit(){#endsyntax#}. |
| ... | @@ -6313,14 +6309,18 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val | ... | @@ -6313,14 +6309,18 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 6313 | </li> | 6309 | </li> |
| 6314 | <li> | 6310 | <li> |
| 6315 | Finally, if none of the above apply, you need a general purpose allocator. | 6311 | Finally, if none of the above apply, you need a general purpose allocator. |
| 6316 | Zig's general purpose allocator is available as a function that takes a {#link|comptime#} | 6312 | If you are in Debug mode, {#syntax#}std.heap.DebugAllocator{#endsyntax#} is available as a |
| 6317 | {#link|struct#} of configuration options and returns a type. | 6313 | function that takes a {#link|comptime#} {#link|struct#} of configuration options and returns a type. |
| 6318 | Generally, you will set up one {#syntax#}std.heap.GeneralPurposeAllocator{#endsyntax#} in | 6314 | Generally, you will set up exactly one in your main function, and |
| 6319 | your main function, and then pass it or sub-allocators around to various parts of your | 6315 | then pass it or sub-allocators around to various parts of your |
| 6320 | application. | 6316 | application. |
| 6321 | </li> | 6317 | </li> |
| 6322 | <li> | 6318 | <li> |
| 6323 | You can also consider {#link|Implementing an Allocator#}. | 6319 | If you are compiling in ReleaseFast mode, {#syntax#}std.heap.smp_allocator{#endsyntax#} is |
| | 6320 | a solid choice for a general purpose allocator. |
| | 6321 | </li> |
| | 6322 | <li> |
| | 6323 | You can also consider implementing an allocator. |
| 6324 | </li> | 6324 | </li> |
| 6325 | </ol> | 6325 | </ol> |
| 6326 | {#header_close#} | 6326 | {#header_close#} |
| ... | @@ -6355,17 +6355,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val | ... | @@ -6355,17 +6355,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 6355 | <p>TODO: thread local variables</p> | 6355 | <p>TODO: thread local variables</p> |
| 6356 | {#header_close#} | 6356 | {#header_close#} |
| 6357 | | 6357 | |
| 6358 | {#header_open|Implementing an Allocator#} | | |
| 6359 | <p>Zig programmers can implement their own allocators by fulfilling the Allocator interface. | | |
| 6360 | In order to do this one must read carefully the documentation comments in std/mem.zig and | | |
| 6361 | then supply a {#syntax#}allocFn{#endsyntax#} and a {#syntax#}resizeFn{#endsyntax#}. | | |
| 6362 | </p> | | |
| 6363 | <p> | | |
| 6364 | There are many example allocators to look at for inspiration. Look at std/heap.zig and | | |
| 6365 | {#syntax#}std.heap.GeneralPurposeAllocator{#endsyntax#}. | | |
| 6366 | </p> | | |
| 6367 | {#header_close#} | | |
| 6368 | | | |
| 6369 | {#header_open|Heap Allocation Failure#} | 6358 | {#header_open|Heap Allocation Failure#} |
| 6370 | <p> | 6359 | <p> |
| 6371 | Many programming languages choose to handle the possibility of heap allocation failure by | 6360 | Many programming languages choose to handle the possibility of heap allocation failure by |