#include "circular_buffer.h"
+#include <atomic>
+
#include "utils/util.h"
/* Circular buffer object */
struct _CircularBuffer
{
- uint64_t size; /* maximum number of elements */
- uint64_t start; /* index of oldest element, reader update only */
- uint64_t end; /* index to write new element, writer update only*/
- ElemType* elems; /* vector of elements */
+ uint64_t size; /* maximum number of elements */
+ std::atomic<uint64_t> start; /* index of oldest element, reader update only */
+ std::atomic<uint64_t> end; /* index to write new element, writer update only*/
+ ElemType* elems; /* vector of elements */
};
/* This approach adds one byte to end and start pointers */
CircularBuffer* cb = (CircularBuffer*)snort_calloc(sizeof(*cb));
cb->size = size + 1;
+ cb->start.store(0, std::memory_order_relaxed);
+ cb->end.store(0, std::memory_order_relaxed);
cb->elems = (ElemType*)snort_calloc(cb->size, sizeof(ElemType));
if (!cb->elems)
int cbuffer_is_full(CircularBuffer* cb)
{
- uint64_t next = cb->end + 1;
+ uint64_t next = cb->end.load(std::memory_order_relaxed) + 1;
if ( next == cb->size )
next = 0;
- return (next == cb->start);
+ return (next == cb->start.load(std::memory_order_acquire));
}
int cbuffer_is_empty(CircularBuffer* cb)
{
- return (cb->end == cb->start);
+ return (cb->end.load(std::memory_order_acquire) == cb->start.load(std::memory_order_relaxed));
}
/* Returns number of elements in use*/
uint64_t cbuffer_used(CircularBuffer* cb)
{
- /* cb->end < cb->start means passing the end of buffer */
- if (cb->end < cb->start)
- {
- return (cb->size + cb->end - cb->start);
- }
+ uint64_t end = cb->end.load(std::memory_order_acquire);
+ uint64_t start = cb->start.load(std::memory_order_acquire);
+
+ if (end < start)
+ return (cb->size + end - start);
else
- {
- return (cb->end - cb->start);
- }
+ return (end - start);
}
/* Returns total number of elements*/
*/
int cbuffer_write(CircularBuffer* cb, const ElemType elem)
{
- uint64_t w = cb->end;
+ uint64_t w = cb->end.load(std::memory_order_relaxed);
if ( cbuffer_is_full (cb)) /* full, return error */
{
if ( w == cb->size )
w = 0;
- cb->end = w;
+ cb->end.store(w, std::memory_order_release);
return CB_SUCCESS;
}
*/
int cbuffer_read(CircularBuffer* cb, ElemType* elem)
{
- uint64_t r = cb->start;
+ uint64_t r = cb->start.load(std::memory_order_relaxed);
if (cbuffer_is_empty(cb)) /* Empty, return error */
{
if ( r == cb->size )
r = 0;
- cb->start = r;
+ cb->start.store(r, std::memory_order_release);
return CB_SUCCESS;
}
void FileCache::set_block_timeout(int64_t timeout)
{
- std::lock_guard<std::mutex> lock(cache_mutex);
- block_timeout = timeout;
+ block_timeout.store(timeout, std::memory_order_relaxed);
}
void FileCache::set_lookup_timeout(int64_t timeout)
{
- std::lock_guard<std::mutex> lock(cache_mutex);
- lookup_timeout = timeout;
+ lookup_timeout.store(timeout, std::memory_order_relaxed);
}
void FileCache::set_max_files(int64_t max)
{
bool cache_full = false;
int64_t cache_expire = 0;
- return get_file(flow, file_id, to_create, lookup_timeout, using_cache_entry, cache_full, cache_expire);
+ return get_file(flow, file_id, to_create, lookup_timeout.load(std::memory_order_relaxed),
+ using_cache_entry, cache_full, cache_expire);
}
FileVerdict FileCache::check_verdict(Packet* p, FileInfo* file,
file_ctx->stop_file_capture();
return false;
case FILE_VERDICT_PENDING:
+ {
+ int64_t cur_lookup_timeout = lookup_timeout.load(std::memory_order_relaxed);
packet_gettimeofday(&now);
if (timerisset(&file_ctx->pending_expire_time) and
FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p,
"File signature lookup: timed out after %" PRIi64 "ms.\n",
- time_elapsed_ms(&now, &file_ctx->pending_expire_time, lookup_timeout));
+ time_elapsed_ms(&now, &file_ctx->pending_expire_time, cur_lookup_timeout));
if (PacketTracer::is_active())
{
- PacketTracer::log("File signature lookup: timed out after %" PRIi64 "ms.\n", time_elapsed_ms(&now, &file_ctx->pending_expire_time, lookup_timeout));
+ PacketTracer::log("File signature lookup: timed out after %" PRIi64 "ms.\n", time_elapsed_ms(&now, &file_ctx->pending_expire_time, cur_lookup_timeout));
}
}
else
if (!timerisset(&file_ctx->pending_expire_time))
{
- add_time = { static_cast<time_t>(lookup_timeout), 0 };
+ add_time = { static_cast<time_t>(cur_lookup_timeout), 0 };
timeradd(&now, &add_time, &file_ctx->pending_expire_time);
FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p,
// be there.
if (!(p->packet_flags & PKT_RETRANSMIT) or p->is_retry())
{
- PacketTracer::log("File signature lookup: adding packet to retry queue. Resume=%d, Waited %" PRIi64 "ms.\n", resume, time_elapsed_ms(&now, &file_ctx->pending_expire_time, lookup_timeout));
+ PacketTracer::log("File signature lookup: adding packet to retry queue. Resume=%d, Waited %" PRIi64 "ms.\n", resume, time_elapsed_ms(&now, &file_ctx->pending_expire_time, cur_lookup_timeout));
FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, p,
"File signature lookup adding packet to retry queue"
"Resume=%d, Waited %" PRIi64 "ms.\n", resume,
- time_elapsed_ms(&now, &file_ctx->pending_expire_time, lookup_timeout));
+ time_elapsed_ms(&now, &file_ctx->pending_expire_time, cur_lookup_timeout));
}
}
if (resume)
policy->log_file_action(flow, file_ctx, FILE_RESUME_BLOCK);
- else if (store_verdict(flow, file_ctx, lookup_timeout, cache_full, file_ctx->is_cacheable()) != 0)
+ else if (store_verdict(flow, file_ctx, cur_lookup_timeout, cache_full, file_ctx->is_cacheable()) != 0)
{
if (cache_full)
{
}
}
return true;
+ }
default:
return false;
}
}
else if (bool is_cacheable = file_ctx->is_cacheable())
{
- if (store_verdict(flow, file_ctx, block_timeout, cache_full, is_cacheable) != 0)
+ if (store_verdict(flow, file_ctx, block_timeout.load(std::memory_order_relaxed), cache_full, is_cacheable) != 0)
{
if (PacketTracer::is_active())
{