about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--include/afl-fuzz.h5
-rw-r--r--src/afl-fuzz-queue.c8
2 files changed, 10 insertions, 3 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 880b8d50..220380b9 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -704,7 +704,10 @@ typedef struct afl_state {
   /* How many queue entries currently have cached testcases */
   u32 q_testcase_cache_count;
 
-  /* How often did we evict from the cache */
+  /* the smallest id currently known free entry */
+  u32 q_testcase_smallest_free;
+
+  /* How often did we evict from the cache (for statistics only) */
   u32 q_testcase_evictions;
 
   /* Refs to each queue entry with cached testcase (for eviction, if cache_count
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 3e6deb0c..db387c33 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -1004,13 +1004,15 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
       afl->q_testcase_cache[tid] = NULL;
       --afl->q_testcase_cache_count;
       ++afl->q_testcase_evictions;
+      if (tid < afl->q_testcase_smallest_free)
+        afl->q_testcase_smallest_free = tid;
 
     }
 
-    if (tid >= TESTCASE_ENTRIES) {
+    if (unlikely(tid >= TESTCASE_ENTRIES)) {
 
       // uh we were full, so now we have to search from start
-      tid = 0;
+      tid = afl->q_testcase_smallest_free;
 
     }
 
@@ -1042,6 +1044,8 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
     ++afl->q_testcase_cache_count;
     if (tid >= afl->q_testcase_max_cache_count)
       afl->q_testcase_max_cache_count = tid + 1;
+    if (tid == afl->q_testcase_smallest_free)
+      afl->q_testcase_smallest_free = tid + 1;
 
   }