├── switch_code ├── netchain │ ├── p4src │ │ ├── actions.p4 │ │ ├── tables.p4 │ │ ├── includes │ │ │ ├── defines.p4 │ │ │ ├── parser.p4 │ │ │ └── headers.p4 │ │ ├── blackboxs.p4 │ │ ├── routing.p4 │ │ ├── tool.py │ │ └── netchain.p4 │ └── controller │ │ ├── config.py │ │ └── ports.json └── netlock │ ├── controller_init │ ├── config.py │ └── ports.json │ └── p4src │ ├── ptf-tests │ └── config.py │ ├── includes │ ├── defines.p4 │ ├── headers.p4 │ └── parser.p4 │ ├── routing.p4 │ ├── tool.py │ ├── actions.p4 │ ├── tables.p4 │ └── blackboxs.p4 ├── traces ├── tpcc_traces │ └── .gitignore └── microbenchmark │ └── micro_bm_gen.py ├── figures ├── 10a.jpg └── architecture.jpg ├── .gitignore ├── logs └── .gitignore ├── results └── .gitignore ├── dpdk_code ├── client_code │ ├── Makefile │ ├── build │ │ ├── .simple_socket.o.cmd │ │ ├── .simple_socket.cmd │ │ └── .simple_socket.o.d │ ├── include │ │ ├── txn_queue.h │ │ ├── think_queue.h │ │ ├── lock_queue.h │ │ ├── zipf.h │ │ └── new_order.h │ ├── txn_queue.c │ ├── README.md │ ├── think_queue.c │ ├── tpcc.py │ ├── lock_queue.c │ ├── tools.sh │ └── statistic.py ├── lock_server_code │ ├── Makefile │ ├── build │ │ ├── .simple_socket.o.cmd │ │ ├── .simple_socket.cmd │ │ └── .simple_socket.o.d │ ├── include │ │ ├── txn_queue.h │ │ ├── think_queue.h │ │ ├── new_order.h │ │ ├── lock_queue.h │ │ └── zipf.h │ ├── txn_queue.c │ ├── README.md │ ├── think_queue.c │ ├── tpcc.py │ ├── lock_queue.c │ ├── tools.sh │ └── statistic.py └── tools.sh ├── config.py ├── LICENSE └── README.md /switch_code/netchain/p4src/actions.p4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /switch_code/netchain/p4src/tables.p4: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /traces/tpcc_traces/.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | *.csv 3 | 4 | -------------------------------------------------------------------------------- /figures/10a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netx-repo/NetLock/HEAD/figures/10a.jpg -------------------------------------------------------------------------------- /figures/architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netx-repo/NetLock/HEAD/figures/architecture.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac 2 | .DS_Store 3 | 4 | # Excutable file 5 | bin/ 6 | 7 | # Playground 8 | playground/ 9 | 10 | *.pcap 11 | 12 | # Backup file 13 | *.bak 14 | *.bak.* 15 | 16 | # Python byte code 17 | *.pyc 18 | 19 | # Object file 20 | *.o 21 | 22 | *.e 23 | 24 | # Temp file 25 | *.swp 26 | *.tmp 27 | tmp.* 28 | 29 | # Data 30 | *.csv 31 | *.in 32 | *.out 33 | *.stat 34 | 35 | # Figures 36 | !*.pdf 37 | 38 | # Function code 39 | simulator.py 40 | 41 | *.zip 42 | 43 | *.res 44 | *.log 45 | *_bak/ 46 | .ipynb_checkpoints/ 47 | -------------------------------------------------------------------------------- /logs/.gitignore: -------------------------------------------------------------------------------- 1 | # Mac 2 | .DS_Store 3 | 4 | # Excutable file 5 | bin/ 6 | 7 | # Playground 8 | playground/ 9 | 10 | *.pcap 11 | 12 | # Backup file 13 | *.bak 14 | *.bak.* 15 | 16 | # Python byte code 17 | *.pyc 18 | 19 | # Object file 20 | *.o 21 | 22 | *.e 23 | 24 | # Temp file 25 | *.swp 26 | *.tmp 27 | tmp.* 28 | 29 | # Data 30 | *.csv 31 | *.in 32 | *.out 33 | *.stat 34 | 35 | # Figures 36 | !*.pdf 37 | 38 | # Function code 39 | simulator.py 40 | 41 | *.zip 42 | 43 | *.res 44 | *.log 45 | *_bak/ 46 | .ipynb_checkpoints/ 47 | -------------------------------------------------------------------------------- /results/.gitignore: -------------------------------------------------------------------------------- 1 | # Mac 2 | .DS_Store 3 | 4 | # Excutable file 5 | bin/ 6 | 7 | # Playground 8 | playground/ 9 | 10 | *.pcap 11 | 12 | # Backup file 13 | *.bak 14 | *.bak.* 15 | 16 | # Python byte code 17 | *.pyc 18 | 19 | # Object file 20 | *.o 21 | 22 | *.e 23 | 24 | # Temp file 25 | *.swp 26 | *.tmp 27 | tmp.* 28 | 29 | # Data 30 | *.csv 31 | *.in 32 | *.out 33 | *.stat 34 | 35 | # Figures 36 | !*.pdf 37 | 38 | # Function code 39 | simulator.py 40 | 41 | *.zip 42 | 43 | *.res 44 | *.log 45 | *_bak/ 46 | .ipynb_checkpoints/ 47 | -------------------------------------------------------------------------------- /switch_code/netlock/controller_init/config.py: -------------------------------------------------------------------------------- 1 | ADM_PORT = 7777 2 | LK_PORT = 8888 3 | REPLY_PORT = 8889 4 | DROP_PORT = 9999 5 | ACQUIRE_LOCK = 0 6 | RELEASE_LOCK = 1 7 | SHARED_LOCK = 0 8 | EXCLUSIVE_LOCK = 1 9 | COUNT_MAX = 16384 10 | NUM_LOCKS = 16384 11 | LENGTH_ARRAY = 16384 12 | SHRINK = 1 13 | MODIFY = 2 14 | DEDICATED_SERVER_IP = 101 15 | CONTROLLER_IP = 102 -------------------------------------------------------------------------------- /switch_code/netlock/p4src/ptf-tests/config.py: -------------------------------------------------------------------------------- 1 | ADM_PORT = 7777 2 | LK_PORT = 8888 3 | REPLY_PORT = 8889 4 | DROP_PORT = 9999 5 | ACQUIRE_LOCK = 0 6 | RELEASE_LOCK = 1 7 | SHARED_LOCK = 0 8 | EXCLUSIVE_LOCK = 1 9 | COUNT_MAX = 16384 10 | NUM_LOCKS = 16384 11 | LENGTH_ARRAY = 16384 12 | SHRINK = 1 13 | MODIFY = 2 14 | DEDICATED_SERVER_IP = 101 15 | CONTROLLER_IP = 102 -------------------------------------------------------------------------------- /dpdk_code/client_code/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(RTE_SDK),) 2 | $(error "Please define RTE_SDK environment variable") 3 | endif 4 | 5 | # Default target, can be overriden by command line or environment 6 | RTE_TARGET ?= x86_64-native-linuxapp-gcc 7 | 8 | include $(RTE_SDK)/mk/rte.vars.mk 9 | 10 | # binary name 11 | APP = client 12 | 13 | # all source are stored in SRCS-y 14 | SRCS-y = txn_queue.c client.c think_queue.c 15 | 16 | CFLAGS += -O3 # -g for gdb debugging 17 | EXTRA_CFLAGS= -I$(S)/include/ 18 | #CFLAGS += $(WERROR_FLAGS) 19 | 20 | include $(RTE_SDK)/mk/rte.extapp.mk 21 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(RTE_SDK),) 2 | $(error "Please define RTE_SDK environment variable") 3 | endif 4 | 5 | # Default target, can be overriden by command line or environment 6 | RTE_TARGET ?= x86_64-native-linuxapp-gcc 7 | 8 | include $(RTE_SDK)/mk/rte.vars.mk 9 | 10 | # binary name 11 | APP = server 12 | 13 | # all source are stored in SRCS-y 14 | SRCS-y = txn_queue.c server.c think_queue.c 15 | 16 | CFLAGS += -O3 # -g for gdb debugging 17 | EXTRA_CFLAGS= -I$(S)/include/ 18 | #CFLAGS += $(WERROR_FLAGS) 19 | 20 | include $(RTE_SDK)/mk/rte.extapp.mk 21 | -------------------------------------------------------------------------------- /switch_code/netchain/controller/config.py: -------------------------------------------------------------------------------- 1 | NC_PORT = 6666 2 | ADM_PORT = 7777 3 | LK_PORT = 8888 4 | REPLY_PORT = 8889 5 | DROP_PORT = 9999 6 | ACQUIRE_LOCK = 0 7 | RELEASE_LOCK = 1 8 | SHARED_LOCK = 0 9 | EXCLUSIVE_LOCK = 1 10 | COUNT_MAX = 16384 11 | NUM_LOCKS = 16384 12 | LENGTH_ARRAY = 16384 13 | SHRINK = 1 14 | MODIFY = 2 15 | DEDICATED_SERVER_IP = 101 16 | CONTROLLER_IP = 102 -------------------------------------------------------------------------------- /dpdk_code/client_code/build/.simple_socket.o.cmd: -------------------------------------------------------------------------------- 1 | cmd_simple_socket.o = gcc -Wp,-MD,./.simple_socket.o.d.tmp -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/user/hz/NetPB/client_dpdk/build/include -I/home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include -include /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_config.h -O3 -o simple_socket.o -c /home/user/hz/NetPB/client_dpdk/simple_socket.c 2 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/build/.simple_socket.o.cmd: -------------------------------------------------------------------------------- 1 | cmd_simple_socket.o = gcc -Wp,-MD,./.simple_socket.o.d.tmp -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/user/hz/NetPB/client_dpdk/build/include -I/home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include -include /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_config.h -O3 -o simple_socket.o -c /home/user/hz/NetPB/client_dpdk/simple_socket.c 2 | -------------------------------------------------------------------------------- /switch_code/netlock/p4src/includes/defines.p4: -------------------------------------------------------------------------------- 1 | #define ADM_PORT 7777 2 | #define LK_PORT 8888 3 | #define REPLY_PORT 8889 4 | #define DROP_PORT 9999 5 | #define PROBE_PORT 9998 6 | #define ACQUIRE_LOCK 0 7 | #define RELEASE_LOCK 1 8 | #define PUSH_BACK_LOCK 2 9 | #define GRANT_LOCK_FROM_SERVER 3 10 | #define REJECT_LOCK_ACQUIRE 4 11 | #define SHARED_LOCK 0 12 | #define EXCLUSIVE_LOCK 1 13 | #define NUM_LOCKS 55000 14 | #define LENGTH_ARRAY 130000 15 | #define SHRINK 1 16 | #define MODIFY 2 17 | #define DEDICATED_SERVER_IP 0x0a01000b 18 | #define CONTROLLER_IP 0x01010101 19 | #define CONTROLLER_IP 102 20 | #define RECIRCULATED_1 1 21 | #define RECIRCULATED_2 2 22 | #define PRIMARY_BACKUP 1 23 | #define SECONDARY_BACKUP 2 24 | #define FAILURE_NOTIFICATION 3 25 | #define NUM_TENANTS 12 -------------------------------------------------------------------------------- /switch_code/netchain/p4src/includes/defines.p4: -------------------------------------------------------------------------------- 1 | #define NC_PORT 6666 2 | #define ADM_PORT 7777 3 | #define LK_PORT 8888 4 | #define REPLY_PORT 8889 5 | #define DROP_PORT 9999 6 | #define PROBE_PORT 9998 7 | #define ACQUIRE_LOCK 0 8 | #define RELEASE_LOCK 1 9 | #define PUSH_BACK_LOCK 2 10 | #define GRANT_LOCK_FROM_SERVER 3 11 | #define REJECT_LOCK_ACQUIRE 4 12 | #define RETRY_LOCK 5 13 | #define SHARED_LOCK 0 14 | #define EXCLUSIVE_LOCK 1 15 | #define NUM_LOCKS 55000 16 | #define LENGTH_ARRAY 130000 17 | #define SHRINK 1 18 | #define MODIFY 2 19 | #define DEDICATED_SERVER_IP 0x0a01000b 20 | #define CONTROLLER_IP 0x01010101 21 | #define CONTROLLER_IP 102 22 | #define RECIRCULATED_1 1 23 | #define RECIRCULATED_2 2 24 | #define PRIMARY_BACKUP 1 25 | #define SECONDARY_BACKUP 2 26 | #define FAILURE_NOTIFICATION 3 27 | #define NUM_TENANTS 12 -------------------------------------------------------------------------------- /switch_code/netchain/p4src/blackboxs.p4: -------------------------------------------------------------------------------- 1 | blackbox stateful_alu acquire_lock_alu { 2 | reg: lock_status_register; 3 | 4 | update_lo_1_value: 1; 5 | 6 | output_value: register_lo; 7 | output_dst : meta.available; 8 | } 9 | 10 | blackbox stateful_alu release_lock_alu { 11 | reg: lock_status_register; 12 | 13 | update_lo_1_value: 0; 14 | } 15 | 16 | // blackbox stateful_alu acquire_lock_alu { 17 | // reg: lock_status_register; 18 | 19 | // update_lo_1_value: nc_hdr.txn_id; 20 | 21 | // output_value: register_lo; 22 | // output_dst : meta.available; 23 | // } 24 | 25 | // blackbox stateful_alu release_lock_alu { 26 | // reg: lock_status_register; 27 | 28 | // condition_lo: register_lo == nc_hdr.txn_id; 29 | 30 | // update_hi_1_predicate: condition_lo; 31 | // update_lo_1_value: 0; 32 | // } -------------------------------------------------------------------------------- /dpdk_code/client_code/include/txn_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef TXN_QUEUE_INCLUDED 2 | #define TXN_QUEUE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef struct TXNQueueNode { 9 | uint8_t mode; 10 | uint8_t op_type; 11 | uint32_t lock_id; 12 | struct TXNQueueNode *next; 13 | } txn_queue_node; 14 | 15 | typedef struct TXNQueueList { 16 | int size_of_queue; 17 | txn_queue_node *head; 18 | txn_queue_node *tail; 19 | } txn_queue_list; 20 | 21 | void txn_queue_init(txn_queue_list *q); 22 | 23 | int txn_enqueue(txn_queue_list *q, uint8_t mode, uint8_t opt, uint32_t lock_id); 24 | 25 | void txn_dequeue(txn_queue_list *q, uint8_t* mode, uint32_t* lock_id); 26 | 27 | void txn_queue_clear(txn_queue_list *q); 28 | 29 | int txn_get_queue_size(txn_queue_list *q); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/include/txn_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef TXN_QUEUE_INCLUDED 2 | #define TXN_QUEUE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef struct TXNQueueNode { 9 | uint8_t mode; 10 | uint8_t op_type; 11 | uint32_t lock_id; 12 | struct TXNQueueNode *next; 13 | } txn_queue_node; 14 | 15 | typedef struct TXNQueueList { 16 | int size_of_queue; 17 | txn_queue_node *head; 18 | txn_queue_node *tail; 19 | } txn_queue_list; 20 | 21 | void txn_queue_init(txn_queue_list *q); 22 | 23 | int txn_enqueue(txn_queue_list *q, uint8_t mode, uint8_t opt, uint32_t lock_id); 24 | 25 | void txn_dequeue(txn_queue_list *q, uint8_t* mode, uint32_t* lock_id); 26 | 27 | void txn_queue_clear(txn_queue_list *q); 28 | 29 | int txn_get_queue_size(txn_queue_list *q); 30 | 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /dpdk_code/client_code/include/think_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef THINK_QUEUE_INCLUDED 2 | #define THINK_QUEUE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef struct ThinkQueueNode { 9 | uint8_t mode; 10 | uint8_t client_id; 11 | uint32_t lock_id; 12 | uint32_t txnID; 13 | uint32_t ip_src; 14 | uint64_t timestamp; 15 | uint64_t grant_time; 16 | struct ThinkQueueNode *next; 17 | } think_queue_node; 18 | 19 | typedef struct ThinkQueueList { 20 | int size_of_queue; 21 | think_queue_node *head; 22 | think_queue_node *tail; 23 | } think_queue_list; 24 | 25 | void think_queue_init(think_queue_list *q); 26 | 27 | int think_enqueue(think_queue_list *q, uint8_t mode, uint32_t lock_id, uint32_t txn_id, uint8_t client_id, uint64_t grant_time); 28 | 29 | void think_dequeue(think_queue_list *q, uint8_t* mode, uint32_t* lock_id, uint32_t* txn_id, uint8_t* client_id); 30 | 31 | void think_queue_clear(think_queue_list *q); 32 | 33 | int think_get_queue_size(think_queue_list *q); 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/include/think_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef THINK_QUEUE_INCLUDED 2 | #define THINK_QUEUE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef struct ThinkQueueNode { 9 | uint8_t mode; 10 | uint8_t client_id; 11 | uint32_t lock_id; 12 | uint32_t txnID; 13 | uint32_t ip_src; 14 | uint64_t timestamp; 15 | uint64_t grant_time; 16 | struct ThinkQueueNode *next; 17 | } think_queue_node; 18 | 19 | typedef struct ThinkQueueList { 20 | int size_of_queue; 21 | think_queue_node *head; 22 | think_queue_node *tail; 23 | } think_queue_list; 24 | 25 | void think_queue_init(think_queue_list *q); 26 | 27 | int think_enqueue(think_queue_list *q, uint8_t mode, uint32_t lock_id, uint32_t txn_id, uint8_t client_id, uint64_t grant_time); 28 | 29 | void think_dequeue(think_queue_list *q, uint8_t* mode, uint32_t* lock_id, uint32_t* txn_id, uint8_t* client_id); 30 | 31 | void think_queue_clear(think_queue_list *q); 32 | 33 | int think_get_queue_size(think_queue_list *q); 34 | 35 | #endif 36 | 37 | -------------------------------------------------------------------------------- /switch_code/netchain/p4src/routing.p4: -------------------------------------------------------------------------------- 1 | action set_egress(egress_spec) { 2 | modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_spec); 3 | add_to_field(ipv4.ttl, -1); 4 | } 5 | 6 | @pragma stage 11 7 | table ipv4_route { 8 | reads { 9 | ipv4.dstAddr : exact; 10 | } 11 | actions { 12 | set_egress; 13 | _drop; 14 | } 15 | size : 8192; 16 | } 17 | 18 | action set_egress_2(egress_spec) { 19 | modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_spec); 20 | add_to_field(ipv4.ttl, -1); 21 | modify_field(meta.routed, 1); 22 | } 23 | 24 | @pragma stage 8 25 | table ipv4_route_2 { 26 | reads { 27 | ipv4.dstAddr : exact; 28 | // current_node_meta.ip_address: exact; 29 | } 30 | actions { 31 | set_egress_2; 32 | _drop; 33 | } 34 | size : 8192; 35 | } 36 | 37 | action ethernet_set_mac_act (smac, dmac) { 38 | modify_field (ethernet.srcAddr, smac); 39 | modify_field (ethernet.dstAddr, dmac); 40 | } 41 | 42 | table ethernet_set_mac { 43 | reads { 44 | ig_intr_md_for_tm.ucast_egress_port: exact; 45 | } 46 | actions { 47 | ethernet_set_mac_act; 48 | _no_op; 49 | } 50 | } 51 | 52 | action _no_op() { 53 | no_op(); 54 | } 55 | 56 | action _drop() { 57 | drop(); 58 | } 59 | -------------------------------------------------------------------------------- /switch_code/netlock/p4src/routing.p4: -------------------------------------------------------------------------------- 1 | action set_egress(egress_spec) { 2 | modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_spec); 3 | add_to_field(ipv4.ttl, -1); 4 | } 5 | 6 | @pragma stage 11 7 | table ipv4_route { 8 | reads { 9 | ipv4.dstAddr : exact; 10 | } 11 | actions { 12 | set_egress; 13 | _drop; 14 | } 15 | size : 8192; 16 | } 17 | 18 | action set_egress_2(egress_spec) { 19 | modify_field(ig_intr_md_for_tm.ucast_egress_port, egress_spec); 20 | add_to_field(ipv4.ttl, -1); 21 | modify_field(meta.routed, 1); 22 | } 23 | 24 | @pragma stage 8 25 | table ipv4_route_2 { 26 | reads { 27 | ipv4.dstAddr : exact; 28 | // current_node_meta.ip_address: exact; 29 | } 30 | actions { 31 | set_egress_2; 32 | _drop; 33 | } 34 | size : 8192; 35 | } 36 | 37 | action ethernet_set_mac_act (smac, dmac) { 38 | modify_field (ethernet.srcAddr, smac); 39 | modify_field (ethernet.dstAddr, dmac); 40 | } 41 | 42 | table ethernet_set_mac { 43 | reads { 44 | ig_intr_md_for_tm.ucast_egress_port: exact; 45 | } 46 | actions { 47 | ethernet_set_mac_act; 48 | _no_op; 49 | } 50 | } 51 | 52 | action _no_op() { 53 | no_op(); 54 | } 55 | 56 | action _drop() { 57 | drop(); 58 | } 59 | -------------------------------------------------------------------------------- /switch_code/netchain/controller/ports.json: -------------------------------------------------------------------------------- 1 | { 2 | "PortToVeth": [ 3 | { 4 | "device_port":0, 5 | "veth1":0, 6 | "veth2":1 7 | }, 8 | { 9 | "device_port":188, 10 | "veth1":48, 11 | "veth2":49 12 | }, 13 | { 14 | "device_port":184, 15 | "veth1":50, 16 | "veth2":51 17 | }, 18 | { 19 | "device_port":180, 20 | "veth1":52, 21 | "veth2":53 22 | }, 23 | { 24 | "device_port":176, 25 | "veth1":54, 26 | "veth2":55 27 | }, 28 | { 29 | "device_port":172, 30 | "veth1":56, 31 | "veth2":57 32 | }, 33 | { 34 | "device_port":168, 35 | "veth1":58, 36 | "veth2":59 37 | }, 38 | { 39 | "device_port":164, 40 | "veth1":60, 41 | "veth2":61 42 | }, 43 | { 44 | "device_port":160, 45 | "veth1":62, 46 | "veth2":63 47 | }, 48 | { 49 | "device_port":156, 50 | "veth1":40, 51 | "veth2":41 52 | }, 53 | { 54 | "device_port":152, 55 | "veth1":42, 56 | "veth2":43 57 | }, 58 | { 59 | "_comment": "Map ethernet CPU port 64 to veth250", 60 | "device_port":64, 61 | "veth1":250, 62 | "veth2":251 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /switch_code/netlock/controller_init/ports.json: -------------------------------------------------------------------------------- 1 | { 2 | "PortToVeth": [ 3 | { 4 | "device_port":0, 5 | "veth1":0, 6 | "veth2":1 7 | }, 8 | { 9 | "device_port":188, 10 | "veth1":48, 11 | "veth2":49 12 | }, 13 | { 14 | "device_port":184, 15 | "veth1":50, 16 | "veth2":51 17 | }, 18 | { 19 | "device_port":180, 20 | "veth1":52, 21 | "veth2":53 22 | }, 23 | { 24 | "device_port":176, 25 | "veth1":54, 26 | "veth2":55 27 | }, 28 | { 29 | "device_port":172, 30 | "veth1":56, 31 | "veth2":57 32 | }, 33 | { 34 | "device_port":168, 35 | "veth1":58, 36 | "veth2":59 37 | }, 38 | { 39 | "device_port":164, 40 | "veth1":60, 41 | "veth2":61 42 | }, 43 | { 44 | "device_port":160, 45 | "veth1":62, 46 | "veth2":63 47 | }, 48 | { 49 | "device_port":156, 50 | "veth1":40, 51 | "veth2":41 52 | }, 53 | { 54 | "device_port":152, 55 | "veth1":42, 56 | "veth2":43 57 | }, 58 | { 59 | "device_port":148, 60 | "veth1":44, 61 | "veth2":45 62 | }, 63 | { 64 | "device_port":144, 65 | "veth1":46, 66 | "veth2":47 67 | }, 68 | { 69 | "_comment": "Map ethernet CPU port 64 to veth250", 70 | "device_port":64, 71 | "veth1":250, 72 | "veth2":251 73 | } 74 | ] 75 | } 76 | -------------------------------------------------------------------------------- /dpdk_code/client_code/build/.simple_socket.cmd: -------------------------------------------------------------------------------- 1 | cmd_simple_socket = gcc -o simple_socket -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/user/hz/NetPB/client_dpdk/build/include -I/home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include -include /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_config.h -O3 simple_socket.o -L/home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/lib -Wl,-lrte_kni -Wl,-lrte_pipeline -Wl,-lrte_table -Wl,-lrte_port -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_reorder -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_sched -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_power -Wl,--whole-archive -Wl,-lrte_timer -Wl,-lrte_hash -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_cryptodev -Wl,-lrte_mempool -Wl,-lrte_ring -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_cfgfile -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_pmd_null_crypto -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-ldl -Wl,-export-dynamic -Wl,-export-dynamic -L/home/user/hz/NetPB/client_dpdk/build/lib -L/home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/lib -Wl,--as-needed -Wl,-Map=simple_socket.map -Wl,--cref 2 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/build/.simple_socket.cmd: -------------------------------------------------------------------------------- 1 | cmd_simple_socket = gcc -o simple_socket -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/user/hz/NetPB/client_dpdk/build/include -I/home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include -include /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_config.h -O3 simple_socket.o -L/home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/lib -Wl,-lrte_kni -Wl,-lrte_pipeline -Wl,-lrte_table -Wl,-lrte_port -Wl,-lrte_pdump -Wl,-lrte_distributor -Wl,-lrte_reorder -Wl,-lrte_ip_frag -Wl,-lrte_meter -Wl,-lrte_sched -Wl,-lrte_lpm -Wl,--whole-archive -Wl,-lrte_acl -Wl,--no-whole-archive -Wl,-lrte_jobstats -Wl,-lrte_power -Wl,--whole-archive -Wl,-lrte_timer -Wl,-lrte_hash -Wl,-lrte_vhost -Wl,-lrte_kvargs -Wl,-lrte_mbuf -Wl,-lrte_net -Wl,-lrte_ethdev -Wl,-lrte_cryptodev -Wl,-lrte_mempool -Wl,-lrte_ring -Wl,-lrte_eal -Wl,-lrte_cmdline -Wl,-lrte_cfgfile -Wl,-lrte_pmd_bond -Wl,-lrte_pmd_af_packet -Wl,-lrte_pmd_bnxt -Wl,-lrte_pmd_cxgbe -Wl,-lrte_pmd_e1000 -Wl,-lrte_pmd_ena -Wl,-lrte_pmd_enic -Wl,-lrte_pmd_fm10k -Wl,-lrte_pmd_i40e -Wl,-lrte_pmd_ixgbe -Wl,-lrte_pmd_null -Wl,-lrte_pmd_qede -Wl,-lrte_pmd_ring -Wl,-lrte_pmd_virtio -Wl,-lrte_pmd_vhost -Wl,-lrte_pmd_vmxnet3_uio -Wl,-lrte_pmd_null_crypto -Wl,--no-whole-archive -Wl,-lrt -Wl,-lm -Wl,-ldl -Wl,-export-dynamic -Wl,-export-dynamic -L/home/user/hz/NetPB/client_dpdk/build/lib -L/home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/lib -Wl,--as-needed -Wl,-Map=simple_socket.map -Wl,--cref 2 | -------------------------------------------------------------------------------- /dpdk_code/client_code/txn_queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void txn_queue_init(txn_queue_list *q) { 4 | q->size_of_queue = 0; 5 | q->head = NULL; 6 | q->tail = NULL; 7 | } 8 | 9 | int txn_enqueue(txn_queue_list *q, uint8_t mode, uint8_t opt, uint32_t lock_id) { 10 | txn_queue_node *new_node = (txn_queue_node *) malloc(sizeof(txn_queue_node)); 11 | if (new_node == NULL) { 12 | fprintf(stderr, "MALLOC ERROR.\n"); 13 | return -1; 14 | } 15 | 16 | new_node->mode = mode; 17 | new_node->op_type = opt; 18 | new_node->lock_id = lock_id; 19 | 20 | new_node->next = NULL; 21 | 22 | if (q->size_of_queue == 0) { 23 | q->head = new_node; 24 | q->tail = new_node; 25 | } 26 | else { 27 | q->tail->next = new_node; 28 | q->tail = new_node; 29 | } 30 | q->size_of_queue ++; 31 | return 0; 32 | } 33 | 34 | void txn_dequeue(txn_queue_list *q, uint8_t* mode, uint32_t* lock_id) { 35 | if ((q != NULL) && (q->size_of_queue > 0)) { 36 | txn_queue_node *temp = q->head; 37 | (*mode) = temp->mode; 38 | (*lock_id) = temp->lock_id; 39 | 40 | free(temp); 41 | if (q->size_of_queue > 1) { 42 | q->head = q->head->next; 43 | } 44 | else { 45 | q->head = NULL; 46 | q->tail = NULL; 47 | } 48 | 49 | q->size_of_queue --; 50 | 51 | } 52 | return; 53 | } 54 | 55 | void txn_queue_clear(txn_queue_list *q) { 56 | txn_queue_node *temp; 57 | while (q->size_of_queue > 0) { 58 | temp = q->head; 59 | q->head = temp->next; 60 | free(temp); 61 | q->size_of_queue --; 62 | } 63 | 64 | q->head = NULL; 65 | q->tail = NULL; 66 | return; 67 | } 68 | 69 | int txn_get_queue_size(txn_queue_list *q) { 70 | if (q == NULL) 71 | return 0; 72 | return q->size_of_queue; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/txn_queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void txn_queue_init(txn_queue_list *q) { 4 | q->size_of_queue = 0; 5 | q->head = NULL; 6 | q->tail = NULL; 7 | } 8 | 9 | int txn_enqueue(txn_queue_list *q, uint8_t mode, uint8_t opt, uint32_t lock_id) { 10 | txn_queue_node *new_node = (txn_queue_node *) malloc(sizeof(txn_queue_node)); 11 | if (new_node == NULL) { 12 | fprintf(stderr, "MALLOC ERROR.\n"); 13 | return -1; 14 | } 15 | 16 | new_node->mode = mode; 17 | new_node->op_type = opt; 18 | new_node->lock_id = lock_id; 19 | 20 | new_node->next = NULL; 21 | 22 | if (q->size_of_queue == 0) { 23 | q->head = new_node; 24 | q->tail = new_node; 25 | } 26 | else { 27 | q->tail->next = new_node; 28 | q->tail = new_node; 29 | } 30 | q->size_of_queue ++; 31 | return 0; 32 | } 33 | 34 | void txn_dequeue(txn_queue_list *q, uint8_t* mode, uint32_t* lock_id) { 35 | if ((q != NULL) && (q->size_of_queue > 0)) { 36 | txn_queue_node *temp = q->head; 37 | (*mode) = temp->mode; 38 | (*lock_id) = temp->lock_id; 39 | 40 | free(temp); 41 | if (q->size_of_queue > 1) { 42 | q->head = q->head->next; 43 | } 44 | else { 45 | q->head = NULL; 46 | q->tail = NULL; 47 | } 48 | 49 | q->size_of_queue --; 50 | 51 | } 52 | return; 53 | } 54 | 55 | void txn_queue_clear(txn_queue_list *q) { 56 | txn_queue_node *temp; 57 | while (q->size_of_queue > 0) { 58 | temp = q->head; 59 | q->head = temp->next; 60 | free(temp); 61 | q->size_of_queue --; 62 | } 63 | 64 | q->head = NULL; 65 | q->tail = NULL; 66 | return; 67 | } 68 | 69 | int txn_get_queue_size(txn_queue_list *q) { 70 | if (q == NULL) 71 | return 0; 72 | return q->size_of_queue; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/include/new_order.h: -------------------------------------------------------------------------------- 1 | // tpc-c 2 | #define DEBUG 3 | #ifndef TPCC 4 | #define TPCC 5 | #define ITEM_PER_WARE 100000 6 | #define DIST_PER_WARE 10 7 | #define CUST_PER_DIST 3000 8 | #define ROLL_BACK 0 9 | 10 | #include 11 | #include 12 | #include 13 | #include "new_order.h" 14 | 15 | #define min(a,b) \ 16 | ({ __typeof__ (a) _a = (a); \ 17 | __typeof__ (b) _b = (b); \ 18 | _a < _b ? _a : _b; }) 19 | // * C is a run-time constant randomly chosen within [0 .. A] that can be varied without altering performance. The same C value, per field (C_LAST, C_ID, and OL_I_ID), must be used by all emulated terminals. 20 | // * NURand(A,x,y)=(((random(0,A)| random(x,y))+C)%(y-x+1))+x 21 | 22 | // * 1: SHARED; 2: EXCLUSIVE; 8:TABLE_LOCK_SHARED; 9: TABLE_LOCK_EXCLUSIVE. 23 | 24 | static uint32_t get_random(uint32_t x, uint32_t y) { 25 | return ((rand() % (y - x + 1)) + x); 26 | } 27 | 28 | static uint32_t NURand(uint32_t A, uint32_t x, uint32_t y, uint32_t C) { 29 | return ((((get_random(0,A) | get_random(x,y)) + C) % (y-x+1)) + x); 30 | } 31 | 32 | static void get_batch_map(uint32_t *map) { 33 | FILE *fin, *fp; 34 | char filename[200]; 35 | char command[200]; 36 | int line_c = 0, a,b; 37 | sprintf(filename, "../batch/batch_%d.in", batch_size); 38 | sprintf(command, "wc -l %s | awk -F '[ ]'+ '{print $1}'", filename); 39 | DEBUG_PRINT("command: %s\n", command); 40 | fp = popen(command, "r"); 41 | if (fp == NULL) { 42 | fprintf(stderr, "Failed to run command\n"); 43 | return; 44 | } 45 | if (fscanf(fp, "%d", &line_c) == EOF) { 46 | fprintf(stderr, "RUN SHELL ERROR\n"); 47 | return; 48 | } 49 | fclose(fp); 50 | 51 | fin = fopen(filename, "r"); 52 | for (int i=0; i 2 | 3 | void think_queue_init(think_queue_list *q) { 4 | q->size_of_queue = 0; 5 | q->head = NULL; 6 | q->tail = NULL; 7 | } 8 | 9 | int think_enqueue(think_queue_list *q, uint8_t mode, uint32_t lock_id, uint32_t txn_id, uint8_t client_id, uint64_t grant_time) { 10 | think_queue_node *new_node = (think_queue_node *) malloc(sizeof(think_queue_node)); 11 | if (new_node == NULL) { 12 | fprintf(stderr, "MALLOC ERROR.\n"); 13 | return -1; 14 | } 15 | 16 | new_node->mode = mode; 17 | new_node->client_id = client_id; 18 | new_node->lock_id = lock_id; 19 | new_node->txnID = txn_id; 20 | // new_node->ip_src = ip_src_addr; 21 | // new_node->timestamp = timestamp; 22 | new_node->grant_time = grant_time; 23 | new_node->next = NULL; 24 | 25 | if (q->size_of_queue == 0) { 26 | q->head = new_node; 27 | q->tail = new_node; 28 | } 29 | else { 30 | q->tail->next = new_node; 31 | q->tail = new_node; 32 | } 33 | q->size_of_queue ++; 34 | return 0; 35 | } 36 | 37 | void think_dequeue(think_queue_list *q, uint8_t* mode, uint32_t* lock_id, uint32_t* txn_id, uint8_t* client_id) { 38 | if ((q != NULL) && (q->size_of_queue > 0)) { 39 | think_queue_node *temp = q->head; 40 | (*mode) = temp->mode; 41 | (*client_id) = temp->client_id; 42 | (*lock_id) = temp->lock_id; 43 | (*txn_id) = temp->txnID; 44 | // (*ip_src_addr) = temp->ip_src; 45 | // (*timestamp) = temp->timestamp; 46 | free(temp); 47 | if (q->size_of_queue > 1) { 48 | q->head = q->head->next; 49 | } 50 | else { 51 | q->head = NULL; 52 | q->tail = NULL; 53 | } 54 | 55 | q->size_of_queue --; 56 | 57 | } 58 | return; 59 | } 60 | 61 | void think_queue_clear(think_queue_list *q) { 62 | think_queue_node *temp; 63 | while (q->size_of_queue > 0) { 64 | temp = q->head; 65 | q->head = temp->next; 66 | free(temp); 67 | q->size_of_queue --; 68 | } 69 | 70 | q->head = NULL; 71 | q->tail = NULL; 72 | return; 73 | } 74 | 75 | int think_get_queue_size(think_queue_list *q) { 76 | if (q == NULL) 77 | return 0; 78 | return q->size_of_queue; 79 | } -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/think_queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void think_queue_init(think_queue_list *q) { 4 | q->size_of_queue = 0; 5 | q->head = NULL; 6 | q->tail = NULL; 7 | } 8 | 9 | int think_enqueue(think_queue_list *q, uint8_t mode, uint32_t lock_id, uint32_t txn_id, uint8_t client_id, uint64_t grant_time) { 10 | think_queue_node *new_node = (think_queue_node *) malloc(sizeof(think_queue_node)); 11 | if (new_node == NULL) { 12 | fprintf(stderr, "MALLOC ERROR.\n"); 13 | return -1; 14 | } 15 | 16 | new_node->mode = mode; 17 | new_node->client_id = client_id; 18 | new_node->lock_id = lock_id; 19 | new_node->txnID = txn_id; 20 | // new_node->ip_src = ip_src_addr; 21 | // new_node->timestamp = timestamp; 22 | new_node->grant_time = grant_time; 23 | new_node->next = NULL; 24 | 25 | if (q->size_of_queue == 0) { 26 | q->head = new_node; 27 | q->tail = new_node; 28 | } 29 | else { 30 | q->tail->next = new_node; 31 | q->tail = new_node; 32 | } 33 | q->size_of_queue ++; 34 | return 0; 35 | } 36 | 37 | void think_dequeue(think_queue_list *q, uint8_t* mode, uint32_t* lock_id, uint32_t* txn_id, uint8_t* client_id) { 38 | if ((q != NULL) && (q->size_of_queue > 0)) { 39 | think_queue_node *temp = q->head; 40 | (*mode) = temp->mode; 41 | (*client_id) = temp->client_id; 42 | (*lock_id) = temp->lock_id; 43 | (*txn_id) = temp->txnID; 44 | // (*ip_src_addr) = temp->ip_src; 45 | // (*timestamp) = temp->timestamp; 46 | free(temp); 47 | if (q->size_of_queue > 1) { 48 | q->head = q->head->next; 49 | } 50 | else { 51 | q->head = NULL; 52 | q->tail = NULL; 53 | } 54 | 55 | q->size_of_queue --; 56 | 57 | } 58 | return; 59 | } 60 | 61 | void think_queue_clear(think_queue_list *q) { 62 | think_queue_node *temp; 63 | while (q->size_of_queue > 0) { 64 | temp = q->head; 65 | q->head = temp->next; 66 | free(temp); 67 | q->size_of_queue --; 68 | } 69 | 70 | q->head = NULL; 71 | q->tail = NULL; 72 | return; 73 | } 74 | 75 | int think_get_queue_size(think_queue_list *q) { 76 | if (q == NULL) 77 | return 0; 78 | return q->size_of_queue; 79 | } -------------------------------------------------------------------------------- /switch_code/netlock/p4src/includes/headers.p4: -------------------------------------------------------------------------------- 1 | header_type ethernet_t { 2 | fields { 3 | dstAddr: 48; 4 | srcAddr: 48; 5 | etherType: 16; 6 | } 7 | } 8 | header ethernet_t ethernet; 9 | 10 | header_type ipv4_t { 11 | fields { 12 | version: 4; 13 | ihl: 4; 14 | diffserv: 8; 15 | totalLen: 16; 16 | identification: 16; 17 | flags: 3; 18 | fragOffset: 13; 19 | ttl: 8; 20 | protocol: 8; 21 | hdrChecksum: 16; 22 | srcAddr: 32; 23 | dstAddr: 32; 24 | } 25 | } 26 | header ipv4_t ipv4; 27 | 28 | header_type tcp_t { 29 | fields { 30 | srcPort: 16; 31 | dstPort: 16; 32 | seqNo: 32; 33 | ackNo: 32; 34 | dataOffset: 4; 35 | res: 3; 36 | ecn: 3; 37 | ctrl: 6; 38 | window: 16; 39 | checksum: 16; 40 | urgentPtr: 16; 41 | } 42 | } 43 | header tcp_t tcp; 44 | 45 | header_type udp_t { 46 | fields { 47 | srcPort: 16; 48 | dstPort: 16; 49 | pkt_length: 16; 50 | checksum: 16; 51 | } 52 | } 53 | header udp_t udp; 54 | 55 | header_type nlk_hdr_t { 56 | fields { 57 | recirc_flag: 8; 58 | op: 8; 59 | mode: 8; 60 | client_id: 8; 61 | tid: 32; 62 | lock: 32; 63 | timestamp_lo: 32; 64 | timestamp_hi: 32; 65 | } 66 | 67 | } 68 | header nlk_hdr_t nlk_hdr; 69 | 70 | header_type adm_hdr_t { 71 | fields { 72 | op: 8; 73 | lock: 32; 74 | new_left: 32; 75 | new_right:32; 76 | } 77 | } 78 | header adm_hdr_t adm_hdr; 79 | 80 | header_type recirculate_hdr_t { 81 | fields { 82 | dequeued_mode: 8; 83 | cur_head: 32; 84 | cur_tail: 32; 85 | } 86 | } 87 | header recirculate_hdr_t recirculate_hdr; 88 | 89 | header_type probe_hdr_t { 90 | fields { 91 | failure_status: 8; 92 | op: 8; 93 | mode: 8; 94 | client_id: 8; 95 | tid: 32; 96 | lock: 32; 97 | timestamp_lo: 32; 98 | timestamp_hi: 32; 99 | } 100 | } 101 | header probe_hdr_t probe_hdr; -------------------------------------------------------------------------------- /switch_code/netlock/p4src/includes/parser.p4: -------------------------------------------------------------------------------- 1 | parser start { 2 | return parse_ethernet; 3 | } 4 | 5 | parser parse_ethernet { 6 | extract (ethernet); 7 | return select (latest.etherType) { 8 | 0x0800: parse_ipv4; 9 | default: ingress; 10 | } 11 | } 12 | 13 | parser parse_ipv4 { 14 | extract (ipv4); 15 | return select (latest.protocol) { 16 | 6: parse_tcp; 17 | 17: parse_udp; 18 | default: ingress; 19 | } 20 | } 21 | 22 | field_list ipv4_field_list { 23 | ipv4.version; 24 | ipv4.ihl; 25 | ipv4.diffserv; 26 | ipv4.totalLen; 27 | ipv4.identification; 28 | ipv4.flags; 29 | ipv4.fragOffset; 30 | ipv4.ttl; 31 | ipv4.protocol; 32 | ipv4.srcAddr; 33 | ipv4.dstAddr; 34 | } 35 | 36 | field_list_calculation ipv4_chksum_calc { 37 | input { 38 | ipv4_field_list; 39 | } 40 | algorithm: csum16; 41 | output_width: 16; 42 | } 43 | 44 | calculated_field ipv4.hdrChecksum { 45 | update ipv4_chksum_calc; 46 | } 47 | 48 | parser parse_tcp { 49 | extract (tcp); 50 | return ingress; 51 | } 52 | 53 | parser parse_udp { 54 | extract (udp); 55 | return select (latest.dstPort) { 56 | PROBE_PORT: parse_probe_hdr; 57 | LK_PORT: parse_nlk_hdr; 58 | REPLY_PORT: parse_nlk_hdr; 59 | ADM_PORT: parse_adm_hdr; 60 | default: ingress; 61 | } 62 | } 63 | 64 | /* 65 | field_list udp_field_list { 66 | udp.srcPort; 67 | udp.dstPort; 68 | udp.pkt_length; 69 | udp.checksum; 70 | } 71 | 72 | field_list_calculation udp_chksum_calc { 73 | input { 74 | udp_field_list; 75 | } 76 | algorithm: csum16; 77 | output_width: 16; 78 | } 79 | 80 | calculated_field udp.checksum { 81 | update udp_chksum_calc; 82 | } 83 | */ 84 | 85 | parser parse_nlk_hdr { 86 | extract (nlk_hdr); 87 | return select (latest.recirc_flag) { 88 | RECIRCULATED_1: parse_recirculate_hdr; 89 | RECIRCULATED_2: parse_recirculate_hdr; 90 | default: ingress; 91 | } 92 | } 93 | 94 | parser parse_recirculate_hdr { 95 | extract (recirculate_hdr); 96 | return ingress; 97 | } 98 | 99 | parser parse_adm_hdr { 100 | extract (adm_hdr); 101 | return ingress; 102 | } 103 | 104 | parser parse_probe_hdr { 105 | extract (probe_hdr); 106 | return ingress; 107 | } 108 | -------------------------------------------------------------------------------- /switch_code/netchain/p4src/tool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from __future__ import print_function 4 | import sys, os, time, subprocess, random 5 | 6 | p4_build = "/home/zhuolong/bf-sde-8.2.2/p4_build.sh" 7 | run_tofino_model = "/home/zhuolong/bf-sde-8.2.2/run_tofino_model.sh" 8 | run_switchd = "/home/zhuolong/bf-sde-8.2.2/run_switchd.sh" 9 | run_p4_tests = "/home/zhuolong/bf-sde-8.2.2/run_p4_tests.sh" 10 | set_sde = "/home/zhuolong/bf-sde-8.2.2/set_sde.bash" 11 | 12 | sys_name = "netlock" 13 | target_mode = "hw" 14 | 15 | def exe_cmd(cmd): 16 | #print "\t", cmd 17 | subprocess.call(cmd, shell=True) 18 | 19 | def sync(): 20 | exe_cmd("rsync -r * netx3:~/xinjin/p4src") 21 | 22 | def compile(file_name): 23 | print("Try 'source ~/bf-sde-6.1.1.31/set_sde.bash' for debugging") 24 | exe_cmd("%s %s" % (p4_build, file_name)) 25 | 26 | def start_switch(p4_name): 27 | #exe_cmd("%s -p %s >tofino.log 2>&1 &" % (run_tofino_model, p4_name)) 28 | print("%s -p %s" % (run_switchd, p4_name)) 29 | exe_cmd("%s -p %s" % (run_switchd, p4_name)) 30 | 31 | def ptf_test(folder_name, lock_num): 32 | ports_map = folder_name + "/ports.json" 33 | print("%s -t %s -p %s -f %s --target %s" % (run_p4_tests, folder_name, sys_name, ports_map, target_mode)) 34 | exe_cmd("%s -t %s -p %s -f %s --target %s --test-params=\"bm=\'x\';lk=\'%s\'\"" % (run_p4_tests, folder_name, sys_name, ports_map, target_mode, lock_num)) 35 | 36 | def stop_switch(): 37 | exe_cmd("ps -ef | grep tofino | grep -v grep | " \ 38 | "awk '{print $2}' | xargs sudo kill -9") 39 | 40 | if __name__ == "__main__": 41 | if len(sys.argv) <= 1: 42 | print("Usage") 43 | print(" tool.py sync") 44 | print(" tool.py init") 45 | print(" tool.py compile helloworld.p4") 46 | print(" tool.py start_switch helloworld") 47 | print(" tool.py stop_switch") 48 | print(" tool.py ptf_test helloworld/ptf-tests lock_num") 49 | sys.exit() 50 | 51 | if sys.argv[1] == "sync": 52 | sync() 53 | elif sys.argv[1] == "compile": 54 | compile(sys.argv[2]) 55 | elif sys.argv[1] == "start_switch": 56 | start_switch(sys.argv[2]) 57 | elif sys.argv[1] == "stop_switch": 58 | stop_switch() 59 | elif sys.argv[1] == "ptf_test": 60 | if (len(sys.argv) <=2): 61 | print("Not supported option)") 62 | else: 63 | ptf_test(sys.argv[2], sys.argv[3]) 64 | else: 65 | print("Not supported option") 66 | -------------------------------------------------------------------------------- /switch_code/netlock/p4src/tool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from __future__ import print_function 4 | import sys, os, time, subprocess, random 5 | 6 | p4_build = "/home/zhuolong/bf-sde-8.2.2/p4_build.sh" 7 | run_tofino_model = "/home/zhuolong/bf-sde-8.2.2/run_tofino_model.sh" 8 | run_switchd = "/home/zhuolong/bf-sde-8.2.2/run_switchd.sh" 9 | run_p4_tests = "/home/zhuolong/bf-sde-8.2.2/run_p4_tests.sh" 10 | set_sde = "/home/zhuolong/bf-sde-8.2.2/set_sde.bash" 11 | 12 | sys_name = "netlock" 13 | target_mode = "hw" 14 | 15 | def exe_cmd(cmd): 16 | #print "\t", cmd 17 | subprocess.call(cmd, shell=True) 18 | 19 | def sync(): 20 | exe_cmd("rsync -r * netx3:~/xinjin/p4src") 21 | 22 | def compile(file_name): 23 | print("Try 'source ~/bf-sde-6.1.1.31/set_sde.bash' for debugging") 24 | exe_cmd("%s %s" % (p4_build, file_name)) 25 | 26 | def start_switch(p4_name): 27 | #exe_cmd("%s -p %s >tofino.log 2>&1 &" % (run_tofino_model, p4_name)) 28 | print("%s -p %s" % (run_switchd, p4_name)) 29 | exe_cmd("%s -p %s" % (run_switchd, p4_name)) 30 | 31 | def ptf_test(folder_name, lock_num): 32 | ports_map = folder_name + "/ports.json" 33 | print("%s -t %s -p %s -f %s --target %s" % (run_p4_tests, folder_name, sys_name, ports_map, target_mode)) 34 | exe_cmd("%s -t %s -p %s -f %s --target %s --test-params=\"bm=\'x\';lk=\'%s\'\"" % (run_p4_tests, folder_name, sys_name, ports_map, target_mode, lock_num)) 35 | 36 | def stop_switch(): 37 | exe_cmd("ps -ef | grep tofino | grep -v grep | " \ 38 | "awk '{print $2}' | xargs sudo kill -9") 39 | 40 | if __name__ == "__main__": 41 | if len(sys.argv) <= 1: 42 | print("Usage") 43 | print(" tool.py sync") 44 | print(" tool.py init") 45 | print(" tool.py compile helloworld.p4") 46 | print(" tool.py start_switch helloworld") 47 | print(" tool.py stop_switch") 48 | print(" tool.py ptf_test helloworld/ptf-tests lock_num") 49 | sys.exit() 50 | 51 | if sys.argv[1] == "sync": 52 | sync() 53 | elif sys.argv[1] == "compile": 54 | compile(sys.argv[2]) 55 | elif sys.argv[1] == "start_switch": 56 | start_switch(sys.argv[2]) 57 | elif sys.argv[1] == "stop_switch": 58 | stop_switch() 59 | elif sys.argv[1] == "ptf_test": 60 | if (len(sys.argv) <=2): 61 | print("Not supported option)") 62 | else: 63 | ptf_test(sys.argv[2], sys.argv[3]) 64 | else: 65 | print("Not supported option") 66 | -------------------------------------------------------------------------------- /switch_code/netchain/p4src/includes/parser.p4: -------------------------------------------------------------------------------- 1 | parser start { 2 | return parse_ethernet; 3 | } 4 | 5 | parser parse_ethernet { 6 | extract (ethernet); 7 | return select (latest.etherType) { 8 | 0x0800: parse_ipv4; 9 | default: ingress; 10 | } 11 | } 12 | 13 | parser parse_ipv4 { 14 | extract (ipv4); 15 | return select (latest.protocol) { 16 | 6: parse_tcp; 17 | 17: parse_udp; 18 | default: ingress; 19 | } 20 | } 21 | 22 | field_list ipv4_field_list { 23 | ipv4.version; 24 | ipv4.ihl; 25 | ipv4.diffserv; 26 | ipv4.totalLen; 27 | ipv4.identification; 28 | ipv4.flags; 29 | ipv4.fragOffset; 30 | ipv4.ttl; 31 | ipv4.protocol; 32 | ipv4.srcAddr; 33 | ipv4.dstAddr; 34 | } 35 | 36 | field_list_calculation ipv4_chksum_calc { 37 | input { 38 | ipv4_field_list; 39 | } 40 | algorithm: csum16; 41 | output_width: 16; 42 | } 43 | 44 | calculated_field ipv4.hdrChecksum { 45 | update ipv4_chksum_calc; 46 | } 47 | 48 | parser parse_tcp { 49 | extract (tcp); 50 | return ingress; 51 | } 52 | 53 | parser parse_udp { 54 | extract (udp); 55 | return select (latest.dstPort) { 56 | NC_PORT: parse_nc_hdr; 57 | PROBE_PORT: parse_probe_hdr; 58 | LK_PORT: parse_nlk_hdr; 59 | REPLY_PORT: parse_nlk_hdr; 60 | ADM_PORT: parse_adm_hdr; 61 | default: ingress; 62 | } 63 | } 64 | 65 | /* 66 | field_list udp_field_list { 67 | udp.srcPort; 68 | udp.dstPort; 69 | udp.pkt_length; 70 | udp.checksum; 71 | } 72 | 73 | field_list_calculation udp_chksum_calc { 74 | input { 75 | udp_field_list; 76 | } 77 | algorithm: csum16; 78 | output_width: 16; 79 | } 80 | 81 | calculated_field udp.checksum { 82 | update udp_chksum_calc; 83 | } 84 | */ 85 | 86 | parser parse_nc_hdr { 87 | extract (nc_hdr); 88 | return ingress; 89 | } 90 | 91 | parser parse_nlk_hdr { 92 | extract (nlk_hdr); 93 | return select (latest.recirc_flag) { 94 | RECIRCULATED_1: parse_recirculate_hdr; 95 | RECIRCULATED_2: parse_recirculate_hdr; 96 | default: ingress; 97 | } 98 | } 99 | 100 | parser parse_recirculate_hdr { 101 | extract (recirculate_hdr); 102 | return ingress; 103 | } 104 | 105 | parser parse_adm_hdr { 106 | extract (adm_hdr); 107 | return ingress; 108 | } 109 | 110 | parser parse_probe_hdr { 111 | extract (probe_hdr); 112 | return ingress; 113 | } 114 | -------------------------------------------------------------------------------- /dpdk_code/client_code/tpcc.py: -------------------------------------------------------------------------------- 1 | ## tpcc - new order 2 | 3 | ## NURand(A,x,y)=(((random(0,A)| random(x,y))+C)%(y-x+1))+x 4 | 5 | ## w_id: warehouse ID 6 | ## d_id: district ID, which I think not useful for our current case 7 | ## c_id: customer ID 8 | ## ol_cnt: number of items in the order 9 | ## i_ids: a list of item IDs 10 | ## i_id: item ID 11 | ## rbk: 1% of the transactions chosen at random (error) 12 | 13 | def gen_new_order(w_id, d_id, c_id, ol_cnt): 14 | i_ids = [] 15 | for i in range(ol_cnt): 16 | i_ids = i_ids.append(NURand(8191, 1, 100000)) 17 | 18 | #### warehouse table: get w_tax, (1 shared lock) 19 | lock_id = get_lock_id('warehouse_t', w_id) 20 | send_netlock_req(SHARED_LOCK, lock_id) 21 | 22 | #### district table: get d_tax, d_next_i_id++, (1 shared lock + 1 exclusive lock) 23 | lock_id_0 = get_lock_id('district_t', w_id, d_id, 0) 24 | send_netlock_req(SHARED_LOCK, lock_id_0) 25 | lock_id_1 = get_lock_id('district_t', w_id, d_id, 1) 26 | send_netlock_req(EXCLUSIVE_LOCK, lock_id_1) 27 | 28 | #### customer table: get c_discount, get c_last, get c_credit, (3 shared locks) 29 | for i in range(3): 30 | lock_id = get_lock_id('customer_t', w_id, d_id, c_id, i) 31 | send_netlock_req(SHARED_LOCK, lock_id) 32 | 33 | #### order table and new-order table: insert lines into the table, (2 exclusive locks or 2 exclusive table locks ? ) 34 | lock_id_3 = get_lock_id('order_t') 35 | send_netlock_req(EXCLUSIVE_LOCK, lock_id_3) 36 | lock_id_4 = get_lock_id('order_t') 37 | send_netlock_req(EXCLUSIVE_LOCK, lock_id_4) 38 | 39 | #### ol_cnt numbers of items 40 | for i in range(ol_cnt): 41 | i_id = i_ids[i] 42 | #### item table: get i_price, i_name, i_data, (3 shared locks) 43 | for j in range(3): 44 | lock_id = get_lock_id('item_i', i_id, j) 45 | send_netlock_req(SHARED_LOCK, lock_id) 46 | 47 | #### stock table: update s_quantity, s_ytd, s_order_cnt/s_remote_cnt; get s_dist_xx, s_data (2 shared locks and 3 exclusive locks) 48 | for j in range(2): 49 | lock_id = get_lock_id('stock_t', i_id, w_id, j) 50 | send_netlock_req(SHARED_LOCK, lock_id) 51 | for j in range(3): 52 | lock_id = get_lock_id('stock_t', i_id, w_id, j+2) 53 | send_netlock_req(EXCLUSIVE_LOCK, lock_id) 54 | 55 | #### order-line table: insert line: ol_delivery_d, ol_number, pl_dist_info, (3 exclusive locks) 56 | for j in range(3): 57 | lock_id = get_lock_id('order_line_t', j) 58 | send_netlock_req(EXCLUSIVE_LOCK, lock_id) 59 | 60 | 61 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/tpcc.py: -------------------------------------------------------------------------------- 1 | ## tpcc - new order 2 | 3 | ## NURand(A,x,y)=(((random(0,A)| random(x,y))+C)%(y-x+1))+x 4 | 5 | ## w_id: warehouse ID 6 | ## d_id: district ID, which I think not useful for our current case 7 | ## c_id: customer ID 8 | ## ol_cnt: number of items in the order 9 | ## i_ids: a list of item IDs 10 | ## i_id: item ID 11 | ## rbk: 1% of the transactions chosen at random (error) 12 | 13 | def gen_new_order(w_id, d_id, c_id, ol_cnt): 14 | i_ids = [] 15 | for i in range(ol_cnt): 16 | i_ids = i_ids.append(NURand(8191, 1, 100000)) 17 | 18 | #### warehouse table: get w_tax, (1 shared lock) 19 | lock_id = get_lock_id('warehouse_t', w_id) 20 | send_netlock_req(SHARED_LOCK, lock_id) 21 | 22 | #### district table: get d_tax, d_next_i_id++, (1 shared lock + 1 exclusive lock) 23 | lock_id_0 = get_lock_id('district_t', w_id, d_id, 0) 24 | send_netlock_req(SHARED_LOCK, lock_id_0) 25 | lock_id_1 = get_lock_id('district_t', w_id, d_id, 1) 26 | send_netlock_req(EXCLUSIVE_LOCK, lock_id_1) 27 | 28 | #### customer table: get c_discount, get c_last, get c_credit, (3 shared locks) 29 | for i in range(3): 30 | lock_id = get_lock_id('customer_t', w_id, d_id, c_id, i) 31 | send_netlock_req(SHARED_LOCK, lock_id) 32 | 33 | #### order table and new-order table: insert lines into the table, (2 exclusive locks or 2 exclusive table locks ? ) 34 | lock_id_3 = get_lock_id('order_t') 35 | send_netlock_req(EXCLUSIVE_LOCK, lock_id_3) 36 | lock_id_4 = get_lock_id('order_t') 37 | send_netlock_req(EXCLUSIVE_LOCK, lock_id_4) 38 | 39 | #### ol_cnt numbers of items 40 | for i in range(ol_cnt): 41 | i_id = i_ids[i] 42 | #### item table: get i_price, i_name, i_data, (3 shared locks) 43 | for j in range(3): 44 | lock_id = get_lock_id('item_i', i_id, j) 45 | send_netlock_req(SHARED_LOCK, lock_id) 46 | 47 | #### stock table: update s_quantity, s_ytd, s_order_cnt/s_remote_cnt; get s_dist_xx, s_data (2 shared locks and 3 exclusive locks) 48 | for j in range(2): 49 | lock_id = get_lock_id('stock_t', i_id, w_id, j) 50 | send_netlock_req(SHARED_LOCK, lock_id) 51 | for j in range(3): 52 | lock_id = get_lock_id('stock_t', i_id, w_id, j+2) 53 | send_netlock_req(EXCLUSIVE_LOCK, lock_id) 54 | 55 | #### order-line table: insert line: ol_delivery_d, ol_number, pl_dist_info, (3 exclusive locks) 56 | for j in range(3): 57 | lock_id = get_lock_id('order_line_t', j) 58 | send_netlock_req(EXCLUSIVE_LOCK, lock_id) 59 | 60 | 61 | -------------------------------------------------------------------------------- /switch_code/netchain/p4src/includes/headers.p4: -------------------------------------------------------------------------------- 1 | header_type ethernet_t { 2 | fields { 3 | dstAddr: 48; 4 | srcAddr: 48; 5 | etherType: 16; 6 | } 7 | } 8 | header ethernet_t ethernet; 9 | 10 | header_type ipv4_t { 11 | fields { 12 | version: 4; 13 | ihl: 4; 14 | diffserv: 8; 15 | totalLen: 16; 16 | identification: 16; 17 | flags: 3; 18 | fragOffset: 13; 19 | ttl: 8; 20 | protocol: 8; 21 | hdrChecksum: 16; 22 | srcAddr: 32; 23 | dstAddr: 32; 24 | } 25 | } 26 | header ipv4_t ipv4; 27 | 28 | header_type tcp_t { 29 | fields { 30 | srcPort: 16; 31 | dstPort: 16; 32 | seqNo: 32; 33 | ackNo: 32; 34 | dataOffset: 4; 35 | res: 3; 36 | ecn: 3; 37 | ctrl: 6; 38 | window: 16; 39 | checksum: 16; 40 | urgentPtr: 16; 41 | } 42 | } 43 | header tcp_t tcp; 44 | 45 | header_type udp_t { 46 | fields { 47 | srcPort: 16; 48 | dstPort: 16; 49 | pkt_length: 16; 50 | checksum: 16; 51 | } 52 | } 53 | header udp_t udp; 54 | 55 | header_type nlk_hdr_t { 56 | fields { 57 | recirc_flag: 8; 58 | op: 8; 59 | mode: 8; 60 | client_id: 8; 61 | tid: 32; 62 | lock: 32; 63 | timestamp_lo: 32; 64 | timestamp_hi: 32; 65 | } 66 | 67 | } 68 | header nlk_hdr_t nlk_hdr; 69 | 70 | header_type adm_hdr_t { 71 | fields { 72 | op: 8; 73 | lock: 32; 74 | new_left: 32; 75 | new_right:32; 76 | } 77 | } 78 | header adm_hdr_t adm_hdr; 79 | 80 | header_type recirculate_hdr_t { 81 | fields { 82 | dequeued_mode: 8; 83 | cur_head: 32; 84 | cur_tail: 32; 85 | } 86 | } 87 | header recirculate_hdr_t recirculate_hdr; 88 | 89 | header_type probe_hdr_t { 90 | fields { 91 | failure_status: 8; 92 | op: 8; 93 | mode: 8; 94 | client_id: 8; 95 | tid: 32; 96 | lock: 32; 97 | timestamp_lo: 32; 98 | timestamp_hi: 32; 99 | } 100 | } 101 | header probe_hdr_t probe_hdr; 102 | 103 | header_type nc_hdr_t { 104 | fields { 105 | recirc_flag: 8; 106 | op: 8; 107 | mode: 8; 108 | client_id: 8; 109 | tid: 32; 110 | lock: 32; 111 | timestamp_lo: 32; 112 | timestamp_hi: 32; 113 | } 114 | } 115 | header nc_hdr_t nc_hdr; -------------------------------------------------------------------------------- /switch_code/netchain/p4src/netchain.p4: -------------------------------------------------------------------------------- 1 | #include 2 | #if __TARGET_TOFINO__ == 2 3 | #include 4 | #else 5 | #include 6 | #endif 7 | #include 8 | #include 9 | 10 | #include "includes/defines.p4" 11 | #include "includes/headers.p4" 12 | #include "includes/parser.p4" 13 | #include "routing.p4" 14 | #include "blackboxs.p4" 15 | #include "actions.p4" 16 | #include "tables.p4" 17 | 18 | header_type meta_t { 19 | fields { 20 | lock_id: 32; 21 | routed: 1; 22 | available: 8; 23 | } 24 | } 25 | metadata meta_t meta; 26 | 27 | register lock_status_register { 28 | width: 32; 29 | instance_count: LENGTH_ARRAY; 30 | } 31 | 32 | action decode_action() { 33 | modify_field(meta.lock_id, nc_hdr.lock); 34 | } 35 | 36 | table decode_table { 37 | actions { 38 | decode_action; 39 | } 40 | default_action: decode_action; 41 | } 42 | 43 | action release_lock_action() { 44 | release_lock_alu.execute_stateful_alu(meta.lock_id); 45 | } 46 | 47 | table release_lock_table { 48 | actions { 49 | release_lock_action; 50 | } 51 | default_action: release_lock_action; 52 | } 53 | 54 | action acquire_lock_action() { 55 | acquire_lock_alu.execute_stateful_alu(meta.lock_id); 56 | } 57 | 58 | table acquire_lock_table { 59 | actions { 60 | acquire_lock_action; 61 | } 62 | default_action: acquire_lock_action; 63 | } 64 | 65 | action set_retry_action() { 66 | modify_field(nc_hdr.op, RETRY_LOCK); 67 | } 68 | 69 | table set_retry_table { 70 | actions { 71 | set_retry_action; 72 | } 73 | default_action: set_retry_action; 74 | } 75 | 76 | action reply_to_client_action() { 77 | modify_field(ipv4.dstAddr, ipv4.srcAddr); 78 | } 79 | 80 | table reply_to_client_table { 81 | actions { 82 | reply_to_client_action; 83 | } 84 | default_action: reply_to_client_action; 85 | } 86 | 87 | control ingress { 88 | if (valid(nc_hdr)) { 89 | apply(decode_table); 90 | if (nc_hdr.op == ACQUIRE_LOCK) { 91 | apply(acquire_lock_table); 92 | if (meta.available != 0) { 93 | // not available, tell client to retry 94 | apply(set_retry_table); 95 | } 96 | } 97 | else if (nc_hdr.op == RELEASE_LOCK) { 98 | apply(release_lock_table); 99 | } 100 | apply(reply_to_client_table); 101 | } 102 | if (valid(nc_hdr)) { 103 | apply(ipv4_route); 104 | } 105 | } 106 | 107 | control egress { 108 | // if () 109 | } -------------------------------------------------------------------------------- /dpdk_code/client_code/lock_queue.c: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_INCLUDED 2 | #define QUEUE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef struct QueueNode { 9 | uint8_t mode; 10 | uint8_t client_id; 11 | uint32_t txnID; 12 | uint32_t ip_src; 13 | uint64_t timestamp; 14 | struct QueueNode *next; 15 | } queue_node; 16 | 17 | typedef struct QueueList { 18 | int size_of_queue; 19 | queue_node *head; 20 | queue_node *tail; 21 | } queue_list; 22 | 23 | static void queue_init(queue_list *q) { 24 | q->size_of_queue = 0; 25 | q->head = NULL; 26 | q->tail = NULL; 27 | } 28 | 29 | static int enqueue(queue_list *q, uint8_t mode, uint32_t txn_id, uint32_t ip_src_addr, uint64_t timestamp, uint8_t client_id) { 30 | queue_node *new_node = (queue_node *) malloc(sizeof(queue_node)); 31 | if (new_node == NULL) { 32 | fprintf(stderr, "MALLOC ERROR.\n"); 33 | return -1; 34 | } 35 | 36 | new_node->mode = mode; 37 | new_node->client_id = client_id; 38 | new_node->txnID = txn_id; 39 | new_node->ip_src = ip_src_addr; 40 | new_node->timestamp = timestamp; 41 | new_node->next = NULL; 42 | 43 | if (q->size_of_queue == 0) { 44 | q->head = new_node; 45 | q->tail = new_node; 46 | } 47 | else { 48 | q->tail->next = new_node; 49 | q->tail = new_node; 50 | } 51 | q->size_of_queue ++; 52 | return 0; 53 | } 54 | 55 | static void dequeue(queue_list *q, uint8_t* mode, uint32_t* txn_id, uint32_t* ip_src_addr, uint64_t* timestamp, uint8_t* client_id) { 56 | if ((q != NULL) && (q->size_of_queue > 0)) { 57 | queue_node *temp = q->head; 58 | (*mode) = temp->mode; 59 | (*client_id) = temp->client_id; 60 | (*txn_id) = ntohl(temp->txnID); 61 | (*ip_src_addr) = temp->ip_src; 62 | (*timestamp) = temp->timestamp; 63 | free(temp); 64 | if (q->size_of_queue > 1) { 65 | q->head = q->head->next; 66 | } 67 | else { 68 | q->head = NULL; 69 | q->tail = NULL; 70 | } 71 | 72 | q->size_of_queue --; 73 | 74 | } 75 | return; 76 | } 77 | 78 | static void queue_clear(queue_list *q) { 79 | queue_node *temp; 80 | while (q->size_of_queue > 0) { 81 | temp = q->head; 82 | q->head = temp->next; 83 | free(temp); 84 | q->size_of_queue --; 85 | } 86 | 87 | q->head = NULL; 88 | q->tail = NULL; 89 | return; 90 | } 91 | 92 | static int get_queue_size(queue_list *q) { 93 | if (q == NULL) 94 | return 0; 95 | return q->size_of_queue; 96 | } 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /dpdk_code/client_code/include/lock_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_INCLUDED 2 | #define QUEUE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef struct QueueNode { 9 | uint8_t mode; 10 | uint8_t client_id; 11 | uint32_t txnID; 12 | uint32_t ip_src; 13 | uint64_t timestamp; 14 | struct QueueNode *next; 15 | } queue_node; 16 | 17 | typedef struct QueueList { 18 | int size_of_queue; 19 | queue_node *head; 20 | queue_node *tail; 21 | } queue_list; 22 | 23 | static void queue_init(queue_list *q) { 24 | q->size_of_queue = 0; 25 | q->head = NULL; 26 | q->tail = NULL; 27 | } 28 | 29 | static int enqueue(queue_list *q, uint8_t mode, uint32_t txn_id, uint32_t ip_src_addr, uint64_t timestamp, uint8_t client_id) { 30 | queue_node *new_node = (queue_node *) malloc(sizeof(queue_node)); 31 | if (new_node == NULL) { 32 | fprintf(stderr, "MALLOC ERROR.\n"); 33 | return -1; 34 | } 35 | 36 | new_node->mode = mode; 37 | new_node->client_id = client_id; 38 | new_node->txnID = txn_id; 39 | new_node->ip_src = ip_src_addr; 40 | new_node->timestamp = timestamp; 41 | new_node->next = NULL; 42 | 43 | if (q->size_of_queue == 0) { 44 | q->head = new_node; 45 | q->tail = new_node; 46 | } 47 | else { 48 | q->tail->next = new_node; 49 | q->tail = new_node; 50 | } 51 | q->size_of_queue ++; 52 | return 0; 53 | } 54 | 55 | static void dequeue(queue_list *q, uint8_t* mode, uint32_t* txn_id, uint32_t* ip_src_addr, uint64_t* timestamp, uint8_t* client_id) { 56 | if ((q != NULL) && (q->size_of_queue > 0)) { 57 | queue_node *temp = q->head; 58 | (*mode) = temp->mode; 59 | (*client_id) = temp->client_id; 60 | (*txn_id) = ntohl(temp->txnID); 61 | (*ip_src_addr) = temp->ip_src; 62 | (*timestamp) = temp->timestamp; 63 | free(temp); 64 | if (q->size_of_queue > 1) { 65 | q->head = q->head->next; 66 | } 67 | else { 68 | q->head = NULL; 69 | q->tail = NULL; 70 | } 71 | 72 | q->size_of_queue --; 73 | 74 | } 75 | return; 76 | } 77 | 78 | static void queue_clear(queue_list *q) { 79 | queue_node *temp; 80 | while (q->size_of_queue > 0) { 81 | temp = q->head; 82 | q->head = temp->next; 83 | free(temp); 84 | q->size_of_queue --; 85 | } 86 | 87 | q->head = NULL; 88 | q->tail = NULL; 89 | return; 90 | } 91 | 92 | static int get_queue_size(queue_list *q) { 93 | if (q == NULL) 94 | return 0; 95 | return q->size_of_queue; 96 | } 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/lock_queue.c: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_INCLUDED 2 | #define QUEUE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef struct QueueNode { 9 | uint8_t mode; 10 | uint8_t client_id; 11 | uint32_t txnID; 12 | uint32_t ip_src; 13 | uint64_t timestamp; 14 | struct QueueNode *next; 15 | } queue_node; 16 | 17 | typedef struct QueueList { 18 | int size_of_queue; 19 | queue_node *head; 20 | queue_node *tail; 21 | } queue_list; 22 | 23 | static void queue_init(queue_list *q) { 24 | q->size_of_queue = 0; 25 | q->head = NULL; 26 | q->tail = NULL; 27 | } 28 | 29 | static int enqueue(queue_list *q, uint8_t mode, uint32_t txn_id, uint32_t ip_src_addr, uint64_t timestamp, uint8_t client_id) { 30 | queue_node *new_node = (queue_node *) malloc(sizeof(queue_node)); 31 | if (new_node == NULL) { 32 | fprintf(stderr, "MALLOC ERROR.\n"); 33 | return -1; 34 | } 35 | 36 | new_node->mode = mode; 37 | new_node->client_id = client_id; 38 | new_node->txnID = txn_id; 39 | new_node->ip_src = ip_src_addr; 40 | new_node->timestamp = timestamp; 41 | new_node->next = NULL; 42 | 43 | if (q->size_of_queue == 0) { 44 | q->head = new_node; 45 | q->tail = new_node; 46 | } 47 | else { 48 | q->tail->next = new_node; 49 | q->tail = new_node; 50 | } 51 | q->size_of_queue ++; 52 | return 0; 53 | } 54 | 55 | static void dequeue(queue_list *q, uint8_t* mode, uint32_t* txn_id, uint32_t* ip_src_addr, uint64_t* timestamp, uint8_t* client_id) { 56 | if ((q != NULL) && (q->size_of_queue > 0)) { 57 | queue_node *temp = q->head; 58 | (*mode) = temp->mode; 59 | (*client_id) = temp->client_id; 60 | (*txn_id) = ntohl(temp->txnID); 61 | (*ip_src_addr) = temp->ip_src; 62 | (*timestamp) = temp->timestamp; 63 | free(temp); 64 | if (q->size_of_queue > 1) { 65 | q->head = q->head->next; 66 | } 67 | else { 68 | q->head = NULL; 69 | q->tail = NULL; 70 | } 71 | 72 | q->size_of_queue --; 73 | 74 | } 75 | return; 76 | } 77 | 78 | static void queue_clear(queue_list *q) { 79 | queue_node *temp; 80 | while (q->size_of_queue > 0) { 81 | temp = q->head; 82 | q->head = temp->next; 83 | free(temp); 84 | q->size_of_queue --; 85 | } 86 | 87 | q->head = NULL; 88 | q->tail = NULL; 89 | return; 90 | } 91 | 92 | static int get_queue_size(queue_list *q) { 93 | if (q == NULL) 94 | return 0; 95 | return q->size_of_queue; 96 | } 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/include/lock_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_INCLUDED 2 | #define QUEUE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | typedef struct QueueNode { 9 | uint8_t mode; 10 | uint8_t client_id; 11 | uint32_t txnID; 12 | uint32_t ip_src; 13 | uint64_t timestamp; 14 | struct QueueNode *next; 15 | } queue_node; 16 | 17 | typedef struct QueueList { 18 | int size_of_queue; 19 | queue_node *head; 20 | queue_node *tail; 21 | } queue_list; 22 | 23 | static void queue_init(queue_list *q) { 24 | q->size_of_queue = 0; 25 | q->head = NULL; 26 | q->tail = NULL; 27 | } 28 | 29 | static int enqueue(queue_list *q, uint8_t mode, uint32_t txn_id, uint32_t ip_src_addr, uint64_t timestamp, uint8_t client_id) { 30 | queue_node *new_node = (queue_node *) malloc(sizeof(queue_node)); 31 | if (new_node == NULL) { 32 | fprintf(stderr, "MALLOC ERROR.\n"); 33 | return -1; 34 | } 35 | 36 | new_node->mode = mode; 37 | new_node->client_id = client_id; 38 | new_node->txnID = txn_id; 39 | new_node->ip_src = ip_src_addr; 40 | new_node->timestamp = timestamp; 41 | new_node->next = NULL; 42 | 43 | if (q->size_of_queue == 0) { 44 | q->head = new_node; 45 | q->tail = new_node; 46 | } 47 | else { 48 | q->tail->next = new_node; 49 | q->tail = new_node; 50 | } 51 | q->size_of_queue ++; 52 | return 0; 53 | } 54 | 55 | static void dequeue(queue_list *q, uint8_t* mode, uint32_t* txn_id, uint32_t* ip_src_addr, uint64_t* timestamp, uint8_t* client_id) { 56 | if ((q != NULL) && (q->size_of_queue > 0)) { 57 | queue_node *temp = q->head; 58 | (*mode) = temp->mode; 59 | (*client_id) = temp->client_id; 60 | (*txn_id) = ntohl(temp->txnID); 61 | (*ip_src_addr) = temp->ip_src; 62 | (*timestamp) = temp->timestamp; 63 | free(temp); 64 | if (q->size_of_queue > 1) { 65 | q->head = q->head->next; 66 | } 67 | else { 68 | q->head = NULL; 69 | q->tail = NULL; 70 | } 71 | 72 | q->size_of_queue --; 73 | 74 | } 75 | return; 76 | } 77 | 78 | static void queue_clear(queue_list *q) { 79 | queue_node *temp; 80 | while (q->size_of_queue > 0) { 81 | temp = q->head; 82 | q->head = temp->next; 83 | free(temp); 84 | q->size_of_queue --; 85 | } 86 | 87 | q->head = NULL; 88 | q->tail = NULL; 89 | return; 90 | } 91 | 92 | static int get_queue_size(queue_list *q) { 93 | if (q == NULL) 94 | return 0; 95 | return q->size_of_queue; 96 | } 97 | 98 | #endif 99 | 100 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import sys 2 | # local_home_dir = "/Users/zyu/Dropbox/code/p4/" 3 | local_home_dir = "/home/username/zhuolong/ae/" 4 | remote_server_home_dir = "/home/username/zhuolong/test/" 5 | remote_switch_home_dir = "/home/zhuolong/test/" 6 | remote_switch_sde_dir = "/home/zhuolong/bf-sde-8.2.2/" 7 | 8 | id_to_usernamename_dict = {"netx1": "username", "netx2": "username", "netx3": "username", 9 | "netx4": "username", "netx5": "username", "netx6": "username", 10 | "netx7": "username", "netx8": "username", "netx9": "username", 11 | "netx10": "username", "netx11": "username", "netx12": "username", 12 | "netxy": "username"} 13 | id_to_passwd_dict = {"netx1": "yourpasswd", "netx2": "yourpasswd", "netx3": "yourpasswd", 14 | "netx4": "yourpasswd", "netx5": "yourpasswd", "netx6": "yourpasswd", 15 | "netx7": "yourpasswd", "netx8": "yourpasswd", "netx9": "yourpasswd", 16 | "netx10": "yourpasswd", "netx11": "yourpasswd", "netx12": "yourpasswd", 17 | "netxy": "yourpasswd"} 18 | 19 | id_to_hostname_dict = {"netx1": "netx1.cs.jhu.edu", "netx2": "netx2.cs.jhu.edu", 20 | "netx3": "netx3.cs.jhu.edu", "netx4": "netx4.cs.jhu.edu", 21 | "netx5": "netx5.cs.jhu.edu", "netx6": "netx6.cs.jhu.edu", 22 | "netx7": "netx7.cs.jhu.edu", "netx8": "netx8.cs.jhu.edu", 23 | "netx9": "netx9.cs.jhu.edu", "netx10": "netx10.cs.jhu.edu", 24 | "netx11": "netx11.cs.jhu.edu", "netx12": "netx12.cs.jhu.edu", 25 | "netxy": "netxy.cs.jhu.edu"} 26 | 27 | client_id_t1 = [] 28 | client_id_t2 = [] 29 | server_id = [] 30 | 31 | def conf_12_clients(): 32 | global client_id_t1, client_id_t2, server_id 33 | # tenant 1's client id. Normally we only need this. 34 | client_id_t1 = ["netx1", "netx2", "netx3", "netx4", "netx5", "netx6", "netx7", "netx8", "netx9", "netx10", "netx11", "netx12"] 35 | # tenant 2's client id. It's for the two tenant situation. 36 | client_id_t2 = [] 37 | # Lock server's id 38 | server_id = [] 39 | print("Clients:", client_id_t1) 40 | print("Servers:", server_id) 41 | 42 | def conf_10_clients_2_servers(): 43 | global client_id_t1, client_id_t2, server_id 44 | # tenant 1's client id. Normally we only need this. 45 | client_id_t1 = ["netx1", "netx2", "netx3", "netx4", "netx5", "netx6", "netx7", "netx8", "netx9", "netx10"] 46 | # tenant 2's client id. It's for the two tenant situation. 47 | client_id_t2 = [] 48 | # Lock server's id 49 | server_id = ["netx11", "netx12"] 50 | print("Clients:", client_id_t1) 51 | print("Servers:", server_id) 52 | 53 | def conf_6_clients_6_servers(): 54 | global client_id_t1, client_id_t2, server_id 55 | # tenant 1's client id. Normally we only need this. 56 | client_id_t1 = ["netx1", "netx2", "netx3", "netx4", "netx5", "netx6"] 57 | # tenant 2's client id. It's for the two tenant situation. 58 | client_id_t2 = [] 59 | # Lock server's id 60 | server_id = ["netx7", "netx8", "netx9", "netx10", "netx11", "netx12"] 61 | print("Clients:", client_id_t1) 62 | print("Servers:", server_id) 63 | 64 | ## use different func to set the clients/servers for different experiments 65 | # conf_12_clients() 66 | if (sys.argv[1] in ["micro_bm_s", "micro_bm_x", "micro_bm_cont"]): 67 | conf_12_clients() 68 | elif (sys.argv[1] in ["run_tpcc_ms"]): 69 | conf_6_clients_6_servers() 70 | else: 71 | conf_10_clients_2_servers() 72 | switch_id = "netxy" -------------------------------------------------------------------------------- /dpdk_code/client_code/include/zipf.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct zipf_gen_state { 6 | uint64_t n; // number of items (input) 7 | double theta; // skewness (input) in (0, 1); or, 0 = uniform, 1 = always zero 8 | double alpha; // only depends on theta 9 | double thres; // only depends on theta 10 | uint64_t last_n; // last n used to calculate the following 11 | double dbl_n; 12 | double zetan; 13 | double eta; 14 | uint64_t rand_state; 15 | }; 16 | 17 | static double zipf_rand_d(uint64_t *state) 18 | { 19 | // caution: this is maybe too non-random 20 | *state = (*state * 0x5deece66dUL + 0xbUL) & ((1UL << 48) - 1); 21 | return (double)*state / (double)((1UL << 48) - 1); 22 | } 23 | 24 | static double zipf_pow_approx(double a, double b) 25 | { 26 | // from http://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ 27 | 28 | // calculate approximation with fraction of the exponent 29 | int e = (int)b; 30 | union 31 | { 32 | double d; 33 | int x[2]; 34 | } u = { a }; 35 | u.x[1] = (int)((b - (double)e) * (double)(u.x[1] - 1072632447) + 1072632447.); 36 | u.x[0] = 0; 37 | 38 | // exponentiation by squaring with the exponent's integer part 39 | // double r = u.d makes everything much slower, not sure why 40 | // TODO: use popcount? 41 | double r = 1.; 42 | while (e) 43 | { 44 | if (e & 1) 45 | r *= a; 46 | a *= a; 47 | e >>= 1; 48 | } 49 | 50 | return r * u.d; 51 | } 52 | 53 | static double zipf_zeta(uint64_t last_n, double last_sum, uint64_t n, double theta) 54 | { 55 | if (last_n > n) 56 | { 57 | last_n = 0; 58 | last_sum = 0.; 59 | } 60 | while (last_n < n) 61 | { 62 | last_sum += 1. / zipf_pow_approx((double)last_n + 1., theta); 63 | last_n++; 64 | } 65 | return last_sum; 66 | } 67 | 68 | static uint64_t zipf_next(struct zipf_gen_state *state) 69 | { 70 | if (state->last_n != state->n) 71 | { 72 | if (state->theta > 0. && state->theta < 1.) 73 | { 74 | state->zetan = zipf_zeta(state->last_n, state->zetan, state->n, state->theta); 75 | state->eta = (1. - zipf_pow_approx(2. / (double)state->n, 1. - state->theta)) / 76 | (1. - zipf_zeta(0, 0., 2, state->theta) / state->zetan); 77 | } 78 | state->last_n = state->n; 79 | state->dbl_n = (double)state->n; 80 | } 81 | 82 | if (state->theta == -1.) 83 | { 84 | uint64_t v = state->rand_state; 85 | if (++state->rand_state >= state->n) 86 | state->rand_state = 0; 87 | return v; 88 | } 89 | else if (state->theta == 0.) 90 | { 91 | double u = zipf_rand_d(&state->rand_state); 92 | return (uint64_t)(state->dbl_n * u); 93 | } 94 | else if (state->theta >= 40.) 95 | { 96 | return 0UL; 97 | } 98 | else 99 | { 100 | // from J. Gray et al. Quickly generating billion-record synthetic databases. In SIGMOD, 1994. 101 | 102 | // double u = erand48(state->rand_state); 103 | double u = zipf_rand_d(&state->rand_state); 104 | double uz = u * state->zetan; 105 | if (uz < 1.) 106 | return 0UL; 107 | else if (uz < state->thres) 108 | return 1UL; 109 | else 110 | return (uint64_t)(state->dbl_n * zipf_pow_approx(state->eta * (u - 1.) + 1., state->alpha)); 111 | } 112 | } 113 | 114 | static void zipf_init(struct zipf_gen_state *state, uint64_t n, double theta, uint64_t rand_seed) 115 | { 116 | assert(n > 0); 117 | if (theta > 0.992 && theta < 1) 118 | fprintf(stderr, "theta > 0.992 will be inaccurate due to approximation\n"); 119 | if (theta >= 1. && theta < 40.) 120 | { 121 | fprintf(stderr, "theta in [1., 40.) is not supported\n"); 122 | assert(0); 123 | } 124 | assert(theta == -1. || (theta >= 0. && theta < 1.) || theta >= 40.); 125 | assert(rand_seed < (1UL << 48)); 126 | memset(state, 0, sizeof(struct zipf_gen_state)); 127 | state->n = n; 128 | state->theta = theta; 129 | if (theta == -1.) 130 | rand_seed = rand_seed % n; 131 | else if (theta > 0. && theta < 1.) 132 | { 133 | state->alpha = 1. / (1. - theta); 134 | state->thres = 1. + zipf_pow_approx(0.5, theta); 135 | } 136 | else 137 | { 138 | state->alpha = 0.; // unused 139 | state->thres = 0.; // unused 140 | } 141 | state->last_n = 0; 142 | state->zetan = 0.; 143 | state->rand_state = rand_seed; 144 | 145 | zipf_next(state); // to prevent the first 'next' from being super slow 146 | } 147 | 148 | static void zipf_init_copy(struct zipf_gen_state *state, const struct zipf_gen_state *src_state, uint64_t rand_seed) 149 | { 150 | assert(rand_seed < (1UL << 48)); 151 | memcpy(state, src_state, sizeof(struct zipf_gen_state)); 152 | state->rand_state = rand_seed; 153 | } 154 | 155 | 156 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/include/zipf.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct zipf_gen_state { 6 | uint64_t n; // number of items (input) 7 | double theta; // skewness (input) in (0, 1); or, 0 = uniform, 1 = always zero 8 | double alpha; // only depends on theta 9 | double thres; // only depends on theta 10 | uint64_t last_n; // last n used to calculate the following 11 | double dbl_n; 12 | double zetan; 13 | double eta; 14 | uint64_t rand_state; 15 | }; 16 | 17 | static double zipf_rand_d(uint64_t *state) 18 | { 19 | // caution: this is maybe too non-random 20 | *state = (*state * 0x5deece66dUL + 0xbUL) & ((1UL << 48) - 1); 21 | return (double)*state / (double)((1UL << 48) - 1); 22 | } 23 | 24 | static double zipf_pow_approx(double a, double b) 25 | { 26 | // from http://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ 27 | 28 | // calculate approximation with fraction of the exponent 29 | int e = (int)b; 30 | union 31 | { 32 | double d; 33 | int x[2]; 34 | } u = { a }; 35 | u.x[1] = (int)((b - (double)e) * (double)(u.x[1] - 1072632447) + 1072632447.); 36 | u.x[0] = 0; 37 | 38 | // exponentiation by squaring with the exponent's integer part 39 | // double r = u.d makes everything much slower, not sure why 40 | // TODO: use popcount? 41 | double r = 1.; 42 | while (e) 43 | { 44 | if (e & 1) 45 | r *= a; 46 | a *= a; 47 | e >>= 1; 48 | } 49 | 50 | return r * u.d; 51 | } 52 | 53 | static double zipf_zeta(uint64_t last_n, double last_sum, uint64_t n, double theta) 54 | { 55 | if (last_n > n) 56 | { 57 | last_n = 0; 58 | last_sum = 0.; 59 | } 60 | while (last_n < n) 61 | { 62 | last_sum += 1. / zipf_pow_approx((double)last_n + 1., theta); 63 | last_n++; 64 | } 65 | return last_sum; 66 | } 67 | 68 | static uint64_t zipf_next(struct zipf_gen_state *state) 69 | { 70 | if (state->last_n != state->n) 71 | { 72 | if (state->theta > 0. && state->theta < 1.) 73 | { 74 | state->zetan = zipf_zeta(state->last_n, state->zetan, state->n, state->theta); 75 | state->eta = (1. - zipf_pow_approx(2. / (double)state->n, 1. - state->theta)) / 76 | (1. - zipf_zeta(0, 0., 2, state->theta) / state->zetan); 77 | } 78 | state->last_n = state->n; 79 | state->dbl_n = (double)state->n; 80 | } 81 | 82 | if (state->theta == -1.) 83 | { 84 | uint64_t v = state->rand_state; 85 | if (++state->rand_state >= state->n) 86 | state->rand_state = 0; 87 | return v; 88 | } 89 | else if (state->theta == 0.) 90 | { 91 | double u = zipf_rand_d(&state->rand_state); 92 | return (uint64_t)(state->dbl_n * u); 93 | } 94 | else if (state->theta >= 40.) 95 | { 96 | return 0UL; 97 | } 98 | else 99 | { 100 | // from J. Gray et al. Quickly generating billion-record synthetic databases. In SIGMOD, 1994. 101 | 102 | // double u = erand48(state->rand_state); 103 | double u = zipf_rand_d(&state->rand_state); 104 | double uz = u * state->zetan; 105 | if (uz < 1.) 106 | return 0UL; 107 | else if (uz < state->thres) 108 | return 1UL; 109 | else 110 | return (uint64_t)(state->dbl_n * zipf_pow_approx(state->eta * (u - 1.) + 1., state->alpha)); 111 | } 112 | } 113 | 114 | static void zipf_init(struct zipf_gen_state *state, uint64_t n, double theta, uint64_t rand_seed) 115 | { 116 | assert(n > 0); 117 | if (theta > 0.992 && theta < 1) 118 | fprintf(stderr, "theta > 0.992 will be inaccurate due to approximation\n"); 119 | if (theta >= 1. && theta < 40.) 120 | { 121 | fprintf(stderr, "theta in [1., 40.) is not supported\n"); 122 | assert(0); 123 | } 124 | assert(theta == -1. || (theta >= 0. && theta < 1.) || theta >= 40.); 125 | assert(rand_seed < (1UL << 48)); 126 | memset(state, 0, sizeof(struct zipf_gen_state)); 127 | state->n = n; 128 | state->theta = theta; 129 | if (theta == -1.) 130 | rand_seed = rand_seed % n; 131 | else if (theta > 0. && theta < 1.) 132 | { 133 | state->alpha = 1. / (1. - theta); 134 | state->thres = 1. + zipf_pow_approx(0.5, theta); 135 | } 136 | else 137 | { 138 | state->alpha = 0.; // unused 139 | state->thres = 0.; // unused 140 | } 141 | state->last_n = 0; 142 | state->zetan = 0.; 143 | state->rand_state = rand_seed; 144 | 145 | zipf_next(state); // to prevent the first 'next' from being super slow 146 | } 147 | 148 | static void zipf_init_copy(struct zipf_gen_state *state, const struct zipf_gen_state *src_state, uint64_t rand_seed) 149 | { 150 | assert(rand_seed < (1UL << 48)); 151 | memcpy(state, src_state, sizeof(struct zipf_gen_state)); 152 | state->rand_state = rand_seed; 153 | } 154 | 155 | 156 | -------------------------------------------------------------------------------- /dpdk_code/tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # update parameters 4 | PCI_PATH="05:00.0" 5 | WORKDIR=/media/sf_in-network-service/kvsrc/netcache 6 | 7 | # fixed parameters 8 | Pages=2048 9 | #Pages=1024 10 | HUGEPGSZ=`cat /proc/meminfo | grep Hugepagesize | cut -d : -f 2 | tr -d ' '` 11 | 12 | # 13 | # Unloads igb_uio.ko. 14 | # 15 | remove_igb_uio_module() 16 | { 17 | echo "Unloading any existing DPDK UIO module" 18 | /sbin/lsmod | grep -s igb_uio > /dev/null 19 | if [ $? -eq 0 ] ; then 20 | sudo /sbin/rmmod igb_uio 21 | fi 22 | } 23 | 24 | # 25 | # Loads new igb_uio.ko (and uio module if needed). 26 | # 27 | load_igb_uio_module() 28 | { 29 | if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko ];then 30 | echo "## ERROR: Target does not have the DPDK UIO Kernel Module." 31 | echo " To fix, please try to rebuild target." 32 | return 33 | fi 34 | 35 | remove_igb_uio_module 36 | 37 | /sbin/lsmod | grep -s uio > /dev/null 38 | if [ $? -ne 0 ] ; then 39 | modinfo uio > /dev/null 40 | if [ $? -eq 0 ]; then 41 | echo "Loading uio module" 42 | sudo /sbin/modprobe uio 43 | fi 44 | fi 45 | 46 | # UIO may be compiled into kernel, so it may not be an error if it can't 47 | # be loaded. 48 | 49 | echo "Loading DPDK UIO module" 50 | sudo /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko 51 | if [ $? -ne 0 ] ; then 52 | echo "## ERROR: Could not load kmod/igb_uio.ko." 53 | quit 54 | fi 55 | } 56 | 57 | # 58 | # Creates hugepage filesystem. 59 | # 60 | create_mnt_huge() 61 | { 62 | echo "Creating /mnt/huge and mounting as hugetlbfs" 63 | sudo mkdir -p /mnt/huge 64 | 65 | grep -s '/mnt/huge' /proc/mounts > /dev/null 66 | if [ $? -ne 0 ] ; then 67 | sudo mount -t hugetlbfs nodev /mnt/huge 68 | fi 69 | } 70 | 71 | # 72 | # Removes hugepage filesystem. 73 | # 74 | remove_mnt_huge() 75 | { 76 | echo "Unmounting /mnt/huge and removing directory" 77 | grep -s '/mnt/huge' /proc/mounts > /dev/null 78 | if [ $? -eq 0 ] ; then 79 | sudo umount /mnt/huge 80 | fi 81 | 82 | if [ -d /mnt/huge ] ; then 83 | sudo rm -R /mnt/huge 84 | fi 85 | } 86 | 87 | # 88 | # Removes all reserved hugepages. 89 | # 90 | clear_huge_pages() 91 | { 92 | echo > .echo_tmp 93 | for d in /sys/devices/system/node/node? ; do 94 | echo "echo 0 > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp 95 | done 96 | echo "Removing currently reserved hugepages" 97 | sudo sh .echo_tmp 98 | rm -f .echo_tmp 99 | 100 | remove_mnt_huge 101 | } 102 | 103 | # 104 | # Creates hugepages on specific NUMA nodes. 105 | # 106 | set_numa_pages() 107 | { 108 | clear_huge_pages 109 | 110 | echo > .echo_tmp 111 | for d in /sys/devices/system/node/node? ; do 112 | node=$(basename $d) 113 | echo "echo $Pages > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp 114 | done 115 | echo "Reserving hugepages" 116 | sudo sh .echo_tmp 117 | rm -f .echo_tmp 118 | 119 | create_mnt_huge 120 | } 121 | 122 | # 123 | # Uses dpdk-devbind.py to move devices to work with igb_uio 124 | # 125 | bind_devices_to_igb_uio() 126 | { 127 | if [ -d /sys/module/igb_uio ]; then 128 | echo "Bind device to DPDK" 129 | sudo $RTE_SDK/tools/dpdk-devbind.py -b igb_uio $PCI_PATH 130 | #${RTE_SDK}/tools/dpdk-devbind.py --status 131 | else 132 | echo "# Please load the 'igb_uio' kernel module before querying or " 133 | echo "# adjusting device bindings" 134 | fi 135 | } 136 | 137 | install_dpdk() { 138 | cd ~ 139 | rm -rf dpdk 140 | mkdir dpdk 141 | cd dpdk 142 | wget http://fast.dpdk.org/rel/dpdk-16.11.1.tar.gz 143 | tar xf dpdk-16.11.1.tar.gz 144 | cd dpdk-stable-16.11.1 145 | make install T=x86_64-native-linuxapp-gcc DESTDIR=$HOME/dpdk/dpdk-stable-16.11.1 146 | echo export\ RTE_SDK=$HOME/dpdk/dpdk-stable-16.11.1 >> $HOME/.profile 147 | echo export\ RTE_TARGET=x86_64-native-linuxapp-gcc >> $HOME/.profile 148 | source ~/.profile 149 | } 150 | 151 | show_device() { 152 | $RTE_SDK/tools/dpdk-devbind.py --status 153 | } 154 | 155 | setup_dpdk() { 156 | # insert Insert IGB UIO module 157 | load_igb_uio_module 158 | 159 | # set hugepage mapping 160 | set_numa_pages 161 | 162 | # bind device 163 | bind_devices_to_igb_uio 164 | } 165 | 166 | bind_dpdk() { 167 | bind_devices_to_igb_uio 168 | } 169 | 170 | unbind_dpdk() { 171 | sudo ${RTE_SDK}/tools/dpdk-devbind.py -u $PCI_PATH 172 | sudo ${RTE_SDK}/tools/dpdk-devbind.py -b i40e $PCI_PATH 173 | } 174 | 175 | run_client() { 176 | cd $WORKDIR/cluster/client 177 | make 178 | cd $WORKDIR/result 179 | sudo $WORKDIR/cluster/client/build/client -l 0,2 -- -z 99 -k 64 -m 10000 180 | } 181 | 182 | run_backend() { 183 | cd $WORKDIR/cluster/backend 184 | make 185 | cd $WORKDIR/result 186 | sudo $WORKDIR/cluster/backend/build/backend -l 0 -- -m 10000 187 | } 188 | 189 | option="${1}" 190 | case ${option} in 191 | install_dpdk) 192 | install_dpdk 193 | ;; 194 | show_device) 195 | show_device 196 | ;; 197 | setup_dpdk) 198 | setup_dpdk 199 | ;; 200 | bind_dpdk) 201 | bind_dpdk 202 | ;; 203 | unbind_dpdk) 204 | unbind_dpdk 205 | ;; 206 | run_client) 207 | run_client 208 | ;; 209 | run_backend) 210 | run_backend 211 | ;; 212 | *) echo "usage:" 213 | echo " ./tools.sh install_dpdk: install dpdk" 214 | echo " ./tools.sh show_device: show device" 215 | echo " ./tools.sh setup_dpdk: setup dpdk" 216 | echo " ./tools.sh bind_dpdk: bind dpdk" 217 | echo " ./tools.sh unbind_dpdk: unbind dpdk" 218 | echo " ./tools.sh run_client: run client" 219 | echo " ./tools.sh run_backend: run backend" 220 | esac 221 | 222 | 223 | -------------------------------------------------------------------------------- /dpdk_code/client_code/tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # update parameters 4 | PCI_PATH="05:00.0" 5 | WORKDIR=/media/sf_in-network-service/kvsrc/netcache 6 | 7 | # fixed parameters 8 | Pages=2048 9 | #Pages=1024 10 | HUGEPGSZ=`cat /proc/meminfo | grep Hugepagesize | cut -d : -f 2 | tr -d ' '` 11 | #HUGEPGSZ='1048576kB' 12 | 13 | # 14 | # Unloads igb_uio.ko. 15 | # 16 | remove_igb_uio_module() 17 | { 18 | echo "Unloading any existing DPDK UIO module" 19 | /sbin/lsmod | grep -s igb_uio > /dev/null 20 | if [ $? -eq 0 ] ; then 21 | echo $passwd | sudo -S /sbin/rmmod igb_uio 22 | fi 23 | } 24 | 25 | # 26 | # Loads new igb_uio.ko (and uio module if needed). 27 | # 28 | load_igb_uio_module() 29 | { 30 | if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko ];then 31 | echo "## ERROR: Target does not have the DPDK UIO Kernel Module." 32 | echo " To fix, please try to rebuild target." 33 | return 34 | fi 35 | 36 | remove_igb_uio_module 37 | 38 | /sbin/lsmod | grep -s uio > /dev/null 39 | if [ $? -ne 0 ] ; then 40 | modinfo uio > /dev/null 41 | if [ $? -eq 0 ]; then 42 | echo "Loading uio module" 43 | echo $passwd | sudo -S /sbin/modprobe uio 44 | fi 45 | fi 46 | 47 | # UIO may be compiled into kernel, so it may not be an error if it can't 48 | # be loaded. 49 | 50 | echo "Loading DPDK UIO module" 51 | echo $passwd | sudo -S /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko 52 | if [ $? -ne 0 ] ; then 53 | echo "## ERROR: Could not load kmod/igb_uio.ko." 54 | quit 55 | fi 56 | } 57 | 58 | # 59 | # Creates hugepage filesystem. 60 | # 61 | create_mnt_huge() 62 | { 63 | echo "Creating /mnt/huge and mounting as hugetlbfs" 64 | echo $passwd | sudo -S mkdir -p /mnt/huge 65 | 66 | grep -s '/mnt/huge' /proc/mounts > /dev/null 67 | if [ $? -ne 0 ] ; then 68 | echo $passwd | sudo -S mount -t hugetlbfs nodev /mnt/huge 69 | fi 70 | } 71 | 72 | # 73 | # Removes hugepage filesystem. 74 | # 75 | remove_mnt_huge() 76 | { 77 | echo "Unmounting /mnt/huge and removing directory" 78 | grep -s '/mnt/huge' /proc/mounts > /dev/null 79 | if [ $? -eq 0 ] ; then 80 | echo $passwd | sudo -S umount /mnt/huge 81 | fi 82 | 83 | if [ -d /mnt/huge ] ; then 84 | echo $passwd | sudo -S rm -R /mnt/huge 85 | fi 86 | } 87 | 88 | # 89 | # Removes all reserved hugepages. 90 | # 91 | clear_huge_pages() 92 | { 93 | echo > .echo_tmp 94 | for d in /sys/devices/system/node/node? ; do 95 | echo "echo 0 > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp 96 | done 97 | echo "Removing currently reserved hugepages" 98 | echo $passwd | sudo -S sh .echo_tmp 99 | rm -f .echo_tmp 100 | 101 | remove_mnt_huge 102 | } 103 | 104 | # 105 | # Creates hugepages on specific NUMA nodes. 106 | # 107 | set_numa_pages() 108 | { 109 | clear_huge_pages 110 | 111 | echo > .echo_tmp 112 | for d in /sys/devices/system/node/node? ; do 113 | node=$(basename $d) 114 | echo "echo $Pages > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp 115 | done 116 | echo "Reserving hugepages" 117 | echo $passwd | sudo -S sh .echo_tmp 118 | rm -f .echo_tmp 119 | 120 | create_mnt_huge 121 | } 122 | 123 | # 124 | # Uses dpdk-devbind.py to move devices to work with igb_uio 125 | # 126 | bind_devices_to_igb_uio() 127 | { 128 | if [ -d /sys/module/igb_uio ]; then 129 | echo "Bind device to DPDK" 130 | echo $passwd | sudo -S $RTE_SDK/tools/dpdk-devbind.py -b igb_uio $PCI_PATH 131 | #${RTE_SDK}/tools/dpdk-devbind.py --status 132 | else 133 | echo "# Please load the 'igb_uio' kernel module before querying or " 134 | echo "# adjusting device bindings" 135 | fi 136 | } 137 | 138 | install_dpdk() { 139 | cd ~ 140 | rm -rf dpdk 141 | mkdir dpdk 142 | cd dpdk 143 | wget http://fast.dpdk.org/rel/dpdk-16.11.1.tar.gz 144 | tar xf dpdk-16.11.1.tar.gz 145 | cd dpdk-stable-16.11.1 146 | make install T=x86_64-native-linuxapp-gcc DESTDIR=$HOME/dpdk/dpdk-stable-16.11.1 147 | echo export\ RTE_SDK=$HOME/dpdk/dpdk-stable-16.11.1 >> $HOME/.bash_profile 148 | echo export\ RTE_TARGET=x86_64-native-linuxapp-gcc >> $HOME/.bash_profile 149 | source ~/.bash_profile 150 | } 151 | 152 | show_device() { 153 | $RTE_SDK/tools/dpdk-devbind.py --status 154 | } 155 | 156 | setup_dpdk() { 157 | # insert Insert IGB UIO module 158 | load_igb_uio_module 159 | 160 | # set hugepage mapping 161 | set_numa_pages 162 | 163 | # bind device 164 | bind_devices_to_igb_uio 165 | } 166 | 167 | bind_dpdk() { 168 | bind_devices_to_igb_uio 169 | } 170 | 171 | unbind_dpdk() { 172 | echo $passwd | sudo -S ${RTE_SDK}/tools/dpdk-devbind.py -u $PCI_PATH 173 | echo $passwd | sudo -S ${RTE_SDK}/tools/dpdk-devbind.py -b i40e $PCI_PATH 174 | } 175 | 176 | run_client() { 177 | cd $WORKDIR/cluster/client 178 | make 179 | cd $WORKDIR/result 180 | echo $passwd | sudo -S $WORKDIR/cluster/client/build/client -l 0,2 -- -z 99 -k 64 -m 10000 181 | } 182 | 183 | run_backend() { 184 | cd $WORKDIR/cluster/backend 185 | make 186 | cd $WORKDIR/result 187 | echo $passwd | sudo -S $WORKDIR/cluster/backend/build/backend -l 0 -- -m 10000 188 | } 189 | 190 | option="${1}" 191 | case ${option} in 192 | install_dpdk) 193 | install_dpdk 194 | ;; 195 | show_device) 196 | show_device 197 | ;; 198 | setup_dpdk) 199 | setup_dpdk 200 | ;; 201 | bind_dpdk) 202 | bind_dpdk 203 | ;; 204 | unbind_dpdk) 205 | unbind_dpdk 206 | ;; 207 | run_client) 208 | run_client 209 | ;; 210 | run_backend) 211 | run_backend 212 | ;; 213 | *) echo "usage:" 214 | echo " ./tools.sh install_dpdk: install dpdk" 215 | echo " ./tools.sh show_device: show device" 216 | echo " ./tools.sh setup_dpdk: setup dpdk" 217 | echo " ./tools.sh bind_dpdk: bind dpdk" 218 | echo " ./tools.sh unbind_dpdk: unbind dpdk" 219 | echo " ./tools.sh run_client: run client" 220 | echo " ./tools.sh run_backend: run backend" 221 | esac 222 | 223 | 224 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # update parameters 4 | PCI_PATH="05:00.0" 5 | WORKDIR=/media/sf_in-network-service/kvsrc/netcache 6 | 7 | # fixed parameters 8 | Pages=2048 9 | #Pages=1024 10 | HUGEPGSZ=`cat /proc/meminfo | grep Hugepagesize | cut -d : -f 2 | tr -d ' '` 11 | #HUGEPGSZ='1048576kB' 12 | 13 | # 14 | # Unloads igb_uio.ko. 15 | # 16 | remove_igb_uio_module() 17 | { 18 | echo "Unloading any existing DPDK UIO module" 19 | /sbin/lsmod | grep -s igb_uio > /dev/null 20 | if [ $? -eq 0 ] ; then 21 | echo $passwd | sudo -S /sbin/rmmod igb_uio 22 | fi 23 | } 24 | 25 | # 26 | # Loads new igb_uio.ko (and uio module if needed). 27 | # 28 | load_igb_uio_module() 29 | { 30 | if [ ! -f $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko ];then 31 | echo "## ERROR: Target does not have the DPDK UIO Kernel Module." 32 | echo " To fix, please try to rebuild target." 33 | return 34 | fi 35 | 36 | remove_igb_uio_module 37 | 38 | /sbin/lsmod | grep -s uio > /dev/null 39 | if [ $? -ne 0 ] ; then 40 | modinfo uio > /dev/null 41 | if [ $? -eq 0 ]; then 42 | echo "Loading uio module" 43 | echo $passwd | sudo -S /sbin/modprobe uio 44 | fi 45 | fi 46 | 47 | # UIO may be compiled into kernel, so it may not be an error if it can't 48 | # be loaded. 49 | 50 | echo "Loading DPDK UIO module" 51 | echo $passwd | sudo -S /sbin/insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko 52 | if [ $? -ne 0 ] ; then 53 | echo "## ERROR: Could not load kmod/igb_uio.ko." 54 | quit 55 | fi 56 | } 57 | 58 | # 59 | # Creates hugepage filesystem. 60 | # 61 | create_mnt_huge() 62 | { 63 | echo "Creating /mnt/huge and mounting as hugetlbfs" 64 | echo $passwd | sudo -S mkdir -p /mnt/huge 65 | 66 | grep -s '/mnt/huge' /proc/mounts > /dev/null 67 | if [ $? -ne 0 ] ; then 68 | echo $passwd | sudo -S mount -t hugetlbfs nodev /mnt/huge 69 | fi 70 | } 71 | 72 | # 73 | # Removes hugepage filesystem. 74 | # 75 | remove_mnt_huge() 76 | { 77 | echo "Unmounting /mnt/huge and removing directory" 78 | grep -s '/mnt/huge' /proc/mounts > /dev/null 79 | if [ $? -eq 0 ] ; then 80 | echo $passwd | sudo -S umount /mnt/huge 81 | fi 82 | 83 | if [ -d /mnt/huge ] ; then 84 | echo $passwd | sudo -S rm -R /mnt/huge 85 | fi 86 | } 87 | 88 | # 89 | # Removes all reserved hugepages. 90 | # 91 | clear_huge_pages() 92 | { 93 | echo > .echo_tmp 94 | for d in /sys/devices/system/node/node? ; do 95 | echo "echo 0 > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp 96 | done 97 | echo "Removing currently reserved hugepages" 98 | echo $passwd | sudo -S sh .echo_tmp 99 | rm -f .echo_tmp 100 | 101 | remove_mnt_huge 102 | } 103 | 104 | # 105 | # Creates hugepages on specific NUMA nodes. 106 | # 107 | set_numa_pages() 108 | { 109 | clear_huge_pages 110 | 111 | echo > .echo_tmp 112 | for d in /sys/devices/system/node/node? ; do 113 | node=$(basename $d) 114 | echo "echo $Pages > $d/hugepages/hugepages-${HUGEPGSZ}/nr_hugepages" >> .echo_tmp 115 | done 116 | echo "Reserving hugepages" 117 | echo $passwd | sudo -S sh .echo_tmp 118 | rm -f .echo_tmp 119 | 120 | create_mnt_huge 121 | } 122 | 123 | # 124 | # Uses dpdk-devbind.py to move devices to work with igb_uio 125 | # 126 | bind_devices_to_igb_uio() 127 | { 128 | if [ -d /sys/module/igb_uio ]; then 129 | echo "Bind device to DPDK" 130 | echo $passwd | sudo -S $RTE_SDK/tools/dpdk-devbind.py -b igb_uio $PCI_PATH 131 | #${RTE_SDK}/tools/dpdk-devbind.py --status 132 | else 133 | echo "# Please load the 'igb_uio' kernel module before querying or " 134 | echo "# adjusting device bindings" 135 | fi 136 | } 137 | 138 | install_dpdk() { 139 | cd ~ 140 | rm -rf dpdk 141 | mkdir dpdk 142 | cd dpdk 143 | wget http://fast.dpdk.org/rel/dpdk-16.11.1.tar.gz 144 | tar xf dpdk-16.11.1.tar.gz 145 | cd dpdk-stable-16.11.1 146 | make install T=x86_64-native-linuxapp-gcc DESTDIR=$HOME/dpdk/dpdk-stable-16.11.1 147 | echo export\ RTE_SDK=$HOME/dpdk/dpdk-stable-16.11.1 >> $HOME/.bash_profile 148 | echo export\ RTE_TARGET=x86_64-native-linuxapp-gcc >> $HOME/.bash_profile 149 | source ~/.bash_profile 150 | } 151 | 152 | show_device() { 153 | $RTE_SDK/tools/dpdk-devbind.py --status 154 | } 155 | 156 | setup_dpdk() { 157 | # insert Insert IGB UIO module 158 | load_igb_uio_module 159 | 160 | # set hugepage mapping 161 | set_numa_pages 162 | 163 | # bind device 164 | bind_devices_to_igb_uio 165 | } 166 | 167 | bind_dpdk() { 168 | bind_devices_to_igb_uio 169 | } 170 | 171 | unbind_dpdk() { 172 | echo $passwd | sudo -S ${RTE_SDK}/tools/dpdk-devbind.py -u $PCI_PATH 173 | echo $passwd | sudo -S ${RTE_SDK}/tools/dpdk-devbind.py -b i40e $PCI_PATH 174 | } 175 | 176 | run_client() { 177 | cd $WORKDIR/cluster/client 178 | make 179 | cd $WORKDIR/result 180 | echo $passwd | sudo -S $WORKDIR/cluster/client/build/client -l 0,2 -- -z 99 -k 64 -m 10000 181 | } 182 | 183 | run_backend() { 184 | cd $WORKDIR/cluster/backend 185 | make 186 | cd $WORKDIR/result 187 | echo $passwd | sudo -S $WORKDIR/cluster/backend/build/backend -l 0 -- -m 10000 188 | } 189 | 190 | option="${1}" 191 | case ${option} in 192 | install_dpdk) 193 | install_dpdk 194 | ;; 195 | show_device) 196 | show_device 197 | ;; 198 | setup_dpdk) 199 | setup_dpdk 200 | ;; 201 | bind_dpdk) 202 | bind_dpdk 203 | ;; 204 | unbind_dpdk) 205 | unbind_dpdk 206 | ;; 207 | run_client) 208 | run_client 209 | ;; 210 | run_backend) 211 | run_backend 212 | ;; 213 | *) echo "usage:" 214 | echo " ./tools.sh install_dpdk: install dpdk" 215 | echo " ./tools.sh show_device: show device" 216 | echo " ./tools.sh setup_dpdk: setup dpdk" 217 | echo " ./tools.sh bind_dpdk: bind dpdk" 218 | echo " ./tools.sh unbind_dpdk: unbind dpdk" 219 | echo " ./tools.sh run_client: run client" 220 | echo " ./tools.sh run_backend: run backend" 221 | esac 222 | 223 | 224 | -------------------------------------------------------------------------------- /dpdk_code/client_code/statistic.py: -------------------------------------------------------------------------------- 1 | import os, sys, subprocess 2 | 3 | MAX_LOCK_NUM = 7000000 4 | 5 | def print_usage(): 6 | print "Usage:" 7 | print " ./statistic.py dirname client_num warehouse_num" 8 | return 9 | 10 | def do_map(dirname, client_num, warehouse): 11 | print "dirname:", dirname 12 | cmd_list = "ls -l " + dirname + " | grep trace | awk -F [' ']+ '{print $9}'" 13 | output_list = subprocess.check_output(cmd_list, shell=True).strip('\n') 14 | file_list = output_list.split('\n') 15 | lock_num = 50000 16 | print file_list 17 | count = [0 for i in range(lock_num)] 18 | for filename in file_list: 19 | fullname = dirname.split('\\')[0] + dirname.split('\\')[1] + "/" + filename 20 | print fullname 21 | fin = open(fullname) 22 | fin.readline() 23 | fin.readline() 24 | while True: 25 | line = fin.readline() 26 | if not line: 27 | break 28 | words = [x.strip() for x in line.split(',')] 29 | txn_id = int(words[0]) 30 | action_type = int(words[1]) 31 | target_lm_id = int(words[2]) 32 | target_obj_idx = int(words[3]) 33 | lock_type = int(words[4]) 34 | target_obj_idx = target_obj_idx + 1 35 | if (lock_type == 7) or (lock_type == 8): 36 | lock_type = 1 37 | elif (lock_type == 9): 38 | lock_type = 2 39 | lock_type = lock_type - 1 40 | 41 | if (target_obj_idx <= 20): 42 | lock_id = target_obj_idx 43 | else: 44 | lock_id = 20 + (target_obj_idx - 20) / 150 45 | count[lock_id] += 1 46 | l_count = [] 47 | for i in range(lock_num + 1): 48 | l_count.append((i, count[i])) 49 | l_count.sort(key = (lambda element:element[1]), reverse = True) 50 | fout = open("stat/tpcc_incast_"+ client_num +"_w_" + warehouse +"_domap.stat", "w") 51 | for i in range(lock_num + 1): 52 | if l_count[i][1] > 0: 53 | fout.write(str(l_count[i][0])+','+str(l_count[i][1])+'\n') 54 | fout.close() 55 | 56 | def no_map(dirname, client_num, warehouse): 57 | print "dirname:", dirname 58 | cmd_list = "ls -l " + dirname + " | grep trace | awk -F [' ']+ '{print $9}'" 59 | output_list = subprocess.check_output(cmd_list, shell=True).strip('\n') 60 | file_list = output_list.split('\n') 61 | print file_list 62 | lock_num = MAX_LOCK_NUM 63 | count = [0 for i in range(lock_num+1)] 64 | for filename in file_list: 65 | num_file = int(filename.strip('.csv').strip('trace_')) 66 | if num_file > 64+40: 67 | continue 68 | fullname = dirname.split('\\')[0] + dirname.split('\\')[1] + "/" + filename 69 | print fullname 70 | fin = open(fullname) 71 | fin.readline() 72 | fin.readline() 73 | while True: 74 | line = fin.readline() 75 | if not line: 76 | break 77 | words = [x.strip() for x in line.split(',')] 78 | if (len(words) <= 4): 79 | continue 80 | txn_id = int(words[0]) 81 | action_type = int(words[1]) 82 | if (action_type == 1): 83 | continue 84 | target_lm_id = int(words[2]) 85 | target_obj_idx = int(words[3]) 86 | lock_type = int(words[4]) 87 | target_obj_idx = target_obj_idx + 1 88 | if (lock_type == 7) or (lock_type == 8): 89 | lock_type = 1 90 | elif (lock_type == 9): 91 | lock_type = 2 92 | lock_type = lock_type - 1 93 | lock_id = target_obj_idx 94 | count[lock_id] += 1 95 | l_count = [] 96 | for i in range(lock_num + 1): 97 | l_count.append((i, count[i])) 98 | l_count.sort(key = (lambda element:element[1]), reverse = True) 99 | fout = open("stat/tpcc_multiserver_"+ client_num +"_w_" + warehouse +"_nomap.stat", "w") 100 | for i in range(lock_num + 1): 101 | if l_count[i][1] > 0: 102 | fout.write(str(l_count[i][0])+','+str(l_count[i][1])+'\n') 103 | fout.close() 104 | 105 | def max_lock_freq_per_txn(dirname, client_num, warehouse): 106 | print "dirname:", dirname 107 | cmd_list = "ls -l " + dirname + " | grep trace | awk -F [' ']+ '{print $9}'" 108 | output_list = subprocess.check_output(cmd_list, shell=True).strip('\n') 109 | file_list = output_list.split('\n') 110 | print file_list 111 | lock_num = MAX_LOCK_NUM 112 | old_txn_id = -1 113 | count = {} 114 | max_c = 0 115 | for filename in file_list: 116 | fullname = dirname.split('\\')[0] + dirname.split('\\')[1] + "/" + filename 117 | print fullname 118 | fin = open(fullname) 119 | fin.readline() 120 | fin.readline() 121 | while True: 122 | line = fin.readline() 123 | if not line: 124 | break 125 | words = [x.strip() for x in line.split(',')] 126 | txn_id = int(words[0]) 127 | 128 | 129 | action_type = int(words[1]) 130 | if action_type == 1: 131 | continue 132 | if (txn_id != old_txn_id): 133 | if (len(count) != 0): 134 | for i in count: 135 | if (count[i] > max_c): 136 | max_c = count[i] 137 | max_lock = i 138 | max_txn = old_txn_id 139 | count_log = count 140 | # if (max(count.values()) > max_c): 141 | # max_c = max(count.values()) 142 | # max_lock = max(count, key=count.get) 143 | # max_txn = old_txn_id 144 | # count_log = count 145 | old_txn_id = txn_id 146 | count = {} 147 | target_lm_id = int(words[2]) 148 | target_obj_idx = int(words[3]) 149 | lock_type = int(words[4]) 150 | target_obj_idx = target_obj_idx + 1 151 | if (lock_type == 7) or (lock_type == 8): 152 | lock_type = 1 153 | elif (lock_type == 9): 154 | lock_type = 2 155 | lock_type = lock_type - 1 156 | lock_id = target_obj_idx 157 | if (lock_id not in count): 158 | count[lock_id] = 1 159 | else: 160 | count[lock_id] += 1 161 | print max_txn, ":", max_lock, ":", max_c 162 | print count_log 163 | 164 | print "max count:", max_c 165 | 166 | def main(): 167 | if (len(sys.argv) <= 3): 168 | print_usage() 169 | sys.exit(-1) 170 | dirname = sys.argv[1] 171 | client_num = sys.argv[2] 172 | warehouse = sys.argv[3] 173 | # max_lock_freq_per_txn(dirname, client_num, warehouse) 174 | no_map(dirname, client_num, warehouse) 175 | 176 | 177 | if __name__ == '__main__': 178 | main() -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/statistic.py: -------------------------------------------------------------------------------- 1 | import os, sys, subprocess 2 | 3 | MAX_LOCK_NUM = 7000000 4 | 5 | def print_usage(): 6 | print "Usage:" 7 | print " ./statistic.py dirname client_num warehouse_num" 8 | return 9 | 10 | def do_map(dirname, client_num, warehouse): 11 | print "dirname:", dirname 12 | cmd_list = "ls -l " + dirname + " | grep trace | awk -F [' ']+ '{print $9}'" 13 | output_list = subprocess.check_output(cmd_list, shell=True).strip('\n') 14 | file_list = output_list.split('\n') 15 | lock_num = 50000 16 | print file_list 17 | count = [0 for i in range(lock_num)] 18 | for filename in file_list: 19 | fullname = dirname.split('\\')[0] + dirname.split('\\')[1] + "/" + filename 20 | print fullname 21 | fin = open(fullname) 22 | fin.readline() 23 | fin.readline() 24 | while True: 25 | line = fin.readline() 26 | if not line: 27 | break 28 | words = [x.strip() for x in line.split(',')] 29 | txn_id = int(words[0]) 30 | action_type = int(words[1]) 31 | target_lm_id = int(words[2]) 32 | target_obj_idx = int(words[3]) 33 | lock_type = int(words[4]) 34 | target_obj_idx = target_obj_idx + 1 35 | if (lock_type == 7) or (lock_type == 8): 36 | lock_type = 1 37 | elif (lock_type == 9): 38 | lock_type = 2 39 | lock_type = lock_type - 1 40 | 41 | if (target_obj_idx <= 20): 42 | lock_id = target_obj_idx 43 | else: 44 | lock_id = 20 + (target_obj_idx - 20) / 150 45 | count[lock_id] += 1 46 | l_count = [] 47 | for i in range(lock_num + 1): 48 | l_count.append((i, count[i])) 49 | l_count.sort(key = (lambda element:element[1]), reverse = True) 50 | fout = open("stat/tpcc_incast_"+ client_num +"_w_" + warehouse +"_domap.stat", "w") 51 | for i in range(lock_num + 1): 52 | if l_count[i][1] > 0: 53 | fout.write(str(l_count[i][0])+','+str(l_count[i][1])+'\n') 54 | fout.close() 55 | 56 | def no_map(dirname, client_num, warehouse): 57 | print "dirname:", dirname 58 | cmd_list = "ls -l " + dirname + " | grep trace | awk -F [' ']+ '{print $9}'" 59 | output_list = subprocess.check_output(cmd_list, shell=True).strip('\n') 60 | file_list = output_list.split('\n') 61 | print file_list 62 | lock_num = MAX_LOCK_NUM 63 | count = [0 for i in range(lock_num+1)] 64 | for filename in file_list: 65 | num_file = int(filename.strip('.csv').strip('trace_')) 66 | if num_file > 64+40: 67 | continue 68 | fullname = dirname.split('\\')[0] + dirname.split('\\')[1] + "/" + filename 69 | print fullname 70 | fin = open(fullname) 71 | fin.readline() 72 | fin.readline() 73 | while True: 74 | line = fin.readline() 75 | if not line: 76 | break 77 | words = [x.strip() for x in line.split(',')] 78 | if (len(words) <= 4): 79 | continue 80 | txn_id = int(words[0]) 81 | action_type = int(words[1]) 82 | if (action_type == 1): 83 | continue 84 | target_lm_id = int(words[2]) 85 | target_obj_idx = int(words[3]) 86 | lock_type = int(words[4]) 87 | target_obj_idx = target_obj_idx + 1 88 | if (lock_type == 7) or (lock_type == 8): 89 | lock_type = 1 90 | elif (lock_type == 9): 91 | lock_type = 2 92 | lock_type = lock_type - 1 93 | lock_id = target_obj_idx 94 | count[lock_id] += 1 95 | l_count = [] 96 | for i in range(lock_num + 1): 97 | l_count.append((i, count[i])) 98 | l_count.sort(key = (lambda element:element[1]), reverse = True) 99 | fout = open("stat/tpcc_multiserver_"+ client_num +"_w_" + warehouse +"_nomap.stat", "w") 100 | for i in range(lock_num + 1): 101 | if l_count[i][1] > 0: 102 | fout.write(str(l_count[i][0])+','+str(l_count[i][1])+'\n') 103 | fout.close() 104 | 105 | def max_lock_freq_per_txn(dirname, client_num, warehouse): 106 | print "dirname:", dirname 107 | cmd_list = "ls -l " + dirname + " | grep trace | awk -F [' ']+ '{print $9}'" 108 | output_list = subprocess.check_output(cmd_list, shell=True).strip('\n') 109 | file_list = output_list.split('\n') 110 | print file_list 111 | lock_num = MAX_LOCK_NUM 112 | old_txn_id = -1 113 | count = {} 114 | max_c = 0 115 | for filename in file_list: 116 | fullname = dirname.split('\\')[0] + dirname.split('\\')[1] + "/" + filename 117 | print fullname 118 | fin = open(fullname) 119 | fin.readline() 120 | fin.readline() 121 | while True: 122 | line = fin.readline() 123 | if not line: 124 | break 125 | words = [x.strip() for x in line.split(',')] 126 | txn_id = int(words[0]) 127 | 128 | 129 | action_type = int(words[1]) 130 | if action_type == 1: 131 | continue 132 | if (txn_id != old_txn_id): 133 | if (len(count) != 0): 134 | for i in count: 135 | if (count[i] > max_c): 136 | max_c = count[i] 137 | max_lock = i 138 | max_txn = old_txn_id 139 | count_log = count 140 | # if (max(count.values()) > max_c): 141 | # max_c = max(count.values()) 142 | # max_lock = max(count, key=count.get) 143 | # max_txn = old_txn_id 144 | # count_log = count 145 | old_txn_id = txn_id 146 | count = {} 147 | target_lm_id = int(words[2]) 148 | target_obj_idx = int(words[3]) 149 | lock_type = int(words[4]) 150 | target_obj_idx = target_obj_idx + 1 151 | if (lock_type == 7) or (lock_type == 8): 152 | lock_type = 1 153 | elif (lock_type == 9): 154 | lock_type = 2 155 | lock_type = lock_type - 1 156 | lock_id = target_obj_idx 157 | if (lock_id not in count): 158 | count[lock_id] = 1 159 | else: 160 | count[lock_id] += 1 161 | print max_txn, ":", max_lock, ":", max_c 162 | print count_log 163 | 164 | print "max count:", max_c 165 | 166 | def main(): 167 | if (len(sys.argv) <= 3): 168 | print_usage() 169 | sys.exit(-1) 170 | dirname = sys.argv[1] 171 | client_num = sys.argv[2] 172 | warehouse = sys.argv[3] 173 | # max_lock_freq_per_txn(dirname, client_num, warehouse) 174 | no_map(dirname, client_num, warehouse) 175 | 176 | 177 | if __name__ == '__main__': 178 | main() -------------------------------------------------------------------------------- /dpdk_code/client_code/include/new_order.h: -------------------------------------------------------------------------------- 1 | // tpc-c 2 | #define DEBUG 3 | #ifndef TPCC 4 | #define TPCC 5 | #define ITEM_PER_WARE 100000 6 | #define DIST_PER_WARE 10 7 | #define CUST_PER_DIST 3000 8 | #define ROLL_BACK 0 9 | 10 | #include 11 | #include 12 | #include 13 | #include "new_order.h" 14 | 15 | #define min(a,b) \ 16 | ({ __typeof__ (a) _a = (a); \ 17 | __typeof__ (b) _b = (b); \ 18 | _a < _b ? _a : _b; }) 19 | // * C is a run-time constant randomly chosen within [0 .. A] that can be varied without altering performance. The same C value, per field (C_LAST, C_ID, and OL_I_ID), must be used by all emulated terminals. 20 | // * NURand(A,x,y)=(((random(0,A)| random(x,y))+C)%(y-x+1))+x 21 | 22 | // * 1: SHARED; 2: EXCLUSIVE; 8:TABLE_LOCK_SHARED; 9: TABLE_LOCK_EXCLUSIVE. 23 | 24 | static uint32_t get_random(uint32_t x, uint32_t y) { 25 | return ((rand() % (y - x + 1)) + x); 26 | } 27 | 28 | static uint32_t NURand(uint32_t A, uint32_t x, uint32_t y, uint32_t C) { 29 | return ((((get_random(0,A) | get_random(x,y)) + C) % (y-x+1)) + x); 30 | } 31 | 32 | 33 | 34 | static void get_batch_map(uint32_t *map) { 35 | FILE *fin, *fp; 36 | char filename[200]; 37 | char command[200]; 38 | int line_c = 0, a,b; 39 | sprintf(filename, "../batch/batch_%d.in", batch_size); 40 | sprintf(command, "wc -l %s | awk -F '[ ]'+ '{print $1}'", filename); 41 | DEBUG_PRINT("command: %s\n", command); 42 | fp = popen(command, "r"); 43 | if (fp == NULL) { 44 | fprintf(stderr, "Failed to run command\n"); 45 | return; 46 | } 47 | if (fscanf(fp, "%d", &line_c) == EOF) { 48 | fprintf(stderr, "RUN SHELL ERROR\n"); 49 | return; 50 | } 51 | fclose(fp); 52 | 53 | fin = fopen(filename, "r"); 54 | for (int i=0; i= 0) && ((*txn_id)[backward_i] == c_txn_id)) { 166 | if ((*target_obj_idx)[backward_i] == c_target_obj_idx) { 167 | if (task_id == 'g') { 168 | if ((c_lock_type == 2) || (c_lock_type == 9)) 169 | (*lock_type)[backward_i] = 1; 170 | } 171 | same_lock_flag = 1; 172 | break; 173 | } 174 | backward_i --; 175 | } 176 | if (same_lock_flag == 1) 177 | continue; 178 | j = (*len); 179 | (*txn_id)[j] = c_txn_id; 180 | (*action_type)[j] = c_action_type; 181 | (*target_lm_id)[j] = c_target_lm_id; 182 | (*target_obj_idx)[j] = c_target_obj_idx; 183 | 184 | (*lock_type)[j] = c_lock_type; 185 | 186 | 187 | 188 | // (*target_obj_idx)[i] ++; 189 | 190 | if (((*lock_type)[j] == 7) || ((*lock_type)[j] == 8) || ((*lock_type)[j] == 1)) { 191 | (*lock_type)[j] = 0; 192 | } 193 | else if (((*lock_type)[j] == 9) || ((*lock_type)[j] == 2)) { 194 | (*lock_type)[j] = 1; 195 | } 196 | 197 | if ((*action_type)[j] == 0) { 198 | locks_each_txn[lcore_id][(*txn_id)[j]] ++; 199 | count_a ++; 200 | } 201 | else if ((*action_type)[j] == 1) { 202 | count_r ++; 203 | } 204 | (*len) ++; 205 | 206 | } 207 | 208 | fclose(fin); 209 | fprintf(stderr, "count_a: %d, count_r: %d\n", count_a, count_r); 210 | } 211 | 212 | #endif -------------------------------------------------------------------------------- /traces/microbenchmark/micro_bm_gen.py: -------------------------------------------------------------------------------- 1 | import os,sys 2 | import csv 3 | lib_path = os.path.abspath(os.path.join('../../client')) 4 | sys.path.append(lib_path) 5 | from config import * 6 | import random 7 | from random import randint 8 | 9 | class MicroBenchmark: 10 | def __init__(self, lock_type = SHARED_LOCK, max_lock_id = 100000, server_number = 10, threads_per_server = 2): 11 | self.lock_per_server = max_lock_id / server_number 12 | if (lock_type == SHARED_LOCK): 13 | self.lock_type = 1 14 | elif (lock_type == EXCLUSIVE_LOCK): 15 | self.lock_type = 2 16 | self.max_lock_id = max_lock_id 17 | self.server_number = server_number 18 | self.threads_per_server = threads_per_server 19 | #for i in range(1, server_number + 1): 20 | 21 | def main(): 22 | micro_benchmark = MicroBenchmark(SHARED_LOCK, 120000, 12) 23 | for i in range(1, micro_benchmark.server_number + 1): 24 | with open('shared/micro_bm_s'+str(i)+'.csv', mode='w') as output_file: 25 | csv_writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) 26 | csv_writer.writerow(['** on machine #'+str(i)]) 27 | csv_writer.writerow(["** txn_id", "action", "target_lm_id", "target_obj_idx", "lock_type"]) 28 | for j in range(1, micro_benchmark.lock_per_server + 1): 29 | txn_id = j % 1000 30 | action = ACQUIRE_LOCK 31 | target_lm_id = 2 32 | #lock_id = (i-1) * micro_benchmark.lock_per_server + j 33 | lock_id = i - 1 34 | lock_type = micro_benchmark.lock_type 35 | csv_writer.writerow([txn_id, action, target_lm_id, lock_id, lock_type]) 36 | 37 | ## exclusive locks contention on client itself (between threads) hold by switch (2) 38 | micro_benchmark = MicroBenchmark(EXCLUSIVE_LOCK, 54000, 12) 39 | for i in range(1, micro_benchmark.server_number + 1): 40 | with open('ex_old/micro_bm_x'+str(i)+'.csv', mode='w') as output_file: 41 | csv_writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) 42 | csv_writer.writerow(['** on machine #'+str(i)]) 43 | csv_writer.writerow(["** txn_id", "action", "target_lm_id", "target_obj_idx", "lock_type"]) 44 | for j in range(1, micro_benchmark.lock_per_server + 1): 45 | txn_id = j % 1000 46 | action = ACQUIRE_LOCK 47 | target_lm_id = 2 48 | lock_id = (i-1) * micro_benchmark.lock_per_server + j 49 | lock_type = micro_benchmark.lock_type 50 | csv_writer.writerow([txn_id, action, target_lm_id, lock_id, lock_type]) 51 | 52 | ## exclusive locks contention on clients (not on threads) hold by switch (2) 53 | micro_benchmark = MicroBenchmark(EXCLUSIVE_LOCK, 54000, 12) 54 | for i in range(1, micro_benchmark.server_number + 1): 55 | for l in range(1, 3): 56 | with open('ex_old/micro_bm_x'+str(i)+"_lc"+str(l+5)+'.csv', mode='w') as output_file: 57 | csv_writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) 58 | csv_writer.writerow(['** on machine #'+str(i)+' contention_degree: 2']) 59 | csv_writer.writerow(["** txn_id", "action", "target_lm_id", "target_obj_idx", "lock_type"]) 60 | for j in range((l-1) * micro_benchmark.lock_per_server + 1, l * micro_benchmark.lock_per_server + 1): 61 | txn_id = j % 1000 62 | action = ACQUIRE_LOCK 63 | target_lm_id = 2 64 | lock_id = ((i-1) * micro_benchmark.lock_per_server + j + 55000 - 1) % 55000 + 1 65 | lock_type = micro_benchmark.lock_type 66 | csv_writer.writerow([txn_id, action, target_lm_id, lock_id, lock_type]) 67 | 68 | ## exclusive locks contention on clients (not on threads) can't hold by switch 69 | for contention_degree in range(1,7): 70 | micro_benchmark = MicroBenchmark(EXCLUSIVE_LOCK, 54000, 12) 71 | for i in range(1, micro_benchmark.server_number + 1): 72 | for l in range(1, 3): 73 | with open('contention/queue_size_2/micro_bm_x'+str(i)+"_cd"+str(contention_degree)+"_lc"+str(l+5)+'.csv', mode='w') as output_file: 74 | csv_writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) 75 | csv_writer.writerow(['** on machine #'+str(i)+' contention_degree: '+str(contention_degree)]) 76 | csv_writer.writerow(["** txn_id", "action", "target_lm_id", "target_obj_idx", "lock_type"]) 77 | for j in range((l-1) * micro_benchmark.lock_per_server * contention_degree / micro_benchmark.threads_per_server + 1, 78 | l * micro_benchmark.lock_per_server * contention_degree / micro_benchmark.threads_per_server + 1): 79 | txn_id = j % 1000 80 | action = ACQUIRE_LOCK 81 | target_lm_id = 2 82 | lock_id = ((i-1) * micro_benchmark.lock_per_server + j + 55000 - 1) % 55000 + 1 83 | lock_type = micro_benchmark.lock_type 84 | csv_writer.writerow([txn_id, action, target_lm_id, lock_id, lock_type]) 85 | return 86 | ## exclusive locks, test different contention (decide by number clients*threads, switch can hold) 87 | client_num = 1200 88 | # lock_nums = [1, 2, 3, 6, 10, 12, 20, 24, 30, 40, 50, 60, 70, 80, 90, 100, 120, 150, 200, 250, 300] 89 | # lock_nums = [150, 200, 250, 300, 350] 90 | lock_nums = [] 91 | server_num = 12 92 | micro_benchmark = MicroBenchmark(EXCLUSIVE_LOCK, 55000, server_num, client_num / server_num) 93 | for lk in lock_nums: 94 | for i in range(1, micro_benchmark.server_number + 1): 95 | for j in range(0, micro_benchmark.threads_per_server): 96 | with open('contention/lk'+str(lk)+'/micro_bm_x'+str(i)+"_t"+str(j)+"_lk"+str(lk)+".csv", mode = 'w') as output_file: 97 | csv_writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) 98 | csv_writer.writerow(['** on machine #'+str(i)+' client: '+str(j)]) 99 | csv_writer.writerow(["** txn_id", "action", "target_lm_id", "target_obj_idx", "lock_type"]) 100 | for l in range(1200): 101 | lock_id = randint(0, lk - 1) 102 | txn_id = l % 1000 103 | action = ACQUIRE_LOCK 104 | target_lm_id = 2 105 | lock_type = micro_benchmark.lock_type 106 | csv_writer.writerow([txn_id, action, target_lm_id, lock_id, lock_type]) 107 | 108 | ## exclusive locks, test different contention (decide by number of locks, switch can hold) 109 | client_num = 24 110 | # lock_nums = [1, 2, 3, 6, 10, 12, 20, 24, 30, 40, 50, 60, 70, 80, 90, 100, 120, 150, 200, 250, 300] 111 | # lock_nums = [150, 200, 250, 300, 350] 112 | # lock_nums = [2, 10, 100, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 8000, 10000] 113 | lock_nums = [2, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000, 6500, 7000, 7500, 8000, 8500, 9000, 9500, 10000] 114 | server_num = 12 115 | micro_benchmark = MicroBenchmark(EXCLUSIVE_LOCK, 55000, server_num, client_num / server_num) 116 | for lk in lock_nums: 117 | for i in range(1, micro_benchmark.server_number + 1): 118 | lk_list = range(lk) 119 | random.shuffle(lk_list) 120 | os.system("mkdir -p contention_shuffle; mkdir -p contention_shuffle/lk"+str(lk)) 121 | for j in range(0, micro_benchmark.threads_per_server): 122 | ## cache miss 123 | shard_list = lk_list[j*lk / micro_benchmark.threads_per_server:(j+1)*lk / micro_benchmark.threads_per_server] 124 | shard_list.sort() 125 | with open('contention_shuffle/lk'+str(lk)+'/micro_bm_x'+str(i)+"_t"+str(j)+"_lk"+str(lk)+".csv", mode = 'w') as output_file: 126 | csv_writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) 127 | csv_writer.writerow(['** on machine #'+str(i)+' client: '+str(j)]) 128 | csv_writer.writerow(["** txn_id", "action", "target_lm_id", "target_obj_idx", "lock_type"]) 129 | for l in range(lk / micro_benchmark.threads_per_server): 130 | # lock_id = j * lk / micro_benchmark.threads_per_server + lk_list[l + j * j * lk / micro_benchmark.threads_per_server] 131 | lock_id = lk_list[l + j * lk / micro_benchmark.threads_per_server] 132 | #lock_id = shard_list[l] 133 | txn_id = l % 1000 134 | action = ACQUIRE_LOCK 135 | target_lm_id = 2 136 | lock_type = micro_benchmark.lock_type 137 | csv_writer.writerow([txn_id, action, target_lm_id, lock_id, lock_type]) 138 | 139 | 140 | 141 | if __name__ == '__main__': 142 | main() -------------------------------------------------------------------------------- /switch_code/netlock/p4src/actions.p4: -------------------------------------------------------------------------------- 1 | // #### actions 2 | action decode_action() { 3 | // get_queue_size_op_alu.execute_stateful_alu(nlk_hdr.lock); 4 | get_queue_size_op_alu.execute_stateful_alu(meta.lock_id); 5 | modify_field(meta.ts_hi, nlk_hdr.timestamp_hi); 6 | modify_field(meta.ts_lo, nlk_hdr.timestamp_lo); 7 | // shift_right(meta.ts_hi, nlk_hdr.timestamp, 32); 8 | // bit_and(meta.ts_lo, nlk_hdr.timestamp, 4294967295); 9 | } 10 | 11 | action forward_to_server_action(server_ip) { 12 | // ## redirect the packet to server ## 13 | //modify_field(nlk_hdr.op, FORWARD_LOCK); 14 | // modify_field(ipv4.srcAddr, DEDICATED_SERVER_IP); 15 | // modify_field(ipv4.dstAddr, DEDICATED_SERVER_IP); 16 | modify_field(ipv4.srcAddr, server_ip); 17 | modify_field(ipv4.dstAddr, server_ip); 18 | } 19 | 20 | action get_left_bound_action() { 21 | // get_left_bound_alu.execute_stateful_alu(nlk_hdr.lock); 22 | get_left_bound_alu.execute_stateful_alu(meta.lock_id); 23 | } 24 | 25 | action get_right_bound_action() { 26 | // get_right_bound_alu.execute_stateful_alu(nlk_hdr.lock); 27 | get_right_bound_alu.execute_stateful_alu(meta.lock_id); 28 | } 29 | 30 | action update_tail_action() { 31 | // update_tail_alu.execute_stateful_alu(nlk_hdr.lock); 32 | update_tail_alu.execute_stateful_alu(meta.lock_id); 33 | } 34 | 35 | action update_mode_array_action() { 36 | update_mode_array_alu.execute_stateful_alu(meta.tail); 37 | } 38 | 39 | action update_ip_array_action() { 40 | update_ip_array_alu.execute_stateful_alu(meta.tail); 41 | } 42 | 43 | action update_tid_array_action() { 44 | update_tid_array_alu.execute_stateful_alu(meta.tail); 45 | } 46 | 47 | action acquire_shared_lock_action() { 48 | // acquire_shared_lock_alu.execute_stateful_alu(nlk_hdr.lock); 49 | acquire_shared_lock_alu.execute_stateful_alu(meta.lock_id); 50 | } 51 | 52 | action acquire_exclusive_lock_action() { 53 | // acquire_exclusive_lock_alu.execute_stateful_alu(nlk_hdr.lock); 54 | acquire_exclusive_lock_alu.execute_stateful_alu(meta.lock_id); 55 | } 56 | 57 | action notify_tail_client_action() { 58 | modify_field(ipv4.dstAddr, ipv4.srcAddr); 59 | // modify_field(udp.dstPort, REPLY_PORT); 60 | } 61 | 62 | action notify_tail_client_1_action() { 63 | /* 64 | * Not using 65 | */ 66 | // ## notify the client that has obtained the lock ## 67 | modify_field(meta.src_ip, ipv4.srcAddr); 68 | modify_field(meta.dst_ip, ipv4.dstAddr); 69 | modify_field(udp.dstPort, REPLY_PORT); 70 | // modify_field(udp.dstPort, LK_PORT); 71 | } 72 | 73 | action notify_tail_client_2_action() { 74 | /* 75 | * Not using 76 | */ 77 | modify_field(ipv4.srcAddr, meta.dst_ip); 78 | modify_field(ipv4.dstAddr, meta.src_ip); 79 | } 80 | 81 | action i2e_mirror_action(mirror_id) { 82 | // ## notify the client that has obtained the lock ## 83 | modify_field(current_node_meta.clone_md, 1); 84 | 85 | #if __TARGET_TOFINO__ == 2 86 | modify_field(ig_intr_md_for_mb.mirror_hash, 2); 87 | modify_field(ig_intr_md_for_mb.mirror_multicast_ctrl, 0); 88 | modify_field(ig_intr_md_for_mb.mirror_io_select, 0); 89 | #endif 90 | clone_ingress_pkt_to_egress(mirror_id, nl_i2e_mirror_info); 91 | } 92 | 93 | 94 | // ## 95 | 96 | action update_head_action() { 97 | // update_head_alu.execute_stateful_alu(nlk_hdr.lock); 98 | update_head_alu.execute_stateful_alu(meta.lock_id); 99 | } 100 | 101 | action get_tail_action() { 102 | // get_tail_alu.execute_stateful_alu(nlk_hdr.lock); 103 | get_tail_alu.execute_stateful_alu(meta.lock_id); 104 | } 105 | 106 | action get_head_action() { 107 | // get_head_alu.execute_stateful_alu(nlk_hdr.lock); 108 | get_head_alu.execute_stateful_alu(meta.lock_id); 109 | } 110 | 111 | action metahead_plus_1_action() { 112 | modify_field(meta.head, meta.left); 113 | } 114 | 115 | action metahead_plus_2_action() { 116 | add_to_field(meta.head, 1); 117 | } 118 | 119 | action get_tid_action() { 120 | get_tid_alu.execute_stateful_alu(meta.head); 121 | } 122 | 123 | action get_mode_action() { 124 | get_mode_alu.execute_stateful_alu(meta.head); 125 | } 126 | 127 | action get_ip_action() { 128 | get_ip_alu.execute_stateful_alu(meta.head); 129 | } 130 | 131 | action update_lock_action() { 132 | // update_lock_alu.execute_stateful_alu(nlk_hdr.lock); 133 | update_lock_alu.execute_stateful_alu(meta.lock_id); 134 | } 135 | 136 | action notify_controller_action() { 137 | // ## notify the controller when the queue is empty #### 138 | modify_field(ig_intr_md_for_tm.copy_to_cpu, 1); 139 | _drop(); 140 | // modify_field(ipv4.dstAddr, CONTROLLER_IP); 141 | } 142 | 143 | 144 | 145 | // ## modify_bound 146 | action modify_left_action() { 147 | modify_left_alu.execute_stateful_alu(adm_hdr.lock); 148 | } 149 | 150 | action modify_right_action() { 151 | modify_right_alu.execute_stateful_alu(adm_hdr.lock); 152 | } 153 | 154 | action modify_head_action() { 155 | modify_head_alu.execute_stateful_alu(adm_hdr.lock); 156 | } 157 | 158 | action modify_tail_action() { 159 | modify_tail_alu.execute_stateful_alu(adm_hdr.lock); 160 | } 161 | 162 | // ## set_shrink 163 | action set_shrink_action() { 164 | set_queue_size_op_alu.execute_stateful_alu(adm_hdr.lock); 165 | } 166 | 167 | action shrink_finish_action() { 168 | clr_queue_size_op_alu.execute_stateful_alu(adm_hdr.lock); 169 | } 170 | 171 | // ## resubmit 172 | action mark_to_resubmit_action() { 173 | // modify_field(resubmit_meta.resubmit_flag, 1); 174 | // modify_field(resubmit_meta.dequeued_mode, current_node_meta.mode); 175 | // modify_field(meta.do_resubmit, 1); 176 | 177 | modify_field(nlk_hdr.recirc_flag, 1); 178 | add_header(recirculate_hdr); 179 | modify_field(recirculate_hdr.cur_tail, meta.tail); 180 | modify_field(recirculate_hdr.cur_head, meta.head); 181 | modify_field(recirculate_hdr.dequeued_mode, current_node_meta.mode); 182 | modify_field(meta.do_resubmit, 1); 183 | } 184 | 185 | action resubmit_action() { 186 | // resubmit(redirect_FL); 187 | 188 | recirculate(68); 189 | modify_field(meta.recirced, 1); 190 | } 191 | 192 | action mark_to_resubmit_2_action() { 193 | modify_field(nlk_hdr.recirc_flag, 2); 194 | modify_field(recirculate_hdr.cur_tail, meta.tail); 195 | modify_field(recirculate_hdr.cur_head, meta.head); 196 | modify_field(meta.do_resubmit, 1); 197 | } 198 | 199 | action notify_head_client_action() { 200 | //modify_field(nlk_hdr.mode, current_node_meta.mode); 201 | //modify_field(ipv4.srcAddr, DEDICATED_SERVER_IP); 202 | modify_field(ipv4.dstAddr, current_node_meta.ip_address); 203 | } 204 | 205 | action get_recirc_info_action() { 206 | modify_field(meta.tail, recirculate_hdr.cur_tail); 207 | modify_field(meta.head, recirculate_hdr.cur_head); 208 | modify_field(meta.recirc_flag, nlk_hdr.recirc_flag); 209 | modify_field(meta.dequeued_mode, recirculate_hdr.dequeued_mode); 210 | //modify_field(meta.queue_not_empty, 1); 211 | } 212 | 213 | action inc_empty_slots_action() { 214 | // inc_empty_slots_alu.execute_stateful_alu(nlk_hdr.lock); 215 | inc_empty_slots_alu.execute_stateful_alu(meta.lock_id); 216 | } 217 | 218 | action dec_empty_slots_action() { 219 | // dec_empty_slots_alu.execute_stateful_alu(nlk_hdr.lock); 220 | dec_empty_slots_alu.execute_stateful_alu(meta.lock_id); 221 | } 222 | 223 | action push_back_action() { 224 | // push_back_alu.execute_stateful_alu(nlk_hdr.lock); 225 | push_back_alu.execute_stateful_alu(meta.lock_id); 226 | } 227 | 228 | action inc_length_in_server_action() { 229 | // inc_length_in_server_alu.execute_stateful_alu(nlk_hdr.lock); 230 | inc_length_in_server_alu.execute_stateful_alu(meta.lock_id); 231 | } 232 | 233 | action modify_empty_slots_action() { 234 | modify_empty_slots_alu.execute_stateful_alu(adm_hdr.lock); 235 | } 236 | 237 | action get_length_action() { 238 | subtract(meta.empty_slots, adm_hdr.new_right, adm_hdr.new_left); 239 | } 240 | 241 | 242 | 243 | action get_size_of_queue_action() { 244 | subtract(meta.size_of_queue, meta.right, meta.left); 245 | } 246 | 247 | action update_timestamp_hi_array_action() { 248 | update_timestamp_hi_array_alu.execute_stateful_alu(meta.tail); 249 | } 250 | 251 | action update_timestamp_lo_array_action() { 252 | update_timestamp_lo_array_alu.execute_stateful_alu(meta.tail); 253 | } 254 | 255 | action get_timestamp_hi_action() { 256 | get_timestamp_hi_alu.execute_stateful_alu(meta.head); 257 | } 258 | 259 | action get_timestamp_lo_action() { 260 | get_timestamp_lo_alu.execute_stateful_alu(meta.head); 261 | } 262 | 263 | action update_client_id_array_action() { 264 | update_client_id_array_alu.execute_stateful_alu(meta.tail); 265 | } 266 | 267 | action get_client_id_action() { 268 | get_client_id_alu.execute_stateful_alu(meta.head); 269 | } 270 | 271 | action set_as_primary_action() { 272 | modify_field(ethernet.dstAddr, PRIMARY_BACKUP); 273 | } 274 | 275 | action set_as_secondary_action() { 276 | modify_field(ethernet.dstAddr, SECONDARY_BACKUP); 277 | } 278 | 279 | action check_lock_exist_action(index) { 280 | modify_field(meta.lock_exist, 1); 281 | modify_field(meta.lock_id, index); 282 | } 283 | 284 | action change_mode_act(udp_src_port) { 285 | modify_field(nlk_hdr.mode, current_node_meta.mode); 286 | modify_field(nlk_hdr.tid, current_node_meta.tid); 287 | modify_field(nlk_hdr.timestamp_lo, current_node_meta.timestamp_lo); 288 | modify_field(nlk_hdr.timestamp_hi, current_node_meta.timestamp_hi); 289 | modify_field(nlk_hdr.client_id, current_node_meta.client_id); 290 | modify_field(ipv4.dstAddr, current_node_meta.ip_address); 291 | modify_field(ipv4.srcAddr, current_node_meta.ip_address); 292 | modify_field(udp.srcPort, udp_src_port); 293 | modify_field(udp.dstPort, LK_PORT); 294 | } 295 | 296 | action fix_src_port_action(fix_port) { 297 | modify_field(ethernet.srcAddr, ipv4.srcAddr); 298 | modify_field(udp.srcPort, fix_port); 299 | } 300 | 301 | action set_as_failure_notification_action() { 302 | modify_field(ethernet.dstAddr, FAILURE_NOTIFICATION); 303 | } 304 | 305 | action check_failure_status_action() { 306 | check_failure_status_alu.execute_stateful_alu(0); 307 | } 308 | 309 | action set_failure_status_action() { 310 | modify_field(probe_hdr.failure_status, meta.failure_status); 311 | } 312 | -------------------------------------------------------------------------------- /switch_code/netlock/p4src/tables.p4: -------------------------------------------------------------------------------- 1 | // #### tables 2 | @pragma stage 1 3 | table decode_table { 4 | actions { 5 | decode_action; 6 | } 7 | default_action: decode_action; 8 | } 9 | 10 | @pragma stage 1 11 | table shrink_finish_table { 12 | actions { 13 | shrink_finish_action; 14 | } 15 | default_action: shrink_finish_action; 16 | } 17 | 18 | @pragma stage 0 19 | table get_length_table { 20 | actions { 21 | get_length_action; 22 | } 23 | default_action: get_length_action; 24 | } 25 | 26 | @pragma stage 1 27 | table set_shrink_table { 28 | actions { 29 | set_shrink_action; 30 | } 31 | default_action: set_shrink_action; 32 | } 33 | 34 | 35 | 36 | @pragma stage 1 37 | table get_left_bound_table { 38 | actions { 39 | get_left_bound_action; 40 | } 41 | default_action: get_left_bound_action; 42 | } 43 | 44 | @pragma stage 1 45 | table get_right_bound_table { 46 | actions { 47 | get_right_bound_action; 48 | } 49 | default_action: get_right_bound_action; 50 | } 51 | 52 | @pragma stage 1 53 | table modify_left_table { 54 | actions { 55 | modify_left_action; 56 | } 57 | default_action: modify_left_action; 58 | } 59 | 60 | @pragma stage 1 61 | table modify_right_table { 62 | actions { 63 | modify_right_action; 64 | } 65 | default_action: modify_right_action; 66 | } 67 | 68 | 69 | @pragma stage 4 70 | table update_tail_table { 71 | actions { 72 | update_tail_action; 73 | } 74 | default_action: update_tail_action; 75 | } 76 | 77 | @pragma stage 3 78 | table update_head_table { 79 | actions { 80 | update_head_action; 81 | } 82 | default_action: update_head_action; 83 | } 84 | 85 | @pragma stage 2 86 | table get_recirc_info_table { 87 | actions { 88 | get_recirc_info_action; 89 | } 90 | default_action: get_recirc_info_action; 91 | } 92 | 93 | @pragma stage 4 94 | table get_tail_table { 95 | actions { 96 | get_tail_action; 97 | } 98 | default_action: get_tail_action; 99 | } 100 | 101 | @pragma stage 2 102 | table inc_empty_slots_table { 103 | actions { 104 | inc_empty_slots_action; 105 | } 106 | default_action: inc_empty_slots_action; 107 | } 108 | 109 | @pragma stage 2 110 | table dec_empty_slots_table { 111 | reads { 112 | nlk_hdr.op: exact; 113 | } 114 | actions { 115 | dec_empty_slots_action; 116 | push_back_action; 117 | } 118 | } 119 | 120 | @pragma stage 2 121 | table modify_empty_slots_table { 122 | actions { 123 | modify_empty_slots_action; 124 | } 125 | default_action: modify_empty_slots_action; 126 | } 127 | 128 | @pragma stage 3 129 | table modify_head_table { 130 | actions { 131 | modify_head_action; 132 | } 133 | default_action: modify_head_action; 134 | } 135 | 136 | @pragma stage 4 137 | table modify_tail_table { 138 | actions { 139 | modify_tail_action; 140 | } 141 | default_action: modify_tail_action; 142 | } 143 | 144 | @pragma stage 5 145 | table forward_to_server_table { 146 | reads { 147 | nlk_hdr.lock: ternary; 148 | } 149 | actions { 150 | forward_to_server_action; 151 | } 152 | default_action: forward_to_server_action; 153 | } 154 | 155 | @pragma stage 6 156 | table update_tid_array_table { 157 | actions { 158 | update_tid_array_action; 159 | } 160 | default_action: update_tid_array_action; 161 | } 162 | 163 | @pragma stage 6 164 | table get_tid_table { 165 | actions { 166 | get_tid_action; 167 | } 168 | default_action: get_tid_action; 169 | } 170 | 171 | @pragma stage 5 172 | table update_mode_array_table { 173 | actions { 174 | update_mode_array_action; 175 | } 176 | default_action: update_mode_array_action; 177 | } 178 | 179 | @pragma stage 5 180 | table get_mode_table { 181 | actions { 182 | get_mode_action; 183 | } 184 | default_action: get_mode_action; 185 | } 186 | 187 | @pragma stage 5 188 | table update_ip_array_table { 189 | actions { 190 | update_ip_array_action; 191 | } 192 | default_action: update_ip_array_action; 193 | } 194 | 195 | @pragma stage 5 196 | table get_ip_table { 197 | actions { 198 | get_ip_action; 199 | } 200 | default_action: get_ip_action; 201 | } 202 | 203 | @pragma stage 3 204 | table acquire_lock_table { 205 | reads { 206 | nlk_hdr.mode: exact; 207 | } 208 | actions { 209 | acquire_shared_lock_action; 210 | acquire_exclusive_lock_action; 211 | } 212 | } 213 | 214 | @pragma stage 3 215 | table update_lock_table { 216 | actions { 217 | update_lock_action; 218 | } 219 | default_action: update_lock_action; 220 | } 221 | 222 | @pragma stage 8 223 | table notify_tail_client_table { 224 | actions { 225 | notify_tail_client_action; 226 | } 227 | default_action: notify_tail_client_action; 228 | } 229 | 230 | /* 231 | @pragma stage 7 232 | table notify_tail_client_1_table { 233 | actions { 234 | notify_tail_client_1_action; 235 | } 236 | default_action: notify_tail_client_1_action; 237 | } 238 | 239 | @pragma stage 8 240 | table notify_tail_client_2_table { 241 | actions { 242 | notify_tail_client_2_action; 243 | } 244 | default_action: notify_tail_client_2_action; 245 | } 246 | */ 247 | 248 | @pragma stage 8 249 | table i2e_mirror_table { 250 | reads { 251 | ipv4.dstAddr: exact; 252 | } 253 | actions { 254 | i2e_mirror_action; 255 | } 256 | } 257 | 258 | 259 | 260 | // ## 261 | 262 | @pragma stage 8 263 | table metahead_plus_1_table { 264 | actions { 265 | metahead_plus_1_action; 266 | } 267 | default_action: metahead_plus_1_action; 268 | } 269 | @pragma stage 8 270 | table metahead_plus_2_table { 271 | actions { 272 | metahead_plus_2_action; 273 | } 274 | default_action: metahead_plus_2_action; 275 | } 276 | 277 | // ## 278 | 279 | // ## resubmit 280 | @pragma stage 9 281 | table mark_to_resubmit_table { 282 | actions { 283 | mark_to_resubmit_action; 284 | } 285 | default_action: mark_to_resubmit_action; 286 | } 287 | 288 | 289 | @pragma stage 9 290 | table mark_to_resubmit_2_table { 291 | actions { 292 | mark_to_resubmit_2_action; 293 | } 294 | default_action: mark_to_resubmit_2_action; 295 | } 296 | 297 | table resubmit_table { 298 | actions { 299 | resubmit_action; 300 | } 301 | default_action: resubmit_action; 302 | } 303 | 304 | @pragma stage 9 305 | table notify_controller_table { 306 | actions { 307 | notify_controller_action; 308 | } 309 | default_action: notify_controller_action; 310 | } 311 | 312 | @pragma stage 6 313 | table notify_head_client_table { 314 | actions { 315 | notify_head_client_action; 316 | } 317 | default_action: notify_head_client_action; 318 | } 319 | 320 | @pragma stage 10 321 | table drop_packet_table { 322 | actions { 323 | _drop; 324 | } 325 | default_action: _drop; 326 | } 327 | 328 | 329 | 330 | @pragma stage 2 331 | table get_size_of_queue_table { 332 | actions { 333 | get_size_of_queue_action; 334 | } 335 | default_action: get_size_of_queue_action; 336 | } 337 | 338 | @pragma stage 7 339 | table update_timestamp_hi_array_table { 340 | actions { 341 | update_timestamp_hi_array_action; 342 | } 343 | default_action: update_timestamp_hi_array_action; 344 | } 345 | 346 | @pragma stage 8 347 | table update_timestamp_lo_array_table { 348 | actions { 349 | update_timestamp_lo_array_action; 350 | } 351 | default_action: update_timestamp_lo_array_action; 352 | } 353 | 354 | @pragma stage 7 355 | table get_timestamp_hi_table { 356 | actions { 357 | get_timestamp_hi_action; 358 | } 359 | default_action: get_timestamp_hi_action; 360 | } 361 | 362 | @pragma stage 8 363 | table get_timestamp_lo_table { 364 | actions { 365 | get_timestamp_lo_action; 366 | } 367 | default_action: get_timestamp_lo_action; 368 | } 369 | 370 | @pragma stage 6 371 | table update_client_id_array_table { 372 | actions { 373 | update_client_id_array_action; 374 | } 375 | default_action: update_client_id_array_action; 376 | } 377 | 378 | @pragma stage 6 379 | table get_client_id_table { 380 | actions { 381 | get_client_id_action; 382 | } 383 | default_action: get_client_id_action; 384 | } 385 | 386 | // table set_as_secondary_table { 387 | // actions { 388 | // set_as_secondary_action; 389 | // } 390 | // default_action: set_as_secondary_action; 391 | // } 392 | 393 | // table set_as_primary_table { 394 | // actions { 395 | // set_as_primary_action; 396 | // } 397 | // default_action: set_as_primary_action; 398 | // } 399 | table set_tag_table { 400 | reads { 401 | meta.failure_status: exact; 402 | meta.lock_exist: exact; 403 | } 404 | actions { 405 | set_as_primary_action; 406 | set_as_secondary_action; 407 | set_as_failure_notification_action; 408 | } 409 | } 410 | 411 | @pragma stage 0 412 | table check_lock_exist_table { 413 | reads { 414 | nlk_hdr.lock: exact; 415 | } 416 | actions { 417 | check_lock_exist_action; 418 | } 419 | size: NUM_LOCKS; 420 | } 421 | 422 | table change_mode_table { 423 | reads { 424 | current_node_meta.tid: ternary; 425 | } 426 | actions { 427 | change_mode_act; 428 | } 429 | default_action: change_mode_act; 430 | } 431 | 432 | table fix_src_port_table { 433 | reads { 434 | nlk_hdr.lock: ternary; 435 | } 436 | actions { 437 | fix_src_port_action; 438 | } 439 | //default_action: fix_src_port_action; 440 | } 441 | 442 | @pragma stage 0 443 | table check_failure_status_table { 444 | actions { 445 | check_failure_status_action; 446 | } 447 | default_action: check_failure_status_action; 448 | } 449 | 450 | @pragma stage 0 451 | table check_failure_status_2_table { 452 | actions { 453 | check_failure_status_action; 454 | } 455 | default_action: check_failure_status_action; 456 | } 457 | 458 | table set_failure_status_table { 459 | actions { 460 | set_failure_status_action; 461 | } 462 | default_action: set_failure_status_action; 463 | } 464 | -------------------------------------------------------------------------------- /switch_code/netlock/p4src/blackboxs.p4: -------------------------------------------------------------------------------- 1 | blackbox stateful_alu get_left_bound_alu { 2 | reg: left_bound_register; 3 | 4 | output_value: register_lo; 5 | output_dst : meta.left; 6 | } 7 | 8 | blackbox stateful_alu get_right_bound_alu { 9 | reg: right_bound_register; 10 | 11 | output_value: register_lo; 12 | output_dst : meta.right; 13 | } 14 | 15 | blackbox stateful_alu get_tail_alu { 16 | reg: tail_register; 17 | 18 | output_value: register_lo; 19 | output_dst : meta.tail; 20 | } 21 | 22 | blackbox stateful_alu get_head_alu { 23 | reg: head_register; 24 | 25 | output_value: register_lo; 26 | output_dst : meta.head; 27 | } 28 | 29 | blackbox stateful_alu get_tid_alu { 30 | reg: tid_array_register; 31 | 32 | output_value: register_lo; 33 | output_dst : current_node_meta.tid; 34 | // output_dst : nlk_hdr.tid; 35 | } 36 | 37 | blackbox stateful_alu get_mode_alu { 38 | reg: mode_array_register; 39 | 40 | output_value: register_lo; 41 | output_dst : current_node_meta.mode; 42 | // output_dst : nlk_hdr.mode; 43 | } 44 | 45 | blackbox stateful_alu get_ip_alu { 46 | reg: ip_array_register; 47 | 48 | output_value: register_lo; 49 | output_dst : current_node_meta.ip_address; 50 | } 51 | 52 | blackbox stateful_alu get_client_id_alu { 53 | reg: client_id_array_register; 54 | 55 | output_value: register_lo; 56 | output_dst : current_node_meta.client_id; 57 | } 58 | 59 | blackbox stateful_alu get_timestamp_hi_alu { 60 | reg: timestamp_hi_array_register; 61 | 62 | output_value: register_lo; 63 | output_dst : current_node_meta.timestamp_hi; 64 | } 65 | 66 | blackbox stateful_alu get_timestamp_lo_alu { 67 | reg: timestamp_lo_array_register; 68 | 69 | output_value: register_lo; 70 | output_dst : current_node_meta.timestamp_lo; 71 | } 72 | 73 | blackbox stateful_alu dec_empty_slots_alu { 74 | reg: slots_two_sides_register; 75 | 76 | condition_lo: register_lo > 0; 77 | //condition_hi: (register_hi > 0) or (meta.queue_size_op == SHRINK); 78 | // ** (register_hi > 0) or (meta.queue_size_op == SHRINK) 79 | condition_hi: register_hi + meta.queue_size_op > 0; 80 | 81 | update_lo_1_predicate: (condition_lo) and (not condition_hi); 82 | update_lo_1_value : register_lo - 1; 83 | update_lo_2_predicate: (not condition_lo) or (condition_hi); 84 | update_lo_2_value : register_lo; 85 | 86 | update_hi_1_predicate: (condition_lo) and (not condition_hi); 87 | update_hi_1_value : register_hi; 88 | update_hi_2_predicate: (not condition_lo) or (condition_hi); 89 | update_hi_2_value : register_hi + 1; 90 | 91 | output_value: alu_hi; 92 | output_dst : meta.length_in_server; 93 | } 94 | 95 | blackbox stateful_alu push_back_alu { 96 | reg: slots_two_sides_register; 97 | 98 | update_lo_1_value : register_lo - 1; 99 | update_hi_1_value : register_hi - 1; 100 | } 101 | 102 | blackbox stateful_alu inc_length_in_server_alu { 103 | reg: slots_two_sides_register; 104 | 105 | update_hi_1_value : register_hi + 1; 106 | 107 | output_value: alu_hi; 108 | output_dst : meta.length_in_server; 109 | } 110 | /* 111 | blackbox stateful_alu inc_empty_slots_alu { 112 | reg: empty_slots_register; 113 | 114 | update_lo_1_value: register_lo + 1; 115 | }*/ 116 | 117 | /* 118 | blackbox stateful_alu inc_empty_slots_alu { 119 | reg: slots_two_sides_register; 120 | 121 | // ** empty_slot < (right-left + 1) 122 | condition_lo: register_lo < meta.size_of_queue + 1; 123 | condition_hi: register_hi < 0; 124 | //condition_lo: register_lo < 1; 125 | 126 | update_lo_1_predicate: condition_lo; // ** queue not empty, switch pop 127 | update_lo_1_value : register_lo + 1; 128 | update_lo_2_predicate: not condition_lo; // ** queue empty, forward to server 129 | update_lo_2_value : register_lo; 130 | 131 | update_hi_1_predicate: condition_lo; // ** queue not empty, switch pop 132 | update_hi_1_value : register_hi; 133 | update_hi_2_predicate: not condition_lo; // ** queue empty, forward to server 134 | // ** temporally set to 0, then set by the packet from the server (will push more packets to the queue) 135 | update_hi_2_value : register_hi - 1; 136 | //update_hi_2_value : register_hi - 1; 137 | 138 | output_value: register_lo; 139 | output_dst : meta.queue_not_empty; 140 | } 141 | */ 142 | blackbox stateful_alu inc_empty_slots_alu { 143 | reg: slots_two_sides_register; 144 | 145 | condition_hi: register_hi > 0; 146 | // ** empty_slot 147 | update_lo_1_value : register_lo + 1; 148 | update_hi_1_value : register_hi; 149 | 150 | //output_value: register_lo; 151 | //output_dst : meta.empty_slots_before_pop; 152 | output_predicate: condition_hi; 153 | output_value: register_lo; 154 | output_dst : meta.empty_slots_before_pop; 155 | } 156 | 157 | blackbox stateful_alu modify_empty_slots_alu { 158 | reg: slots_two_sides_register; 159 | 160 | update_lo_1_value: meta.empty_slots + 1; 161 | update_hi_1_value: register_hi; 162 | } 163 | 164 | blackbox stateful_alu update_tail_alu { 165 | reg: tail_register; 166 | 167 | condition_lo: register_lo == meta.right; 168 | 169 | update_lo_1_predicate: condition_lo; 170 | update_lo_1_value : meta.left; 171 | update_lo_2_predicate: not condition_lo; 172 | update_lo_2_value : register_lo + 1; 173 | 174 | output_value: register_lo; 175 | output_dst : meta.tail; 176 | } 177 | 178 | blackbox stateful_alu update_head_alu { 179 | reg: head_register; 180 | 181 | condition_lo: register_lo == meta.right; 182 | 183 | update_lo_1_predicate: condition_lo; 184 | update_lo_1_value : meta.left; 185 | update_lo_2_predicate: not condition_lo; 186 | update_lo_2_value : register_lo + 1; 187 | 188 | output_value: register_lo; 189 | output_dst : meta.head; 190 | } 191 | 192 | blackbox stateful_alu update_mode_array_alu { 193 | reg: mode_array_register; 194 | 195 | update_lo_1_value: nlk_hdr.mode; 196 | } 197 | 198 | blackbox stateful_alu update_ip_array_alu { 199 | reg: ip_array_register; 200 | 201 | update_lo_1_value: ipv4.srcAddr; 202 | } 203 | 204 | blackbox stateful_alu update_client_id_array_alu { 205 | reg: client_id_array_register; 206 | 207 | update_lo_1_value: nlk_hdr.client_id; 208 | } 209 | 210 | blackbox stateful_alu update_tid_array_alu { 211 | reg: tid_array_register; 212 | 213 | update_lo_1_value: nlk_hdr.tid; 214 | } 215 | 216 | blackbox stateful_alu update_timestamp_hi_array_alu { 217 | reg: timestamp_hi_array_register; 218 | 219 | // update_lo_1_value: nlk_hdr.timestamp; 220 | update_lo_1_value: meta.ts_hi; 221 | } 222 | 223 | blackbox stateful_alu update_timestamp_lo_array_alu { 224 | reg: timestamp_lo_array_register; 225 | 226 | // update_lo_1_value: nlk_hdr.timestamp; 227 | update_lo_1_value: meta.ts_lo; 228 | } 229 | 230 | blackbox stateful_alu acquire_shared_lock_alu { 231 | reg: shared_and_exclusive_count_register; 232 | 233 | condition_lo: register_lo > 0; 234 | //condition_hi: 1 == 0; 235 | 236 | update_lo_1_value : register_lo; 237 | 238 | update_hi_1_predicate: condition_lo; 239 | update_hi_1_value : register_hi + 1; 240 | update_hi_2_predicate: not condition_lo; 241 | update_hi_2_value : register_hi + 1; 242 | 243 | // output_value: combined_predicate; 244 | // output_value: register_lo; 245 | output_predicate : condition_lo; 246 | output_value: alu_hi; 247 | output_dst : meta.locked; 248 | } 249 | 250 | blackbox stateful_alu acquire_exclusive_lock_alu { 251 | reg: shared_and_exclusive_count_register; 252 | 253 | condition_lo: register_lo > 0; 254 | condition_hi: register_hi > 0; 255 | 256 | update_lo_1_predicate: (not condition_lo) and (not condition_hi); 257 | update_lo_1_value : register_lo + 1; 258 | update_lo_2_predicate: condition_lo or condition_hi; 259 | update_lo_2_value : register_lo + 1; 260 | //update_lo_2_value : register_lo; 261 | 262 | update_hi_1_value : register_hi; 263 | 264 | 265 | // output_value: combined_predicate; 266 | // output_value: register_lo; 267 | output_predicate : condition_lo or condition_hi; 268 | output_value: alu_lo; 269 | output_dst : meta.locked; 270 | } 271 | 272 | blackbox stateful_alu update_lock_alu { 273 | reg: shared_and_exclusive_count_register; 274 | 275 | // condition_lo: current_node_meta.mode == EXCLUSIVE_LOCK; 276 | // condition_hi: current_node_meta.mode == SHARED_LOCK; 277 | condition_lo: nlk_hdr.mode == EXCLUSIVE_LOCK; 278 | condition_hi: nlk_hdr.mode == SHARED_LOCK; 279 | 280 | update_lo_1_predicate: condition_lo; 281 | update_lo_1_value : register_lo - 1; 282 | update_lo_2_predicate: not condition_lo; 283 | update_lo_2_value : register_lo; 284 | 285 | update_hi_1_predicate: condition_hi; 286 | update_hi_1_value : register_hi - 1; 287 | update_hi_2_predicate: not condition_hi; 288 | update_hi_2_value : register_hi; 289 | } 290 | 291 | blackbox stateful_alu modify_left_alu { 292 | reg: left_bound_register; 293 | 294 | update_lo_1_value: adm_hdr.new_left; 295 | 296 | output_value: alu_lo; 297 | output_dst: meta.left; 298 | } 299 | 300 | blackbox stateful_alu modify_right_alu { 301 | reg: right_bound_register; 302 | 303 | update_lo_1_value: adm_hdr.new_right; 304 | } 305 | 306 | blackbox stateful_alu modify_head_alu { 307 | reg: head_register; 308 | 309 | update_lo_1_value: meta.left; 310 | } 311 | 312 | blackbox stateful_alu modify_tail_alu { 313 | reg: tail_register; 314 | 315 | update_lo_1_value: meta.left; 316 | } 317 | 318 | blackbox stateful_alu get_queue_size_op_alu { 319 | reg: queue_size_op_register; 320 | 321 | output_value: register_lo; 322 | output_dst : meta.queue_size_op; 323 | } 324 | 325 | blackbox stateful_alu set_queue_size_op_alu { 326 | reg: queue_size_op_register; 327 | 328 | update_lo_1_value : set_bit; 329 | } 330 | 331 | blackbox stateful_alu clr_queue_size_op_alu { 332 | reg: queue_size_op_register; 333 | 334 | update_lo_1_value : clr_bit; 335 | } 336 | 337 | blackbox stateful_alu tenant_count_alu { 338 | reg: tenant_acq_counter_register; 339 | 340 | condition_lo: register_lo < meta.tenant_threshold; 341 | 342 | update_lo_1_predicate: condition_lo; 343 | update_lo_1_value : register_lo + 1; 344 | update_lo_2_predicate: not condition_lo; 345 | update_lo_2_value : register_lo; 346 | 347 | update_hi_1_predicate: condition_lo; 348 | update_hi_1_value : 1; 349 | update_hi_2_predicate: not condition_hi; 350 | update_hi_2_value : 0; 351 | 352 | output_value: alu_hi; 353 | output_dst : meta.under_threshold; 354 | } 355 | 356 | blackbox stateful_alu check_failure_status_alu { 357 | reg: failure_status_register; 358 | 359 | output_value: register_lo; 360 | output_dst : meta.failure_status; 361 | } -------------------------------------------------------------------------------- /dpdk_code/client_code/build/.simple_socket.o.d: -------------------------------------------------------------------------------- 1 | dep_simple_socket.o = /home/user/hz/NetPB/client_dpdk/simple_socket.c \ 2 | /usr/include/stdc-predef.h \ 3 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_config.h \ 4 | /usr/include/stdio.h /usr/include/features.h \ 5 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ 7 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ 8 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ 9 | /usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h \ 10 | /usr/include/x86_64-linux-gnu/bits/types.h \ 11 | /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ 12 | /usr/include/_G_config.h /usr/include/wchar.h \ 13 | /usr/lib/gcc/x86_64-linux-gnu/5/include/stdarg.h \ 14 | /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ 15 | /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ 16 | /usr/include/x86_64-linux-gnu/bits/stdio.h \ 17 | /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/string.h \ 18 | /usr/include/xlocale.h /usr/include/x86_64-linux-gnu/bits/string.h \ 19 | /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/endian.h \ 20 | /usr/include/x86_64-linux-gnu/bits/endian.h \ 21 | /usr/include/x86_64-linux-gnu/bits/byteswap.h \ 22 | /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/stdlib.h \ 23 | /usr/include/x86_64-linux-gnu/bits/string3.h \ 24 | /usr/lib/gcc/x86_64-linux-gnu/5/include/stdint.h /usr/include/stdint.h \ 25 | /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/inttypes.h \ 26 | /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ 27 | /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ 28 | /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ 29 | /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/time.h \ 30 | /usr/include/x86_64-linux-gnu/bits/time.h /usr/include/assert.h \ 31 | /usr/include/arpa/inet.h /usr/include/netinet/in.h \ 32 | /usr/include/x86_64-linux-gnu/sys/socket.h \ 33 | /usr/include/x86_64-linux-gnu/sys/uio.h \ 34 | /usr/include/x86_64-linux-gnu/sys/types.h \ 35 | /usr/include/x86_64-linux-gnu/sys/select.h \ 36 | /usr/include/x86_64-linux-gnu/bits/select.h \ 37 | /usr/include/x86_64-linux-gnu/bits/sigset.h \ 38 | /usr/include/x86_64-linux-gnu/bits/select2.h \ 39 | /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ 40 | /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ 41 | /usr/include/x86_64-linux-gnu/bits/uio.h \ 42 | /usr/include/x86_64-linux-gnu/bits/socket.h \ 43 | /usr/include/x86_64-linux-gnu/bits/socket_type.h \ 44 | /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ 45 | /usr/include/x86_64-linux-gnu/asm/socket.h \ 46 | /usr/include/asm-generic/socket.h \ 47 | /usr/include/x86_64-linux-gnu/asm/sockios.h \ 48 | /usr/include/asm-generic/sockios.h \ 49 | /usr/include/x86_64-linux-gnu/bits/socket2.h \ 50 | /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/getopt.h \ 51 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_memory.h \ 52 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_config.h \ 53 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/exec-env/rte_dom0_common.h \ 54 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_common.h \ 55 | /usr/include/x86_64-linux-gnu/bits/waitflags.h \ 56 | /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/alloca.h \ 57 | /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ 58 | /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ 59 | /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/ctype.h \ 60 | /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h \ 61 | /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/syslimits.h \ 62 | /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ 63 | /usr/include/x86_64-linux-gnu/bits/local_lim.h \ 64 | /usr/include/linux/limits.h \ 65 | /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ 66 | /usr/lib/gcc/x86_64-linux-gnu/5/include/emmintrin.h \ 67 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xmmintrin.h \ 68 | /usr/lib/gcc/x86_64-linux-gnu/5/include/mmintrin.h \ 69 | /usr/lib/gcc/x86_64-linux-gnu/5/include/mm_malloc.h \ 70 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_memzone.h \ 71 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_launch.h \ 72 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_eal.h \ 73 | /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/sched.h \ 74 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_per_lcore.h \ 75 | /usr/include/pthread.h /usr/include/x86_64-linux-gnu/bits/setjmp.h \ 76 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_lcore.h \ 77 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_debug.h \ 78 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_log.h \ 79 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_branch_prediction.h \ 80 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_cycles.h \ 81 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_cycles.h \ 82 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_atomic.h \ 83 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_atomic.h \ 84 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_atomic_64.h \ 85 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_branch_prediction.h \ 86 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_mbuf.h \ 87 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_mempool.h \ 88 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_spinlock.h \ 89 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_spinlock.h \ 90 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_rtm.h \ 91 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_cpuflags.h \ 92 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_cpuflags.h \ 93 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_common.h \ 94 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_log.h \ 95 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ring.h \ 96 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_memcpy.h \ 97 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_vect.h \ 98 | /usr/lib/gcc/x86_64-linux-gnu/5/include/x86intrin.h \ 99 | /usr/lib/gcc/x86_64-linux-gnu/5/include/ia32intrin.h \ 100 | /usr/lib/gcc/x86_64-linux-gnu/5/include/pmmintrin.h \ 101 | /usr/lib/gcc/x86_64-linux-gnu/5/include/tmmintrin.h \ 102 | /usr/lib/gcc/x86_64-linux-gnu/5/include/ammintrin.h \ 103 | /usr/lib/gcc/x86_64-linux-gnu/5/include/smmintrin.h \ 104 | /usr/lib/gcc/x86_64-linux-gnu/5/include/popcntintrin.h \ 105 | /usr/lib/gcc/x86_64-linux-gnu/5/include/wmmintrin.h \ 106 | /usr/lib/gcc/x86_64-linux-gnu/5/include/immintrin.h \ 107 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avxintrin.h \ 108 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx2intrin.h \ 109 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512fintrin.h \ 110 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512erintrin.h \ 111 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512pfintrin.h \ 112 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512cdintrin.h \ 113 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vlintrin.h \ 114 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512bwintrin.h \ 115 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512dqintrin.h \ 116 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vlbwintrin.h \ 117 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vldqintrin.h \ 118 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512ifmaintrin.h \ 119 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512ifmavlintrin.h \ 120 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vbmiintrin.h \ 121 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vbmivlintrin.h \ 122 | /usr/lib/gcc/x86_64-linux-gnu/5/include/shaintrin.h \ 123 | /usr/lib/gcc/x86_64-linux-gnu/5/include/lzcntintrin.h \ 124 | /usr/lib/gcc/x86_64-linux-gnu/5/include/bmiintrin.h \ 125 | /usr/lib/gcc/x86_64-linux-gnu/5/include/bmi2intrin.h \ 126 | /usr/lib/gcc/x86_64-linux-gnu/5/include/fmaintrin.h \ 127 | /usr/lib/gcc/x86_64-linux-gnu/5/include/f16cintrin.h \ 128 | /usr/lib/gcc/x86_64-linux-gnu/5/include/rtmintrin.h \ 129 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xtestintrin.h \ 130 | /usr/lib/gcc/x86_64-linux-gnu/5/include/mm3dnow.h \ 131 | /usr/lib/gcc/x86_64-linux-gnu/5/include/prfchwintrin.h \ 132 | /usr/lib/gcc/x86_64-linux-gnu/5/include/fma4intrin.h \ 133 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xopintrin.h \ 134 | /usr/lib/gcc/x86_64-linux-gnu/5/include/lwpintrin.h \ 135 | /usr/lib/gcc/x86_64-linux-gnu/5/include/tbmintrin.h \ 136 | /usr/lib/gcc/x86_64-linux-gnu/5/include/rdseedintrin.h \ 137 | /usr/lib/gcc/x86_64-linux-gnu/5/include/fxsrintrin.h \ 138 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xsaveintrin.h \ 139 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xsaveoptintrin.h \ 140 | /usr/lib/gcc/x86_64-linux-gnu/5/include/adxintrin.h \ 141 | /usr/lib/gcc/x86_64-linux-gnu/5/include/clwbintrin.h \ 142 | /usr/lib/gcc/x86_64-linux-gnu/5/include/pcommitintrin.h \ 143 | /usr/lib/gcc/x86_64-linux-gnu/5/include/clflushoptintrin.h \ 144 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xsavesintrin.h \ 145 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xsavecintrin.h \ 146 | /usr/lib/gcc/x86_64-linux-gnu/5/include/mwaitxintrin.h \ 147 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_prefetch.h \ 148 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_prefetch.h \ 149 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_mbuf_ptype.h \ 150 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ether.h \ 151 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_random.h \ 152 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_byteorder.h \ 153 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_byteorder.h \ 154 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_byteorder_64.h \ 155 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ip.h \ 156 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_udp.h \ 157 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ethdev.h \ 158 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_dev.h \ 159 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_interrupts.h \ 160 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/exec-env/rte_interrupts.h \ 161 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_pci.h \ 162 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_devargs.h \ 163 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ether.h \ 164 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_eth_ctrl.h \ 165 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_dev_info.h \ 166 | /home/user/hz/NetPB/client_dpdk/util.h \ 167 | /home/user/hz/NetPB/client_dpdk/zipf.h 168 | -------------------------------------------------------------------------------- /dpdk_code/lock_server_code/build/.simple_socket.o.d: -------------------------------------------------------------------------------- 1 | dep_simple_socket.o = /home/user/hz/NetPB/client_dpdk/simple_socket.c \ 2 | /usr/include/stdc-predef.h \ 3 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_config.h \ 4 | /usr/include/stdio.h /usr/include/features.h \ 5 | /usr/include/x86_64-linux-gnu/sys/cdefs.h \ 6 | /usr/include/x86_64-linux-gnu/bits/wordsize.h \ 7 | /usr/include/x86_64-linux-gnu/gnu/stubs.h \ 8 | /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ 9 | /usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h \ 10 | /usr/include/x86_64-linux-gnu/bits/types.h \ 11 | /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \ 12 | /usr/include/_G_config.h /usr/include/wchar.h \ 13 | /usr/lib/gcc/x86_64-linux-gnu/5/include/stdarg.h \ 14 | /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ 15 | /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ 16 | /usr/include/x86_64-linux-gnu/bits/stdio.h \ 17 | /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/string.h \ 18 | /usr/include/xlocale.h /usr/include/x86_64-linux-gnu/bits/string.h \ 19 | /usr/include/x86_64-linux-gnu/bits/string2.h /usr/include/endian.h \ 20 | /usr/include/x86_64-linux-gnu/bits/endian.h \ 21 | /usr/include/x86_64-linux-gnu/bits/byteswap.h \ 22 | /usr/include/x86_64-linux-gnu/bits/byteswap-16.h /usr/include/stdlib.h \ 23 | /usr/include/x86_64-linux-gnu/bits/string3.h \ 24 | /usr/lib/gcc/x86_64-linux-gnu/5/include/stdint.h /usr/include/stdint.h \ 25 | /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/inttypes.h \ 26 | /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ 27 | /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ 28 | /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ 29 | /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/time.h \ 30 | /usr/include/x86_64-linux-gnu/bits/time.h /usr/include/assert.h \ 31 | /usr/include/arpa/inet.h /usr/include/netinet/in.h \ 32 | /usr/include/x86_64-linux-gnu/sys/socket.h \ 33 | /usr/include/x86_64-linux-gnu/sys/uio.h \ 34 | /usr/include/x86_64-linux-gnu/sys/types.h \ 35 | /usr/include/x86_64-linux-gnu/sys/select.h \ 36 | /usr/include/x86_64-linux-gnu/bits/select.h \ 37 | /usr/include/x86_64-linux-gnu/bits/sigset.h \ 38 | /usr/include/x86_64-linux-gnu/bits/select2.h \ 39 | /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ 40 | /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ 41 | /usr/include/x86_64-linux-gnu/bits/uio.h \ 42 | /usr/include/x86_64-linux-gnu/bits/socket.h \ 43 | /usr/include/x86_64-linux-gnu/bits/socket_type.h \ 44 | /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ 45 | /usr/include/x86_64-linux-gnu/asm/socket.h \ 46 | /usr/include/asm-generic/socket.h \ 47 | /usr/include/x86_64-linux-gnu/asm/sockios.h \ 48 | /usr/include/asm-generic/sockios.h \ 49 | /usr/include/x86_64-linux-gnu/bits/socket2.h \ 50 | /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/getopt.h \ 51 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_memory.h \ 52 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_config.h \ 53 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/exec-env/rte_dom0_common.h \ 54 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_common.h \ 55 | /usr/include/x86_64-linux-gnu/bits/waitflags.h \ 56 | /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/alloca.h \ 57 | /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ 58 | /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ 59 | /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/ctype.h \ 60 | /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h \ 61 | /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/syslimits.h \ 62 | /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ 63 | /usr/include/x86_64-linux-gnu/bits/local_lim.h \ 64 | /usr/include/linux/limits.h \ 65 | /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ 66 | /usr/lib/gcc/x86_64-linux-gnu/5/include/emmintrin.h \ 67 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xmmintrin.h \ 68 | /usr/lib/gcc/x86_64-linux-gnu/5/include/mmintrin.h \ 69 | /usr/lib/gcc/x86_64-linux-gnu/5/include/mm_malloc.h \ 70 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_memzone.h \ 71 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_launch.h \ 72 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_eal.h \ 73 | /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/sched.h \ 74 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_per_lcore.h \ 75 | /usr/include/pthread.h /usr/include/x86_64-linux-gnu/bits/setjmp.h \ 76 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_lcore.h \ 77 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_debug.h \ 78 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_log.h \ 79 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_branch_prediction.h \ 80 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_cycles.h \ 81 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_cycles.h \ 82 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_atomic.h \ 83 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_atomic.h \ 84 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_atomic_64.h \ 85 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_branch_prediction.h \ 86 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_mbuf.h \ 87 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_mempool.h \ 88 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_spinlock.h \ 89 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_spinlock.h \ 90 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_rtm.h \ 91 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_cpuflags.h \ 92 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_cpuflags.h \ 93 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_common.h \ 94 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_log.h \ 95 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ring.h \ 96 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_memcpy.h \ 97 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_vect.h \ 98 | /usr/lib/gcc/x86_64-linux-gnu/5/include/x86intrin.h \ 99 | /usr/lib/gcc/x86_64-linux-gnu/5/include/ia32intrin.h \ 100 | /usr/lib/gcc/x86_64-linux-gnu/5/include/pmmintrin.h \ 101 | /usr/lib/gcc/x86_64-linux-gnu/5/include/tmmintrin.h \ 102 | /usr/lib/gcc/x86_64-linux-gnu/5/include/ammintrin.h \ 103 | /usr/lib/gcc/x86_64-linux-gnu/5/include/smmintrin.h \ 104 | /usr/lib/gcc/x86_64-linux-gnu/5/include/popcntintrin.h \ 105 | /usr/lib/gcc/x86_64-linux-gnu/5/include/wmmintrin.h \ 106 | /usr/lib/gcc/x86_64-linux-gnu/5/include/immintrin.h \ 107 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avxintrin.h \ 108 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx2intrin.h \ 109 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512fintrin.h \ 110 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512erintrin.h \ 111 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512pfintrin.h \ 112 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512cdintrin.h \ 113 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vlintrin.h \ 114 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512bwintrin.h \ 115 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512dqintrin.h \ 116 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vlbwintrin.h \ 117 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vldqintrin.h \ 118 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512ifmaintrin.h \ 119 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512ifmavlintrin.h \ 120 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vbmiintrin.h \ 121 | /usr/lib/gcc/x86_64-linux-gnu/5/include/avx512vbmivlintrin.h \ 122 | /usr/lib/gcc/x86_64-linux-gnu/5/include/shaintrin.h \ 123 | /usr/lib/gcc/x86_64-linux-gnu/5/include/lzcntintrin.h \ 124 | /usr/lib/gcc/x86_64-linux-gnu/5/include/bmiintrin.h \ 125 | /usr/lib/gcc/x86_64-linux-gnu/5/include/bmi2intrin.h \ 126 | /usr/lib/gcc/x86_64-linux-gnu/5/include/fmaintrin.h \ 127 | /usr/lib/gcc/x86_64-linux-gnu/5/include/f16cintrin.h \ 128 | /usr/lib/gcc/x86_64-linux-gnu/5/include/rtmintrin.h \ 129 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xtestintrin.h \ 130 | /usr/lib/gcc/x86_64-linux-gnu/5/include/mm3dnow.h \ 131 | /usr/lib/gcc/x86_64-linux-gnu/5/include/prfchwintrin.h \ 132 | /usr/lib/gcc/x86_64-linux-gnu/5/include/fma4intrin.h \ 133 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xopintrin.h \ 134 | /usr/lib/gcc/x86_64-linux-gnu/5/include/lwpintrin.h \ 135 | /usr/lib/gcc/x86_64-linux-gnu/5/include/tbmintrin.h \ 136 | /usr/lib/gcc/x86_64-linux-gnu/5/include/rdseedintrin.h \ 137 | /usr/lib/gcc/x86_64-linux-gnu/5/include/fxsrintrin.h \ 138 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xsaveintrin.h \ 139 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xsaveoptintrin.h \ 140 | /usr/lib/gcc/x86_64-linux-gnu/5/include/adxintrin.h \ 141 | /usr/lib/gcc/x86_64-linux-gnu/5/include/clwbintrin.h \ 142 | /usr/lib/gcc/x86_64-linux-gnu/5/include/pcommitintrin.h \ 143 | /usr/lib/gcc/x86_64-linux-gnu/5/include/clflushoptintrin.h \ 144 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xsavesintrin.h \ 145 | /usr/lib/gcc/x86_64-linux-gnu/5/include/xsavecintrin.h \ 146 | /usr/lib/gcc/x86_64-linux-gnu/5/include/mwaitxintrin.h \ 147 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_prefetch.h \ 148 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_prefetch.h \ 149 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_mbuf_ptype.h \ 150 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ether.h \ 151 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_random.h \ 152 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_byteorder.h \ 153 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/generic/rte_byteorder.h \ 154 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_byteorder_64.h \ 155 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ip.h \ 156 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_udp.h \ 157 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ethdev.h \ 158 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_dev.h \ 159 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_interrupts.h \ 160 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/exec-env/rte_interrupts.h \ 161 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_pci.h \ 162 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_devargs.h \ 163 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_ether.h \ 164 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_eth_ctrl.h \ 165 | /home/user/dpdk/dpdk-stable-16.11.1/x86_64-native-linuxapp-gcc/include/rte_dev_info.h \ 166 | /home/user/hz/NetPB/client_dpdk/util.h \ 167 | /home/user/hz/NetPB/client_dpdk/zipf.h 168 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- 204 | 205 | Code in python/ray/rllib/{evolution_strategies, dqn} adapted from 206 | https://github.com/openai (MIT License) 207 | 208 | Copyright (c) 2016 OpenAI (http://openai.com) 209 | 210 | Permission is hereby granted, free of charge, to any person obtaining a copy 211 | of this software and associated documentation files (the "Software"), to deal 212 | in the Software without restriction, including without limitation the rights 213 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 214 | copies of the Software, and to permit persons to whom the Software is 215 | furnished to do so, subject to the following conditions: 216 | 217 | The above copyright notice and this permission notice shall be included in 218 | all copies or substantial portions of the Software. 219 | 220 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 221 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 222 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 223 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 224 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 225 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 226 | THE SOFTWARE. 227 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetLock: Fast, Centralized Lock Management Using Programmable Switches 2 | ## 0. Introduction
3 | NetLock is a new centralized lock manager that co-designs servers and network switches to achieve high performance without sacrificing flexibility in policy support. NetLock exploits the capability of emerging programmable switches to directly process lock requests in the switch data plane. 4 | 5 | ![10b](figures/architecture.jpg) 6 | 7 | Here we show some major building blocks of NetLock and how they are the implemented at a high level. 8 | - **Lock Request Handling**
9 | Due to the limitation of switch memory, NetLock only processes requests on popular locks in the switch, while the lock servers will help with the rest of the locks. We use `check_lock_exist_table` in `netlock.p4` to check whether the switch is responsible for the coming packet (request). 10 | ```p4 11 | table check_lock_exist_table { 12 | reads { 13 | nlk_hdr.lock: exact; 14 | } 15 | actions { 16 | check_lock_exist_action; 17 | } 18 | size: NUM_LOCKS; 19 | } 20 | 21 | action check_lock_exist_action(index) { 22 | modify_field(meta.lock_exist, 1); 23 | modify_field(meta.lock_id, index); 24 | } 25 | ``` 26 | - **Switch Memory Layout**
27 | We store the requests in a large circular queue and keep extra registers for the heads/tails/boundaries, so that each queue can have a flexible length and the switch memory can be efficiently utilized: 28 | - `head_register`: stores the head pointers.
29 | - `tail_register`: stores the tail pointers.
30 | - `left_bound_register`: stores the left boundaries.
31 | - `right_bound_register`: stores the right boundaries.
32 | - **Resubmission**
33 | After a lock is released, the packet will be resubmitted to check on the requests waiting in the queue. 34 | We store the information of dequeued request into the packet header. 35 | ```p4 36 | action mark_to_resubmit_action() { 37 | modify_field(nlk_hdr.recirc_flag, 1); 38 | add_header(recirculate_hdr); 39 | modify_field(recirculate_hdr.cur_tail, meta.tail); 40 | modify_field(recirculate_hdr.cur_head, meta.head); 41 | modify_field(recirculate_hdr.dequeued_mode, current_node_meta.mode); 42 | modify_field(meta.do_resubmit, 1); 43 | } 44 | ``` 45 | For each packet, we check `nlk_hdr.recirc_flag`, `recirculate_hdr.dequeued_mode`, and `current_node_meta.mode` to decide whether we need to notify the clients and whether we need to resubmit this packet in the `release_lock` control block of `netlock.p4`. 46 | 47 | 48 | More details of the design are available in our SIGCOMM'20 paper "NetLock: Fast, Centralized Lock Management Using Programmable Switches". [[Paper]](http://cs.jhu.edu/~zhuolong/papers/sigcomm20netlock.pdf) 49 | 50 | Below we show how to configure the environment, how to run the system, and how to reproduce the results. 51 | 52 | ## 1. Content
53 | - dpdk_code/
54 | - client_code/: C code to run on clients.
55 | - lock_server_code/: C code to run on lock servers.
56 | - switch_code/
57 | - netlock/ 58 | - p4src/: data-plane module (p4 code) for NetLock.
59 | - controller_init/: control-plane module for NetLock.
60 | - netchain/: netchain for comparison
61 | - results/: We collect results from all the servers and store them here.
62 | - logs/: We collect logs from all the servers and store them here.
63 | - traces/: Some traces we use for the experiments.
64 | - TPCC trace link: [Click to download!](http://cs.jhu.edu/~zhuolong/resource/tpcc_traces.zip)
65 | - Microbenchmark trace link: [Click to download!](http://cs.jhu.edu/~zhuolong/resource/microbenchmark.zip)
66 | - Move the zip to the corresponding folder and unzip.
67 | - console.py: A script to help run different set of evaluations.
68 | - config.py: Some parameters to configure.
69 | - parser.py: A script to parse the raw results.
70 | - README.md: This file.
71 | 72 | ## 2. Environment requirement
73 | - Hardware 74 | - A Barefoot Tofino switch.
75 | - Servers with a DPDK-compatible NIC (we used an Intel XL710 for 40GbE QSFP+) and multi-core CPU.
76 | - Software
77 | The current version of NetLock is tested on:
78 | - Tofino SDK (version after 8.2.2) on the switch.
79 | - DPDK (16.11.1) on the servers.
80 | You can either refer to the [official guige](https://doc.dpdk.org/guides/linux_gsg/quick_start.html) or use the tools.sh script in dpdk_code/. 81 | ```shell 82 | cd dpdk_code 83 | ./tools.sh install_dpdk 84 | ``` 85 | We provide easy-to-use scripts to run the experiments and to analyze the results. To use the scripts, you need: 86 | - Python2.7, Paramiko at your endhost.
87 | ```pip install paramiko``` 88 | 89 | ## 3. How to run
90 | First the traces should be downloaded to the traces/ directory. 91 | ```shell 92 | cd traces 93 | wget [The link is in the Content section] 94 | unzip tpcc_traces.zip -d tpcc_traces 95 | unzip microbenchmark.zip -d microbenchmark 96 | ``` 97 | Then you can either manually execute programs on the switch and the servers, or use the script we provided (Recommended). 98 | - To use scripts (Recommended)
99 | - Configure the parameters in the files based on your environment
100 | - `config.py`: provide the information of your servers (username, passwd, hostname, dir).
101 | - `switch_code/netlock/controller_init/ports.json`: use the information (actual enabled ports) on your switch. 102 | - Environment setup
103 | - Setup the switch
104 | - Setup the necessary environment variables to point to the appropriate locations.
105 | - Copy the files to the switch.
106 | - `python console.py init_sync_switch`
107 | - Compile the NetLock.
108 | - `python console.py compile_switch`
109 | This will take **a couple of minutes**. You can check `logs/p4_compile.log` in the switch to see if it's finished. 110 | - Setup the servers
111 | - Setup DPDK environment (install dpdk, and set correct environment variables).
112 | - Copy the files to the servers.
113 | - `python console.py init_sync_server`
114 | - Compile the clients and lock servers.
115 | - `python console.py compile_host`
116 | It will compile for both lock servers and clients.
117 | - Bind NIC to DPDK.
118 | - `python console.py setup_dpdk`
119 | It will bind NIC to DPDK for both lock servers and clients.
120 | - Run the programs
121 | - Run NetLock on the switch
122 | - `python console.py run_netlock`
123 | It will bring up both the data-plane module and the control-plane module. It may take **up to 150 seconds** (may vary between devices). You can check `logs/run_ptf_test.log` in the switch to see if it's finished (it will say `"INIT Finished"`). 124 | - Run lock servers
125 | - `python console.py run_server`
126 | It will run the lock servers with parameters defined in the script `console.py`. For the parameters, you can check this [readme](dpdk_code/lock_server_code/README.md). 127 | - Run clients
128 | - `python console.py run_client`
129 | It will run the clients with parameters defined in the script `console.py`. For the parameters, you can check this [readme](dpdk_code/client_code/README.md).
130 | - Get the results and logs
131 | The results are located at results/, and the log files are located at logs/
132 | - To easily analyze the results, you can grab results from all the clients/servers to the local machine where you are running all the commands. 133 | - `python console.py grab_result` 134 | - Kill the processes
135 | - Kill the switch process 136 | - `python console.py kill_switch` 137 | - Kill the lock server and client processes 138 | - `python console.py kill_host` 139 | - Kill all the processes (switch, lock servers, clients) 140 | - `python console.py kill_all` 141 | - Other commands
142 | There are also some other commands you can use: 143 | - `python console.py sync_switch`
144 | copy the local "switch code" to the switch 145 | - `python console.py sync_host`
146 | copy the local "client code" and "lock server code" to the servers 147 | - `python console.py sync_trace`
148 | copy the traces to the servers 149 | - `python console.py clean_result`
150 | clean up the results/ directory
151 | - To manually run (Not recommended)
152 | - Configure the ports information
153 | - `switch_code/netlock/controller_init/ports.json`: use the information (actual enabled ports) on your switch. 154 | - Environment setup
155 | - Setup the switch
156 | - Setup the necessary environment variables to point to the appropriate locations.
157 | - Copy the files to the switch.
158 | - Compile the NetLock.
159 | ```shell 160 | cd switch_code/netlock/p4src 161 | python tool.py compile netlock.p4 162 | ``` 163 | - Setup the servers
164 | - Setup DPDK environment (install dpdk, and set correct environment variables).
165 | - Copy the files to the servers.
166 | - Bind NIC to DPDK.
167 | ```shell 168 | cd dpdk_code 169 | ./tools.sh setup_dpdk 170 | ``` 171 | - Compile the clients.
172 | ```shell 173 | cd dpdk_code/client_code 174 | make 175 | ``` 176 | - Compile the lock servers.
177 | ```shell 178 | cd dpdk_code/lock_server_code 179 | make 180 | ``` 181 | - Run the programs
182 | - Run NetLock on the switch.
183 | ```shell 184 | cd switch_code/netlock/p4src 185 | python tool.py start_switch netlock 186 | python tool.py ptf_test ../controller_init netlock (Execute in another window) 187 | ``` 188 | - Run lock servers
189 | - See [here](dpdk_code/client_code/README.md).
190 | - Run clients
191 | - See [here](dpdk_code/lock_server_code/README.md).
192 | - Results and logs 193 | The results are located at results/, and the log files are located at logs/
194 | ## 4. How to reproduce the results
195 | - Copy the traces.
196 | ```shell 197 | cd traces 198 | wget [The link is in the Content section] 199 | unzip tpcc_traces.zip -d tpcc_traces 200 | unzip microbenchmark.zip -d microbenchmark 201 | ``` 202 | - Configure the parameters in the files based on your environment 203 | - `config.py`: provide the information of your servers (username, passwd, hostname, dir).
204 | - `switch_code/netlock/controller_init/ports.json`: use the information (actual enabled ports) on your switch.
205 | - Setup the switch 206 | - Setup the necessary environment variables to point to the appropriate locations.
207 | - Copy the files to the switch: `python console.py init_sync_switch`
208 | - Compile the netlock: `python console.py compile_switch`
209 | Again it will take **a couple of minutes**. You can check `logs/p4_compile.log` in the switch to see if it's finished. 210 | - Setup the servers 211 | - Setup dpdk environment
212 | - Copy the files to the server: `python console.py init_sync_server`
213 | - Bind NIC to DPDK: `python console.py setup_dpdk`
214 | - Compile the clients and lock servers: `python console.py compile_host`
215 | - After both the switch and the servers are correctly configured, you can replay the results by running console.py. The following command will execute the switch program, lock server programs, and client programs automatically and grab the results to your endhost.
216 | - Figure 8(a): `python console.py micro_bm_s`
217 | - Figure 8(b): `python console.py micro_bm_x`
218 | - Figure 8(c)(d): `python console.py micro_bm_cont`
219 | - Figure 9: `python console.py micro_bm_only_server`
220 | - Figure 10: `python console.py run_tpcc`
221 | - Figure 11: `python console.py run_tpcc_ms`
222 | - Figure 13: `python console.py mem_man`
223 | - Figure 14: `python console.py mem_size`
224 | - Interprete the results.
225 | - `console.py` will collect raw results from the servers and store them at `results/`. 226 | - `parser.py` can parse the results (tput, avg. latency, etc.) 227 | - `parser.py` can help process the result files to get the throughput/latency. 228 | - It can process different metrics by running `python parser.py [metric] [task_name]`: 229 | - metric: 230 | - `tput`: lock throughput. 231 | - `txn_tput`: transaction throughput. 232 | - `avg_latency/99_latency/99.9_latency`: the average/99%/99.9% latency for locks. 233 | - `txn_avg_latency/txn_99_latency/txn_99.9_latency`: the average/99%/99.9% latency for transactions. 234 | - task_name: 235 | - `micro_bm_s`: microbenchmark - shared locks. 236 | - `micro_bm_x`: microbenchmark - exclusive locks w/o contention. 237 | - `micro_bm_cont`: microbenchmark - exclusive locks w/ contention. 238 | - `tpcc`: TPC-C workload with 10v2 setting. 239 | - `tpcc_ms`: TPC-C workload with 6v6 setting. 240 | - `mem_man`: memory management experiment. 241 | - `mem_size`: memory size experiment. 242 | - For example, after running `python console.py run_tpcc`, you can run: 243 | - `python parser.py tput tpcc` will give you the transaction throughput. It will give the results we used for Figure 10(a) (Shown below). 244 | ![10b](figures/10a.jpg) 245 | ## 5. Contact
246 | You can email us at `zhuolong at cs dot jhu dot edu` if you have any questions. 247 | --------------------------------------------------------------------------------