678 if (_ix < NODE_T_STK_DEPTH) { \
679 _p->stk[_ix + 1] = 0; \
680 } \
681 }
682 #endif
683
684 #define NODE_TV_SZ 8192
685
686 extern struct node_ts node_tv[NODE_TV_SZ];
687 extern struct node_ts *node_tp;
688
689 #define NODE_T_TRACE(p, a) { \
690 struct node_ts *_p; \
691 struct node_ts *_np; \
692 int _ix; \
693 \
694 do { \
695 _p = node_tp; \
696 if ((_np = _p + 1) == &node_tv[NODE_TV_SZ]) \
697 _np = node_tv; \
698 } while (casptr(&node_tp, _p, _np) != _p); \
699 _p->node = (p); \
700 _p->action = (a); \
701 _p->ref = (p) ? (p)->ref : 0; \
702 _p->cnt = (p) ? (p)->cnt : 0; \
703 _p->cpu = CPU->cpu_seqid; \
704 NODE_T_TRACE_STK(); \
705 }
706
707 #else /* NODE_T_TRACE_ON */
708
709 #define NODE_T_TRACE(p, a)
710
711 #endif /* NODE_T_TRACE_ON */
712
713 /*
714 * DOOR_TRACE - trace door node_t events.
715 *
716 * adb:
717 * 32 bit
718 * *door_tp,0t8192-(((*door_tp)-door_tv)%0t112)/5XnPnPnPnPnPnPnPn64cnn
768 } \
769 }
770 #endif
771
772 #define DOOR_TV_SZ 8192
773
774 extern struct door_ts door_tv[DOOR_TV_SZ];
775 extern struct door_ts *door_tp;
776
777 #define DOOR_TRACE(io, d, d_sz, a) { \
778 nca_conn_t *_cp = (io) ? (nca_conn_t *)(io)->cid : (nca_conn_t *)NULL; \
779 node_t *_req_np = _cp ? _cp->req_np : (node_t *)NULL; \
780 struct door_ts *_p; \
781 struct door_ts *_np; \
782 int _ix; \
783 \
784 do { \
785 _p = door_tp; \
786 if ((_np = _p + 1) == &door_tv[DOOR_TV_SZ]) \
787 _np = door_tv; \
788 } while (casptr(&door_tp, _p, _np) != _p); \
789 _p->cp = _cp; \
790 _p->np = _req_np; \
791 _p->action = (a); \
792 _p->ref = _req_np ? _req_np->ref : 0; \
793 if ((io)) { \
794 _p->state = ((io)->op == http_op ? 0x80000000 : 0) | \
795 ((io)->more ? 0x40000000 : 0) | \
796 ((io)->first ? 0x20000000 : 0) | \
797 ((io)->advisory ? 0x10000000 : 0) | \
798 ((io)->nocache ? 0x08000000 : 0) | \
799 ((io)->preempt ? 0x04000000 : 0) | \
800 ((io)->peer_len ? 0x02000000 : 0) | \
801 ((io)->local_len ? 0x01000000 : 0) | \
802 ((io)->data_len ? 0x00800000 : 0) | \
803 (((io)->direct_type << 20) & 0x00700000) | \
804 ((io)->direct_len ? 0x00080000 : 0) | \
805 ((io)->trailer_len ? 0x00040000 : 0) | \
806 (((io)->peer_len + (io)->local_len + \
807 (io)->data_len + (io)->direct_len + \
808 (io)->trailer_len) & 0x3FFFF); \
970 }
971
972 #define DCB_WR_ENTER() { \
973 int cpu; \
974 int readers; \
975 \
976 mutex_enter(&nca_dcb_readers); \
977 mutex_enter(&nca_dcb_lock); \
978 for (;;) { \
979 readers = 0; \
980 for (cpu = 0; cpu < max_ncpus; cpu++) { \
981 int new; \
982 uint32_t *rp = &nca_gv[cpu].dcb_readers; \
983 int old = *rp; \
984 \
985 if (old & DCB_COUNT_USELOCK) { \
986 readers += old & DCB_COUNT_MASK; \
987 continue; \
988 } \
989 new = old | DCB_COUNT_USELOCK; \
990 while (cas32(rp, old, new) != old) { \
991 old = *rp; \
992 new = old | DCB_COUNT_USELOCK; \
993 } \
994 readers += (new & DCB_COUNT_MASK); \
995 } \
996 if (readers == 0) \
997 break; \
998 cv_wait(&nca_dcb_wait, &nca_dcb_lock); \
999 } \
1000 mutex_exit(&nca_dcb_lock); \
1001 }
1002
1003 #define DCB_WR_EXIT() { \
1004 int cpu; \
1005 \
1006 mutex_enter(&nca_dcb_lock); \
1007 for (cpu = 0; cpu < max_ncpus; cpu++) { \
1008 int new; \
1009 uint32_t *rp = &nca_gv[cpu].dcb_readers; \
1010 int old = *rp; \
1011 \
1012 new = old & ~DCB_COUNT_USELOCK; \
1013 while (cas32(rp, old, new) != old) { \
1014 old = *rp; \
1015 new = old & ~DCB_COUNT_USELOCK; \
1016 } \
1017 } \
1018 mutex_exit(&nca_dcb_lock); \
1019 mutex_exit(&nca_dcb_readers); \
1020 }
1021
1022 typedef struct nca_door_s {
1023 door_handle_t handle; /* The door handle */
1024 char *name; /* The door name */
1025 kmutex_t lock; /* The door lock */
1026 kcondvar_t cv_writer; /* condvar for thread waiting */
1027 /* to do door_init */
1028 kcondvar_t cv_reader; /* condvar for thread waiting */
1029 /* for a door_init to finish */
1030 uint32_t upcalls; /* Number of upcalls in progress */
1031 boolean_t init_waiting; /* door_init thread wanting to */
1032 /* be exclusive */
1033 } nca_door_t;
1526 if (_ix < NCA_CONN_T_STK_DEPTH) { \
1527 _p->stk[_ix + 1] = 0; \
1528 } \
1529 }
1530 #endif
1531
1532 #define CON_TV_SZ 4096
1533
1534 extern struct conn_ts con_tv[CON_TV_SZ];
1535 extern struct conn_ts *conn_tp;
1536
1537 #define NCA_CONN_T_TRACE(p, a) { \
1538 struct conn_ts *_p; \
1539 struct conn_ts *_np; \
1540 int _ix; \
1541 \
1542 do { \
1543 _p = conn_tp; \
1544 if ((_np = _p + 1) == &con_tv[CON_TV_SZ]) \
1545 _np = con_tv; \
1546 } while (casptr(&conn_tp, _p, _np) != _p); \
1547 _p->conn = (p); \
1548 _p->action = (a); \
1549 _p->ref = (p)->ref; \
1550 _p->cpu = CPU->cpu_seqid; \
1551 NCA_CONN_T_TRACE_STK(); \
1552 }
1553
1554 #else /* NCA_CONN_T_TRACE_ON */
1555
1556 #define NCA_CONN_T_TRACE(p, a)
1557
1558 #endif /* NCA_CONN_T_TRACE_ON */
1559
1560
1561 #define CONN_REFHOLD(connp) { \
1562 \
1563 NCA_CONN_T_TRACE((connp), NCA_CONN_T_REFHOLD | ((connp)->ref + 1)); \
1564 \
1565 if ((connp)->ref <= 0) \
1566 panic("nca CONN_REFHOLD: %p has no references", \
1748 unsigned long v;
1749 unsigned long nv;
1750 } nca_counter_t;
1751
1752 extern nca_counter_t nca_counter_tv[];
1753 extern nca_counter_t *nca_counter_tp;
1754
1755 #define NCA_COUNTER(_p, _v) { \
1756 unsigned long *p = _p; \
1757 long v = _v; \
1758 unsigned long _nv; \
1759 nca_counter_t *_otp; \
1760 nca_counter_t *_ntp; \
1761 \
1762 _nv = atomic_add_long_nv(p, v); \
1763 do { \
1764 _otp = nca_counter_tp; \
1765 _ntp = _otp + 1; \
1766 if (_ntp == &nca_counter_tv[NCA_COUNTER_TRACE_SZ]) \
1767 _ntp = nca_counter_tv; \
1768 } while (casptr((void *)&nca_counter_tp, (void *)_otp, \
1769 (void *)_ntp) != (void *)_otp); \
1770 _ntp->t = gethrtime(); \
1771 _ntp->p = p; \
1772 _ntp->v = v; \
1773 _ntp->nv = _nv; \
1774 }
1775
1776 #else /* NCA_COUNTER_TRACE */
1777
1778 #define NCA_COUNTER(p, v) atomic_add_long((p), (v))
1779
1780 #endif /* NCA_COUNTER_TRACE */
1781
1782
1783 /*
1784 * This is the buf used in upcall to httpd.
1785 */
1786 typedef struct {
1787 uintptr_t tid;
1788 char *buf;
|
678 if (_ix < NODE_T_STK_DEPTH) { \
679 _p->stk[_ix + 1] = 0; \
680 } \
681 }
682 #endif
683
684 #define NODE_TV_SZ 8192
685
686 extern struct node_ts node_tv[NODE_TV_SZ];
687 extern struct node_ts *node_tp;
688
689 #define NODE_T_TRACE(p, a) { \
690 struct node_ts *_p; \
691 struct node_ts *_np; \
692 int _ix; \
693 \
694 do { \
695 _p = node_tp; \
696 if ((_np = _p + 1) == &node_tv[NODE_TV_SZ]) \
697 _np = node_tv; \
698 } while (atomic_cas_ptr(&node_tp, _p, _np) != _p); \
699 _p->node = (p); \
700 _p->action = (a); \
701 _p->ref = (p) ? (p)->ref : 0; \
702 _p->cnt = (p) ? (p)->cnt : 0; \
703 _p->cpu = CPU->cpu_seqid; \
704 NODE_T_TRACE_STK(); \
705 }
706
707 #else /* NODE_T_TRACE_ON */
708
709 #define NODE_T_TRACE(p, a)
710
711 #endif /* NODE_T_TRACE_ON */
712
713 /*
714 * DOOR_TRACE - trace door node_t events.
715 *
716 * adb:
717 * 32 bit
718 * *door_tp,0t8192-(((*door_tp)-door_tv)%0t112)/5XnPnPnPnPnPnPnPn64cnn
768 } \
769 }
770 #endif
771
772 #define DOOR_TV_SZ 8192
773
774 extern struct door_ts door_tv[DOOR_TV_SZ];
775 extern struct door_ts *door_tp;
776
777 #define DOOR_TRACE(io, d, d_sz, a) { \
778 nca_conn_t *_cp = (io) ? (nca_conn_t *)(io)->cid : (nca_conn_t *)NULL; \
779 node_t *_req_np = _cp ? _cp->req_np : (node_t *)NULL; \
780 struct door_ts *_p; \
781 struct door_ts *_np; \
782 int _ix; \
783 \
784 do { \
785 _p = door_tp; \
786 if ((_np = _p + 1) == &door_tv[DOOR_TV_SZ]) \
787 _np = door_tv; \
788 } while (atomic_cas_ptr(&door_tp, _p, _np) != _p); \
789 _p->cp = _cp; \
790 _p->np = _req_np; \
791 _p->action = (a); \
792 _p->ref = _req_np ? _req_np->ref : 0; \
793 if ((io)) { \
794 _p->state = ((io)->op == http_op ? 0x80000000 : 0) | \
795 ((io)->more ? 0x40000000 : 0) | \
796 ((io)->first ? 0x20000000 : 0) | \
797 ((io)->advisory ? 0x10000000 : 0) | \
798 ((io)->nocache ? 0x08000000 : 0) | \
799 ((io)->preempt ? 0x04000000 : 0) | \
800 ((io)->peer_len ? 0x02000000 : 0) | \
801 ((io)->local_len ? 0x01000000 : 0) | \
802 ((io)->data_len ? 0x00800000 : 0) | \
803 (((io)->direct_type << 20) & 0x00700000) | \
804 ((io)->direct_len ? 0x00080000 : 0) | \
805 ((io)->trailer_len ? 0x00040000 : 0) | \
806 (((io)->peer_len + (io)->local_len + \
807 (io)->data_len + (io)->direct_len + \
808 (io)->trailer_len) & 0x3FFFF); \
970 }
971
972 #define DCB_WR_ENTER() { \
973 int cpu; \
974 int readers; \
975 \
976 mutex_enter(&nca_dcb_readers); \
977 mutex_enter(&nca_dcb_lock); \
978 for (;;) { \
979 readers = 0; \
980 for (cpu = 0; cpu < max_ncpus; cpu++) { \
981 int new; \
982 uint32_t *rp = &nca_gv[cpu].dcb_readers; \
983 int old = *rp; \
984 \
985 if (old & DCB_COUNT_USELOCK) { \
986 readers += old & DCB_COUNT_MASK; \
987 continue; \
988 } \
989 new = old | DCB_COUNT_USELOCK; \
990 while (atomic_cas_32(rp, old, new) != old) { \
991 old = *rp; \
992 new = old | DCB_COUNT_USELOCK; \
993 } \
994 readers += (new & DCB_COUNT_MASK); \
995 } \
996 if (readers == 0) \
997 break; \
998 cv_wait(&nca_dcb_wait, &nca_dcb_lock); \
999 } \
1000 mutex_exit(&nca_dcb_lock); \
1001 }
1002
1003 #define DCB_WR_EXIT() { \
1004 int cpu; \
1005 \
1006 mutex_enter(&nca_dcb_lock); \
1007 for (cpu = 0; cpu < max_ncpus; cpu++) { \
1008 int new; \
1009 uint32_t *rp = &nca_gv[cpu].dcb_readers; \
1010 int old = *rp; \
1011 \
1012 new = old & ~DCB_COUNT_USELOCK; \
1013 while (atomic_cas_32(rp, old, new) != old) { \
1014 old = *rp; \
1015 new = old & ~DCB_COUNT_USELOCK; \
1016 } \
1017 } \
1018 mutex_exit(&nca_dcb_lock); \
1019 mutex_exit(&nca_dcb_readers); \
1020 }
1021
1022 typedef struct nca_door_s {
1023 door_handle_t handle; /* The door handle */
1024 char *name; /* The door name */
1025 kmutex_t lock; /* The door lock */
1026 kcondvar_t cv_writer; /* condvar for thread waiting */
1027 /* to do door_init */
1028 kcondvar_t cv_reader; /* condvar for thread waiting */
1029 /* for a door_init to finish */
1030 uint32_t upcalls; /* Number of upcalls in progress */
1031 boolean_t init_waiting; /* door_init thread wanting to */
1032 /* be exclusive */
1033 } nca_door_t;
1526 if (_ix < NCA_CONN_T_STK_DEPTH) { \
1527 _p->stk[_ix + 1] = 0; \
1528 } \
1529 }
1530 #endif
1531
1532 #define CON_TV_SZ 4096
1533
1534 extern struct conn_ts con_tv[CON_TV_SZ];
1535 extern struct conn_ts *conn_tp;
1536
1537 #define NCA_CONN_T_TRACE(p, a) { \
1538 struct conn_ts *_p; \
1539 struct conn_ts *_np; \
1540 int _ix; \
1541 \
1542 do { \
1543 _p = conn_tp; \
1544 if ((_np = _p + 1) == &con_tv[CON_TV_SZ]) \
1545 _np = con_tv; \
1546 } while (atomic_cas_ptr(&conn_tp, _p, _np) != _p); \
1547 _p->conn = (p); \
1548 _p->action = (a); \
1549 _p->ref = (p)->ref; \
1550 _p->cpu = CPU->cpu_seqid; \
1551 NCA_CONN_T_TRACE_STK(); \
1552 }
1553
1554 #else /* NCA_CONN_T_TRACE_ON */
1555
1556 #define NCA_CONN_T_TRACE(p, a)
1557
1558 #endif /* NCA_CONN_T_TRACE_ON */
1559
1560
1561 #define CONN_REFHOLD(connp) { \
1562 \
1563 NCA_CONN_T_TRACE((connp), NCA_CONN_T_REFHOLD | ((connp)->ref + 1)); \
1564 \
1565 if ((connp)->ref <= 0) \
1566 panic("nca CONN_REFHOLD: %p has no references", \
1748 unsigned long v;
1749 unsigned long nv;
1750 } nca_counter_t;
1751
1752 extern nca_counter_t nca_counter_tv[];
1753 extern nca_counter_t *nca_counter_tp;
1754
1755 #define NCA_COUNTER(_p, _v) { \
1756 unsigned long *p = _p; \
1757 long v = _v; \
1758 unsigned long _nv; \
1759 nca_counter_t *_otp; \
1760 nca_counter_t *_ntp; \
1761 \
1762 _nv = atomic_add_long_nv(p, v); \
1763 do { \
1764 _otp = nca_counter_tp; \
1765 _ntp = _otp + 1; \
1766 if (_ntp == &nca_counter_tv[NCA_COUNTER_TRACE_SZ]) \
1767 _ntp = nca_counter_tv; \
1768 } while (atomic_cas_ptr((void *)&nca_counter_tp, (void *)_otp, \
1769 (void *)_ntp) != (void *)_otp); \
1770 _ntp->t = gethrtime(); \
1771 _ntp->p = p; \
1772 _ntp->v = v; \
1773 _ntp->nv = _nv; \
1774 }
1775
1776 #else /* NCA_COUNTER_TRACE */
1777
1778 #define NCA_COUNTER(p, v) atomic_add_long((p), (v))
1779
1780 #endif /* NCA_COUNTER_TRACE */
1781
1782
1783 /*
1784 * This is the buf used in upcall to httpd.
1785 */
1786 typedef struct {
1787 uintptr_t tid;
1788 char *buf;
|