SPLAY_HEAD(mta_route_tree, mta_route); static void mta_imsg(struct imsgev *, struct imsg *); static void mta_shutdown(void); static void mta_sig_handler(int, short, void *); static struct mta_route *mta_route_for(struct envelope *); static void mta_route_drain(struct mta_route *); static void mta_route_free(struct mta_route *); static void mta_envelope_done(struct mta_task *, struct envelope *, const char *); static int mta_route_cmp(struct mta_route *, struct mta_route *); SPLAY_PROTOTYPE(mta_route_tree, mta_route, entry, mta_route_cmp); static struct mta_route_tree routes = SPLAY_INITIALIZER(&routes); static struct tree batches = SPLAY_INITIALIZER(&batches); void mta_imsg(struct imsgev *iev, struct imsg *imsg) { struct mta_route *route; struct mta_batch2 *batch; struct mta_task *task; struct envelope *e; struct ssl *ssl; uint64_t id; if (iev->proc == PROC_QUEUE) { switch (imsg->hdr.type) {
help(void) { fprintf(stderr, "usage: splay [-hnpx]\n" " -p number of threads (default: 2)\n" " -n number of repeats (default: 100)\n" " -a use adaptive lock (default)\n" " -l use lock only\n" " -t use transaction only\n" " -x transactional overhead (default: 5.0)\n" " -z number of instr. in transactional load (default: 50)\n" " -h show this\n"); exit(0); } SPLAY_HEAD(TREE,tree_node) tab = SPLAY_INITIALIZER(tab); typedef struct tree_node { long key; long value; SPLAY_ENTRY(tree_node) links; } tree_node; __attribute__((atomic ("l1"))) int node_cmp(tree_node* x,tree_node* y) { if (x == 0 || y == 0) abort(); return x->key - y->key; }
void (*cb)(void *, void *, void *); void *arg; }; struct waitq { SPLAY_ENTRY(waitq) entry; void *tag; TAILQ_HEAD(, waiter) waiters; }; static int waitq_cmp(struct waitq *, struct waitq *); SPLAY_HEAD(waitqtree, waitq); SPLAY_PROTOTYPE(waitqtree, waitq, entry, waitq_cmp); static struct waitqtree waitqs = SPLAY_INITIALIZER(&waitqs); static int waitq_cmp(struct waitq *a, struct waitq *b) { if (a->tag < b->tag) return (-1); if (a->tag > b->tag) return (1); return (0); } SPLAY_GENERATE(waitqtree, waitq, entry, waitq_cmp); int waitq_wait(void *tag, void (*cb)(void *, void *, void *), void *arg)
int is_reading; /* XXX remove this later */ int ext; struct ssl *ssl; }; static void mta_io(struct io *, int); static void mta_enter_state(struct mta_session *, int); static void mta_status(struct mta_session *, int, const char *, ...); static void mta_envelope_done(struct mta_task *, struct envelope *, const char *); static void mta_send(struct mta_session *, char *, ...); static ssize_t mta_queue_data(struct mta_session *); static void mta_response(struct mta_session *, char *); static const char * mta_strstate(int); static int mta_check_loop(FILE *); static struct tree sessions = SPLAY_INITIALIZER(&sessions); void mta_session(struct mta_route *route) { struct mta_session *session; session = xcalloc(1, sizeof *session, "mta_session"); session->id = generate_uid(); session->route = route; session->state = MTA_INIT; session->io.sock = -1; tree_xset(&sessions, session->id, session); TAILQ_INIT(&session->hosts); if (route->flags & ROUTE_MX)