#include "packet_cache.h" void nn_packet_cache_init(struct nn_packet_cache *cache, u32 size) { al_array_init(cache->cache); al_array_reserve(cache->cache, size); cache->flush = (size > 0) ? size / 2 : 0; cache->disabled = false; nn_cond_init(&cache->cond); nn_mutex_init(&cache->mutex); } bool nn_packet_cache_available(struct nn_packet_cache *cache) { nn_mutex_lock(&cache->mutex); return !cache->disabled; } void nn_packet_cache_send_packet(struct nn_packet_cache *cache, struct nn_packet *packet) { al_assert(!cache->disabled); al_array_push(cache->cache, packet); bool flush = !packet || cache->cache.count >= cache->flush; if (flush && nn_cond_is_waiting(&cache->cond)) { nn_cond_signal(&cache->cond); } } void nn_packet_cache_flush(struct nn_packet_cache *cache) { nn_mutex_lock(&cache->mutex); if (nn_cond_is_waiting(&cache->cond)) { nn_cond_signal(&cache->cond); } nn_mutex_unlock(&cache->mutex); } bool nn_packet_cache_wait(struct nn_packet_cache *cache, u32 *count) { nn_mutex_lock(&cache->mutex); if (!cache->disabled && !cache->cache.count) { nn_cond_wait(&cache->cond, &cache->mutex); } // If there was an active wait before calling disable(), expected // behavior would be that wait() returns false. if (cache->disabled) { *count = 0; nn_mutex_unlock(&cache->mutex); return false; } *count = cache->cache.count; return true; } struct nn_packet *nn_packet_cache_at(struct nn_packet_cache *cache, u32 index) { return al_array_at(cache->cache, index); } void nn_packet_cache_lock(struct nn_packet_cache *cache) { nn_mutex_lock(&cache->mutex); } void nn_packet_cache_unlock(struct nn_packet_cache *cache) { nn_mutex_unlock(&cache->mutex); } void nn_packet_cache_disable(struct nn_packet_cache *cache) { nn_mutex_lock(&cache->mutex); cache->disabled = true; if (nn_cond_is_waiting(&cache->cond)) { nn_cond_signal(&cache->cond); } nn_mutex_unlock(&cache->mutex); } void nn_packet_cache_enable(struct nn_packet_cache *cache) { nn_mutex_lock(&cache->mutex); cache->disabled = false; nn_mutex_unlock(&cache->mutex); } void nn_packet_cache_free(struct nn_packet_cache *cache) { al_array_free(cache->cache); nn_mutex_destroy(&cache->mutex); nn_cond_destroy(&cache->cond); }