Data Structures | Macros | Typedefs | Functions | Variables
cpuworker.c File Reference
#include "core/or/or.h"
#include "core/or/channel.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/connection_or.h"
#include "app/config/config.h"
#include "core/mainloop/cpuworker.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "core/or/onion.h"
#include "feature/relay/onion_queue.h"
#include "feature/stats/rephist.h"
#include "feature/relay/router.h"
#include "lib/evloop/workqueue.h"
#include "core/crypto/onion_crypto.h"
#include "core/or/or_circuit_st.h"
#include "lib/intmath/weakrng.h"

Go to the source code of this file.

Data Structures

struct  worker_state_s
struct  cpuworker_request_t
struct  cpuworker_reply_t
struct  cpuworker_job_u


#define worker_state_free(ws)   FREE_AND_NULL(worker_state_t, worker_state_free_, (ws))
#define CPUWORKER_REQUEST_MAGIC   0xda4afeed
#define CPUWORKER_REPLY_MAGIC   0x5eedf00d
#define MAX_BELIEVABLE_ONIONSKIN_DELAY   (2*1000*1000)


typedef struct worker_state_s worker_state_t
typedef struct cpuworker_request_t cpuworker_request_t
typedef struct cpuworker_reply_t cpuworker_reply_t
typedef struct cpuworker_job_u cpuworker_job_t


static void queue_pending_tasks (void)
static void * worker_state_new (void *arg)
static void worker_state_free_ (worker_state_t *ws)
static void worker_state_free_void (void *arg)
void cpu_init (void)
static workqueue_reply_t update_state_threadfn (void *state_, void *work_)
void cpuworkers_rotate_keyinfo (void)
static int should_time_request (uint16_t onionskin_type)
uint64_t estimated_usec_for_onionskins (uint32_t n_requests, uint16_t onionskin_type)
static int get_overhead_for_onionskins (uint32_t *usec_out, double *frac_out, uint16_t onionskin_type)
void cpuworker_log_onionskin_overhead (int severity, int onionskin_type, const char *onionskin_type_name)
static void cpuworker_onion_handshake_replyfn (void *work_)
static workqueue_reply_t cpuworker_onion_handshake_threadfn (void *state_, void *work_)
 MOCK_IMPL (workqueue_entry_t *, cpuworker_queue_work,(workqueue_priority_t priority, workqueue_reply_t(*fn)(void *, void *), void(*reply_fn)(void *), void *arg))
int assign_onionskin_to_cpuworker (or_circuit_t *circ, create_cell_t *onionskin)
void cpuworker_cancel_circ_handshake (or_circuit_t *circ)


static replyqueue_treplyqueue = NULL
static threadpool_tthreadpool = NULL
static tor_weak_rng_t request_sample_rng = TOR_WEAK_RNG_INIT
static int total_pending_tasks = 0
static int max_pending_tasks = 128
static uint64_t onionskins_n_processed [MAX_ONION_HANDSHAKE_TYPE+1]
static uint64_t onionskins_usec_internal [MAX_ONION_HANDSHAKE_TYPE+1]
static uint64_t onionskins_usec_roundtrip [MAX_ONION_HANDSHAKE_TYPE+1]

Detailed Description

Uses the workqueue/threadpool code to farm CPU-intensive activities out to subprocesses.

The multithreading backend for this module is in workqueue.c; this module specializes workqueue.c.

Right now, we use this infrastructure

Definition in file cpuworker.c.

Macro Definition Documentation


#define CPUWORKER_REQUEST_MAGIC   0xda4afeed

Magic numbers to make sure our cpuworker_requests don't grow any mis-framing bugs.

Definition at line 117 of file cpuworker.c.

Referenced by cpuworker_onion_handshake_threadfn().


#define MAX_BELIEVABLE_ONIONSKIN_DELAY   (2*1000*1000)

If any onionskin takes longer than this, we clip them to this time. (microseconds)

Definition at line 224 of file cpuworker.c.

Typedef Documentation

◆ cpuworker_reply_t

A reply sent by a cpuworker.

◆ cpuworker_request_t

A request sent to a cpuworker.

Function Documentation

◆ assign_onionskin_to_cpuworker()

int assign_onionskin_to_cpuworker ( or_circuit_t circ,
create_cell_t onionskin 

Try to tell a cpuworker to perform the public key operations necessary to respond to onionskin for the circuit circ.

Return 0 if we successfully assign the task, or -1 on failure.

Definition at line 516 of file cpuworker.c.

References tor_assert().

◆ cpu_init()

void cpu_init ( void  )

Initialize the cpuworker subsystem. It is OK to call this more than once during Tor's lifetime.

Definition at line 86 of file cpuworker.c.

◆ cpuworker_cancel_circ_handshake()

void cpuworker_cancel_circ_handshake ( or_circuit_t circ)

If circ has a pending handshake that hasn't been processed yet, remove it from the worker queue.

Definition at line 584 of file cpuworker.c.

References memwipe(), tor_assert(), tor_free, or_circuit_t::workqueue_entry, and workqueue_entry_cancel().

Referenced by onion_pending_remove().

◆ cpuworker_log_onionskin_overhead()

void cpuworker_log_onionskin_overhead ( int  severity,
int  onionskin_type,
const char *  onionskin_type_name 

If we've measured overhead for onionskins of type onionskin_type, log it.

Definition at line 295 of file cpuworker.c.

References get_overhead_for_onionskins(), LD_OR, and log_fn.

◆ cpuworker_onion_handshake_replyfn()

static void cpuworker_onion_handshake_replyfn ( void *  work_)

Handle a reply from the worker threads.

Definition at line 315 of file cpuworker.c.

References tor_assert().

◆ cpuworker_onion_handshake_threadfn()

static workqueue_reply_t cpuworker_onion_handshake_threadfn ( void *  state_,
void *  work_ 

◆ cpuworkers_rotate_keyinfo()

void cpuworkers_rotate_keyinfo ( void  )

Called when the onion key has changed so update all CPU worker(s) with new function pointers with which a new state will be generated.

Definition at line 192 of file cpuworker.c.

◆ estimated_usec_for_onionskins()

uint64_t estimated_usec_for_onionskins ( uint32_t  n_requests,
uint16_t  onionskin_type 

Return an estimate of how many microseconds we will need for a single cpuworker to process n_requests onionskins of type onionskin_type.

Definition at line 247 of file cpuworker.c.

◆ get_overhead_for_onionskins()

static int get_overhead_for_onionskins ( uint32_t *  usec_out,
double *  frac_out,
uint16_t  onionskin_type 

Compute the absolute and relative overhead of using the cpuworker framework for onionskins of type onionskin_type.

Definition at line 268 of file cpuworker.c.

Referenced by cpuworker_log_onionskin_overhead().


MOCK_IMPL ( workqueue_entry_t ,
cpuworker_queue_work  ,
(workqueue_priority_t priority, workqueue_reply_t(*fn)(void *, void *), void(*reply_fn)(void *), void *arg)   


Definition at line 495 of file cpuworker.c.

References tor_assert().

◆ queue_pending_tasks()

static void queue_pending_tasks ( void  )

Take pending tasks from the queue and assign them to cpuworkers.

Definition at line 478 of file cpuworker.c.

◆ should_time_request()

static int should_time_request ( uint16_t  onionskin_type)

Return true iff we'd like to measure a handshake of type onionskin_type. Call only from the main thread.

Otherwise, measure with P=1/128. We avoid doing this for every handshake, since the measurement itself can take a little time.

Definition at line 229 of file cpuworker.c.

Variable Documentation

◆ onionskins_n_processed

uint64_t onionskins_n_processed[MAX_ONION_HANDSHAKE_TYPE+1]

Indexed by handshake type: how many onionskins have we processed and counted of that type?

Definition at line 211 of file cpuworker.c.

◆ onionskins_usec_internal

uint64_t onionskins_usec_internal[MAX_ONION_HANDSHAKE_TYPE+1]

Indexed by handshake type, corresponding to the onionskins counted in onionskins_n_processed: how many microseconds have we spent in cpuworkers processing that kind of onionskin?

Definition at line 215 of file cpuworker.c.

◆ onionskins_usec_roundtrip

uint64_t onionskins_usec_roundtrip[MAX_ONION_HANDSHAKE_TYPE+1]

Indexed by handshake type, corresponding to onionskins counted in onionskins_n_processed: how many microseconds have we spent waiting for cpuworkers to give us answers for that kind of onionskin?

Definition at line 220 of file cpuworker.c.