FreeBSD/sys/security/audit/audit_worker.c
/*
 * The audit_worker thread is responsible for watching the event queue,
 * dequeueing records, converting them to BSM format, and committing them to
 * disk.  In order to minimize lock thrashing, records are dequeued in sets
 * to a thread-local work queue.
 *
 * Note: this means that the effect bound on the size of the pending record
 * queue is 2x the length of the global queue.
 */
The audit_worker thread is responsible for watching the event queue,
dequeueing records, converting them to BSM format, and committing them to
disk.  In order to minimize lock thrashing, records are dequeued in sets
to a thread-local work queue.

this means that the effect bound on the size of the pending record
queue is 2x the length of the global queue.
The audit_worker thread is responsible for watching the event queue dequeueing records converting them to BSM format and committing them to disk . In order to minimize lock thrashing records are dequeued in sets to a thread - local work queue . this means that the effect bound on the size of the pending record queue is 2x the length of the global queue .
static void
audit_worker(void *arg)
{
	struct kaudit_queue ar_worklist;
	struct kaudit_record *ar;
	int lowater_signal;
	TAILQ_INIT(&ar_worklist);
	mtx_lock(&audit_mtx);
	while (1) {
		mtx_assert(&audit_mtx, MA_OWNED);
		while (TAILQ_EMPTY(&audit_q))
			cv_wait(&audit_worker_cv, &audit_mtx);
		lowater_signal = 0;
		while ((ar = TAILQ_FIRST(&audit_q))) {
			TAILQ_REMOVE(&audit_q, ar, k_q);
			audit_q_len--;
			if (audit_q_len == audit_qctrl.aq_lowater)
				lowater_signal++;
			TAILQ_INSERT_TAIL(&ar_worklist, ar, k_q);
		}
		if (lowater_signal)
			cv_broadcast(&audit_watermark_cv);
		mtx_unlock(&audit_mtx);
		while ((ar = TAILQ_FIRST(&ar_worklist))) {
			TAILQ_REMOVE(&ar_worklist, ar, k_q);
			audit_worker_process_record(ar);
			audit_free(ar);
		}
		mtx_lock(&audit_mtx);
	}
}
static void audit_worker ( void * arg ) { struct kaudit_queue ar_worklist ; struct kaudit_record * ar ; int lowater_signal ; TAILQ_INIT ( & ar_worklist ) ; mtx_lock ( & audit_mtx ) ; while ( 1 ) { mtx_assert ( & audit_mtx , MA_OWNED ) ; while ( TAILQ_EMPTY ( & audit_q ) ) cv_wait ( & audit_worker_cv , & audit_mtx ) ; lowater_signal = 0 ; while ( ( ar = TAILQ_FIRST ( & audit_q ) ) ) { TAILQ_REMOVE ( & audit_q , ar , k_q ) ; audit_q_len -- ; if ( audit_q_len == audit_qctrl . aq_lowater ) lowater_signal ++ ; TAILQ_INSERT_TAIL ( & ar_worklist , ar , k_q ) ; } if ( lowater_signal ) cv_broadcast ( & audit_watermark_cv ) ; mtx_unlock ( & audit_mtx ) ; while ( ( ar = TAILQ_FIRST ( & ar_worklist ) ) ) { TAILQ_REMOVE ( & ar_worklist , ar , k_q ) ; audit_worker_process_record ( ar ) ; audit_free ( ar ) ; } mtx_lock ( & audit_mtx ) ; } }
The audit_worker thread is responsible for watching the event queue,
 dequeueing records, converting them to BSM format, and committing them to
 disk.
The audit_worker thread is responsible for watching the event queue dequeueing records converting them to BSM format and committing them to disk .
/*
		 * Wait for a record.
		 */ /*
		 * If there are records in the global audit record queue,
		 * transfer them to a thread-local queue and process them
		 * one by one.  If we cross the low watermark threshold,
		 * signal any waiting processes that they may wake up and
		 * continue generating records.
		 */