diff --git a/src/libs/compat/freebsd11_network/compat/sys/counter.h b/src/libs/compat/freebsd11_network/compat/sys/counter.h index d4133a46e3..3f0dd04701 100644 --- a/src/libs/compat/freebsd11_network/compat/sys/counter.h +++ b/src/libs/compat/freebsd11_network/compat/sys/counter.h @@ -1,12 +1,85 @@ /* - * Copyright 2017 Haiku Inc. All rights reserved. + * Copyright 2017-2018, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _FBSD_COMPAT_SYS_COUNTER_H_ #define _FBSD_COMPAT_SYS_COUNTER_H_ +#include +#include -typedef uint64_t *counter_u64_t; + +/* FreeBSD does not use atomics: it has a per-CPU data storage structure + * that it adds to whenever someone calls add(), and then only locks and + * coalesces it whenever fetch() is called. This means that on some + * architectures (e.g. x86_64), adding to the counter is one instruction. + * + * However, this seems to be for the most part overengineering, as its + * only uses seem to be statistical counting in semi-performance-critical paths. + * Axel noted in #12328 that there's a potential way to implement FreeBSD's + * method on Haiku using cpu_ent, but that atomics were "perfectly fine", + * so we will go with that for now. + */ + + +typedef uint64_t* counter_u64_t; + + +static inline counter_u64_t +counter_u64_alloc(int wait) +{ + return (counter_u64_t)_kernel_malloc(sizeof(uint64_t), wait | M_ZERO); +} + + +static inline void +counter_u64_free(counter_u64_t c) +{ + _kernel_free(c); +} + + +static inline void +counter_u64_add(counter_u64_t c, int64_t v) +{ + atomic_add64((int64*)c, v); +} + + +static inline uint64_t +counter_u64_fetch(counter_u64_t c) +{ + return atomic_get64((int64*)c); +} + + +static inline void +counter_u64_zero(counter_u64_t c) +{ + atomic_set64((int64*)c, 0); +} + + +static inline void +counter_enter() +{ + // unneeded; counters are atomic +} + + +static inline void +counter_exit() +{ + // unneeded; counters are atomic +} + + +static inline void +counter_u64_add_protected(counter_u64_t c, int64_t v) +{ + // counters are atomic + counter_u64_add(c, v); +} #endif