* Allocate 'count' items from our max_items limit. Returns the number * available. If M_NOWAIT is not specified it will sleep until at least * one item can be allocated. */
| 3940 | * one item can be allocated. |
| 3941 | */ |
| 3942 | static int |
| 3943 | zone_alloc_limit(uma_zone_t zone, int count, int flags) |
| 3944 | { |
| 3945 | uint64_t old; |
| 3946 | uint64_t max; |
| 3947 | |
| 3948 | max = zone->uz_max_items; |
| 3949 | MPASS(max > 0); |
| 3950 | |
| 3951 | /* |
| 3952 | * We expect normal allocations to succeed with a simple |
| 3953 | * fetchadd. |
| 3954 | */ |
| 3955 | old = atomic_fetchadd_64(&zone->uz_items, count); |
| 3956 | if (__predict_true(old + count <= max)) |
| 3957 | return (count); |
| 3958 | |
| 3959 | /* |
| 3960 | * If we had some items and no sleepers just return the |
| 3961 | * truncated value. We have to release the excess space |
| 3962 | * though because that may wake sleepers who weren't woken |
| 3963 | * because we were temporarily over the limit. |
| 3964 | */ |
| 3965 | if (old < max) { |
| 3966 | zone_free_limit(zone, (old + count) - max); |
| 3967 | return (max - old); |
| 3968 | } |
| 3969 | return (zone_alloc_limit_hard(zone, count, flags)); |
| 3970 | } |
| 3971 | |
| 3972 | /* |
| 3973 | * Free a number of items back to the limit. |
no test coverage detected