diff options
Diffstat (limited to 'examples/performance-thread')
20 files changed, 284 insertions, 37 deletions
diff --git a/examples/performance-thread/common/arch/x86/ctx.h b/examples/performance-thread/common/arch/x86/ctx.h index 03860508..a41ce05a 100644 --- a/examples/performance-thread/common/arch/x86/ctx.h +++ b/examples/performance-thread/common/arch/x86/ctx.h @@ -35,6 +35,10 @@ #ifndef CTX_H #define CTX_H +#ifdef __cplusplus +extern "C" { +#endif + /* * CPU context registers */ @@ -54,4 +58,8 @@ void ctx_switch(struct ctx *new_ctx, struct ctx *curr_ctx); +#ifdef __cplusplus +} +#endif + #endif /* RTE_CTX_H_ */ diff --git a/examples/performance-thread/common/common.mk b/examples/performance-thread/common/common.mk index d3de5fc6..f6cab771 100644 --- a/examples/performance-thread/common/common.mk +++ b/examples/performance-thread/common/common.mk @@ -30,13 +30,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# list the C files belonhing to the lthread subsystem, these are common to all lthread apps -SRCS-y += ../common/lthread.c \ - ../common/lthread_sched.c \ - ../common/lthread_cond.c \ - ../common/lthread_tls.c \ - ../common/lthread_mutex.c \ - ../common/lthread_diag.c \ - ../common/arch/x86/ctx.c +# list the C files belonging to the lthread subsystem, these are common to all +# lthread apps. Any makefile including this should set VPATH to include this +# directory path +# + +MKFILE_PATH=$(abspath $(dir $(lastword $(MAKEFILE_LIST)))) + +VPATH := $(MKFILE_PATH) $(MKFILE_PATH)/arch/x86 + +SRCS-y += lthread.c lthread_sched.c lthread_cond.c lthread_tls.c lthread_mutex.c lthread_diag.c ctx.c -INCLUDES += -I$(RTE_SDK)/examples/performance-thread/common/ -I$(RTE_SDK)/examples/performance-thread/common/arch/x86/ +INCLUDES += -I$(MKFILE_PATH) -I$(MKFILE_PATH)/arch/x86/ diff --git a/examples/performance-thread/common/lthread.h b/examples/performance-thread/common/lthread.h index 8c77af82..5c2c1a5f 100644 --- a/examples/performance-thread/common/lthread.h +++ b/examples/performance-thread/common/lthread.h @@ -62,6 +62,10 @@ #ifndef LTHREAD_H_ #define LTHREAD_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include <rte_per_lcore.h> #include "lthread_api.h" @@ -96,4 +100,8 @@ _lthread_init(struct lthread *lt, void _lthread_set_stack(struct lthread *lt, void *stack, size_t stack_size); +#ifdef __cplusplus +} +#endif + #endif /* LTHREAD_H_ */ diff --git a/examples/performance-thread/common/lthread_api.h b/examples/performance-thread/common/lthread_api.h index ec976103..ff245a08 100644 --- a/examples/performance-thread/common/lthread_api.h +++ b/examples/performance-thread/common/lthread_api.h @@ -124,6 +124,10 @@ #ifndef LTHREAD_H #define LTHREAD_H +#ifdef __cplusplus +extern "C" { +#endif + #include <stdint.h> #include <sys/socket.h> #include <fcntl.h> @@ -829,4 +833,8 @@ int lthread_cond_signal(struct lthread_cond *c); */ int lthread_cond_broadcast(struct lthread_cond *c); +#ifdef __cplusplus +} +#endif + #endif /* LTHREAD_H */ diff --git a/examples/performance-thread/common/lthread_cond.h b/examples/performance-thread/common/lthread_cond.h index 5bd02a7d..5e5f14be 100644 --- a/examples/performance-thread/common/lthread_cond.h +++ b/examples/performance-thread/common/lthread_cond.h @@ -62,6 +62,10 @@ #ifndef LTHREAD_COND_H_ #define LTHREAD_COND_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "lthread_queue.h" #define MAX_COND_NAME_SIZE 64 @@ -74,4 +78,8 @@ struct lthread_cond { uint64_t diag_ref; /* optional ref to user diag data */ } __rte_cache_aligned; +#ifdef __cplusplus +} +#endif + #endif /* LTHREAD_COND_H_ */ diff --git a/examples/performance-thread/common/lthread_diag.h b/examples/performance-thread/common/lthread_diag.h index 2877d311..3dce8e0e 100644 --- a/examples/performance-thread/common/lthread_diag.h +++ b/examples/performance-thread/common/lthread_diag.h @@ -34,6 +34,10 @@ #ifndef LTHREAD_DIAG_H_ #define LTHREAD_DIAG_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include <stdint.h> #include <inttypes.h> @@ -129,4 +133,9 @@ extern uint64_t diag_mask; #define DIAG_USED __rte_unused #endif /* LTHREAD_DIAG */ + +#ifdef __cplusplus +} +#endif + #endif /* LTHREAD_DIAG_H_ */ diff --git a/examples/performance-thread/common/lthread_diag_api.h b/examples/performance-thread/common/lthread_diag_api.h index 7ee514f8..2fda0951 100644 --- a/examples/performance-thread/common/lthread_diag_api.h +++ b/examples/performance-thread/common/lthread_diag_api.h @@ -33,6 +33,10 @@ #ifndef LTHREAD_DIAG_API_H_ #define LTHREAD_DIAG_API_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include <stdint.h> #include <inttypes.h> @@ -322,4 +326,8 @@ lthread_cond_diag_ref(struct lthread_cond *c); uint64_t lthread_mutex_diag_ref(struct lthread_mutex *m); +#ifdef __cplusplus +} +#endif + #endif /* LTHREAD_DIAG_API_H_ */ diff --git a/examples/performance-thread/common/lthread_int.h b/examples/performance-thread/common/lthread_int.h index 031d8afc..3f7fb92d 100644 --- a/examples/performance-thread/common/lthread_int.h +++ b/examples/performance-thread/common/lthread_int.h @@ -62,6 +62,10 @@ #include <lthread_api.h> #define LTHREAD_INT_H +#ifdef __cplusplus +extern "C" { +#endif + #include <stdint.h> #include <sys/time.h> #include <sys/types.h> @@ -197,4 +201,8 @@ struct lthread { uint64_t diag_ref; /* ref to user diag data */ } __rte_cache_aligned; +#ifdef __cplusplus +} +#endif + #endif /* LTHREAD_INT_H */ diff --git a/examples/performance-thread/common/lthread_mutex.h b/examples/performance-thread/common/lthread_mutex.h index 4d30b2e7..e78db91d 100644 --- a/examples/performance-thread/common/lthread_mutex.h +++ b/examples/performance-thread/common/lthread_mutex.h @@ -35,6 +35,10 @@ #ifndef LTHREAD_MUTEX_H_ #define LTHREAD_MUTEX_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "lthread_queue.h" @@ -49,4 +53,8 @@ struct lthread_mutex { uint64_t diag_ref; /* optional ref to user diag data */ } __rte_cache_aligned; +#ifdef __cplusplus +} +#endif + #endif /* LTHREAD_MUTEX_H_ */ diff --git a/examples/performance-thread/common/lthread_objcache.h b/examples/performance-thread/common/lthread_objcache.h index d7e35825..6e5195ba 100644 --- a/examples/performance-thread/common/lthread_objcache.h +++ b/examples/performance-thread/common/lthread_objcache.h @@ -33,6 +33,10 @@ #ifndef LTHREAD_OBJCACHE_H_ #define LTHREAD_OBJCACHE_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include <string.h> #include <rte_per_lcore.h> @@ -154,5 +158,8 @@ _lthread_objcache_free(struct lthread_objcache *c, void *obj) } +#ifdef __cplusplus +} +#endif #endif /* LTHREAD_OBJCACHE_H_ */ diff --git a/examples/performance-thread/common/lthread_pool.h b/examples/performance-thread/common/lthread_pool.h index 27680eab..fb0c578b 100644 --- a/examples/performance-thread/common/lthread_pool.h +++ b/examples/performance-thread/common/lthread_pool.h @@ -69,6 +69,10 @@ #ifndef LTHREAD_POOL_H_ #define LTHREAD_POOL_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include <rte_malloc.h> #include <rte_per_lcore.h> #include <rte_log.h> @@ -328,5 +332,8 @@ _qnode_pool_destroy(struct qnode_pool *p) return 0; } +#ifdef __cplusplus +} +#endif #endif /* LTHREAD_POOL_H_ */ diff --git a/examples/performance-thread/common/lthread_queue.h b/examples/performance-thread/common/lthread_queue.h index 2c55fcec..4fc2074e 100644 --- a/examples/performance-thread/common/lthread_queue.h +++ b/examples/performance-thread/common/lthread_queue.h @@ -69,6 +69,10 @@ #ifndef LTHREAD_QUEUE_H_ #define LTHREAD_QUEUE_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include <string.h> #include <rte_prefetch.h> @@ -298,5 +302,8 @@ _lthread_queue_remove(struct lthread_queue *q) return NULL; } +#ifdef __cplusplus +} +#endif #endif /* LTHREAD_QUEUE_H_ */ diff --git a/examples/performance-thread/common/lthread_sched.h b/examples/performance-thread/common/lthread_sched.h index 4ce56c27..7cddda9c 100644 --- a/examples/performance-thread/common/lthread_sched.h +++ b/examples/performance-thread/common/lthread_sched.h @@ -62,6 +62,10 @@ #ifndef LTHREAD_SCHED_H_ #define LTHREAD_SCHED_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "lthread_int.h" #include "lthread_queue.h" #include "lthread_objcache.h" @@ -148,5 +152,8 @@ extern struct lthread_sched *schedcore[]; void _sched_timer_cb(struct rte_timer *tim, void *arg); void _sched_shutdown(__rte_unused void *arg); +#ifdef __cplusplus +} +#endif #endif /* LTHREAD_SCHED_H_ */ diff --git a/examples/performance-thread/common/lthread_timer.h b/examples/performance-thread/common/lthread_timer.h index b5e6fb0e..7c03d673 100644 --- a/examples/performance-thread/common/lthread_timer.h +++ b/examples/performance-thread/common/lthread_timer.h @@ -35,6 +35,10 @@ #ifndef LTHREAD_TIMER_H_ #define LTHREAD_TIMER_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "lthread_int.h" #include "lthread_sched.h" @@ -42,11 +46,22 @@ static inline uint64_t _ns_to_clks(uint64_t ns) { - unsigned __int128 clkns = rte_get_tsc_hz(); + /* + * clkns needs to be divided by 1E9 to get ns clocks. However, + * dividing by this first would lose a lot of accuracy. + * Dividing after a multiply by ns, could cause overflow of + * uint64_t if ns is about 5 seconds [if we assume a max tsc + * rate of 4GHz]. Therefore we first divide by 1E4, then + * multiply and finally divide by 1E5. This allows ns to be + * values many hours long, without overflow, while still keeping + * reasonable accuracy. + */ + uint64_t clkns = rte_get_tsc_hz() / 1e4; clkns *= ns; - clkns /= 1000000000; - return (uint64_t) clkns; + clkns /= 1e5; + + return clkns; } @@ -75,5 +90,8 @@ _timer_stop(struct lthread *lt) } } +#ifdef __cplusplus +} +#endif #endif /* LTHREAD_TIMER_H_ */ diff --git a/examples/performance-thread/common/lthread_tls.c b/examples/performance-thread/common/lthread_tls.c index 6876f831..47505f2d 100644 --- a/examples/performance-thread/common/lthread_tls.c +++ b/examples/performance-thread/common/lthread_tls.c @@ -42,7 +42,6 @@ #include <fcntl.h> #include <sys/time.h> #include <sys/mman.h> -#include <execinfo.h> #include <sched.h> #include <rte_malloc.h> diff --git a/examples/performance-thread/common/lthread_tls.h b/examples/performance-thread/common/lthread_tls.h index 86cbfadc..fff3c0db 100644 --- a/examples/performance-thread/common/lthread_tls.h +++ b/examples/performance-thread/common/lthread_tls.h @@ -34,6 +34,10 @@ #ifndef LTHREAD_TLS_H_ #define LTHREAD_TLS_H_ +#ifdef __cplusplus +extern "C" { +#endif + #include "lthread_api.h" #define RTE_PER_LTHREAD_SECTION_SIZE \ @@ -53,5 +57,8 @@ void _lthread_tls_destroy(struct lthread *lt); void _lthread_key_pool_init(void); void _lthread_tls_alloc(struct lthread *lt); +#ifdef __cplusplus +} +#endif #endif /* LTHREAD_TLS_H_ */ diff --git a/examples/performance-thread/l3fwd-thread/main.c b/examples/performance-thread/l3fwd-thread/main.c index fdc90b28..2d98473e 100644 --- a/examples/performance-thread/l3fwd-thread/main.c +++ b/examples/performance-thread/l3fwd-thread/main.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -90,6 +90,68 @@ #define APP_LOOKUP_METHOD APP_LOOKUP_LPM #endif +#ifndef __GLIBC__ /* sched_getcpu() is glibc specific */ +#define sched_getcpu() rte_lcore_id() +#endif + +static int +check_ptype(int portid) +{ + int i, ret; + int ipv4 = 0, ipv6 = 0; + + ret = rte_eth_dev_get_supported_ptypes(portid, RTE_PTYPE_L3_MASK, NULL, + 0); + if (ret <= 0) + return 0; + + uint32_t ptypes[ret]; + + ret = rte_eth_dev_get_supported_ptypes(portid, RTE_PTYPE_L3_MASK, + ptypes, ret); + for (i = 0; i < ret; ++i) { + if (ptypes[i] & RTE_PTYPE_L3_IPV4) + ipv4 = 1; + if (ptypes[i] & RTE_PTYPE_L3_IPV6) + ipv6 = 1; + } + + if (ipv4 && ipv6) + return 1; + + return 0; +} + +static inline void +parse_ptype(struct rte_mbuf *m) +{ + struct ether_hdr *eth_hdr; + uint32_t packet_type = RTE_PTYPE_UNKNOWN; + uint16_t ether_type; + + eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); + ether_type = eth_hdr->ether_type; + if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) + packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN; + else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6)) + packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN; + + m->packet_type = packet_type; +} + +static uint16_t +cb_parse_ptype(__rte_unused uint8_t port, __rte_unused uint16_t queue, + struct rte_mbuf *pkts[], uint16_t nb_pkts, + __rte_unused uint16_t max_pkts, __rte_unused void *user_param) +{ + unsigned int i; + + for (i = 0; i < nb_pkts; i++) + parse_ptype(pkts[i]); + + return nb_pkts; +} + /* * When set to zero, simple forwaring path is eanbled. * When set to one, optimized forwarding path is enabled. @@ -170,8 +232,9 @@ static __m128i val_eth[RTE_MAX_ETHPORTS]; /* mask of enabled ports */ static uint32_t enabled_port_mask; -static int promiscuous_on; /**< $et in promiscuous mode off by default. */ +static int promiscuous_on; /**< Set in promiscuous mode off by default. */ static int numa_on = 1; /**< NUMA is enabled by default. */ +static int parse_ptype_on; #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH) static int ipv6; /**< ipv6 is false by default. */ @@ -282,7 +345,7 @@ static struct rte_eth_conf port_conf = { .hw_ip_checksum = 1, /**< IP checksum offload enabled */ .hw_vlan_filter = 0, /**< VLAN filtering disabled */ .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ + .hw_strip_crc = 1, /**< CRC stripped by hardware */ }, .rx_adv_conf = { .rss_conf = { @@ -850,7 +913,7 @@ static inline uint8_t get_ipv6_dst_port(void *ipv6_hdr, uint8_t portid, lookup6_struct_t *ipv6_l3fwd_lookup_struct) { - uint8_t next_hop; + uint32_t next_hop; return (uint8_t) ((rte_lpm6_lookup(ipv6_l3fwd_lookup_struct, ((struct ipv6_hdr *)ipv6_hdr)->dst_addr, &next_hop) == 0) ? @@ -1337,15 +1400,14 @@ rfc1812_process(struct ipv4_hdr *ipv4_hdr, uint16_t *dp, uint32_t ptype) static inline __attribute__((always_inline)) uint16_t get_dst_port(struct rte_mbuf *pkt, uint32_t dst_ipv4, uint8_t portid) { - uint32_t next_hop_ipv4; - uint8_t next_hop_ipv6; + uint32_t next_hop; struct ipv6_hdr *ipv6_hdr; struct ether_hdr *eth_hdr; if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) { return (uint16_t) ((rte_lpm_lookup( RTE_PER_LCORE(lcore_conf)->ipv4_lookup_struct, dst_ipv4, - &next_hop_ipv4) == 0) ? next_hop_ipv4 : portid); + &next_hop) == 0) ? next_hop : portid); } else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) { @@ -1354,8 +1416,8 @@ get_dst_port(struct rte_mbuf *pkt, uint32_t dst_ipv4, uint8_t portid) return (uint16_t) ((rte_lpm6_lookup( RTE_PER_LCORE(lcore_conf)->ipv6_lookup_struct, - ipv6_hdr->dst_addr, &next_hop_ipv6) == 0) ? next_hop_ipv6 : - portid); + ipv6_hdr->dst_addr, &next_hop) == 0) ? + next_hop : portid); } @@ -2019,7 +2081,7 @@ lthread_tx_per_ring(void *dummy) */ SET_CPU_BUSY(tx_conf, CPU_POLL); nb_rx = rte_ring_sc_dequeue_burst(ring, (void **)pkts_burst, - MAX_PKT_BURST); + MAX_PKT_BURST, NULL); SET_CPU_IDLE(tx_conf, CPU_POLL); if (nb_rx > 0) { @@ -2155,7 +2217,7 @@ lthread_rx(void *dummy) ret = rte_ring_sp_enqueue_burst( rx_conf->ring[worker_id], (void **) pkts_burst, - nb_rx); + nb_rx, NULL); new_len = old_len + ret; @@ -2323,7 +2385,7 @@ pthread_tx(void *dummy) */ SET_CPU_BUSY(tx_conf, CPU_POLL); nb_rx = rte_ring_sc_dequeue_burst(tx_conf->ring, - (void **)pkts_burst, MAX_PKT_BURST); + (void **)pkts_burst, MAX_PKT_BURST, NULL); SET_CPU_IDLE(tx_conf, CPU_POLL); if (unlikely(nb_rx == 0)) { @@ -2395,7 +2457,7 @@ pthread_rx(void *dummy) SET_CPU_BUSY(rx_conf, CPU_PROCESS); worker_id = (worker_id + 1) % rx_conf->n_ring; n = rte_ring_sp_enqueue_burst(rx_conf->ring[worker_id], - (void **)pkts_burst, nb_rx); + (void **)pkts_burst, nb_rx, NULL); if (unlikely(n != nb_rx)) { uint32_t k; @@ -2610,6 +2672,7 @@ print_usage(const char *prgname) " [--rx (port,queue,lcore,thread)[,(port,queue,lcore,thread]]" " [--tx (lcore,thread)[,(lcore,thread]]" " [--enable-jumbo [--max-pkt-len PKTLEN]]\n" + " [--parse-ptype]\n\n" " -p PORTMASK: hexadecimal bitmask of ports to configure\n" " -P : enable promiscuous mode\n" " --rx (port,queue,lcore,thread): rx queues configuration\n" @@ -2621,7 +2684,8 @@ print_usage(const char *prgname) " --enable-jumbo: enable jumbo frame" " which max packet len is PKTLEN in decimal (64-9600)\n" " --hash-entry-num: specify the hash entry number in hexadecimal to be setup\n" - " --no-lthreads: turn off lthread model\n", + " --no-lthreads: turn off lthread model\n" + " --parse-ptype: set to use software to analyze packet type\n\n", prgname); } @@ -2840,6 +2904,7 @@ parse_eth_dest(const char *optarg) #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo" #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num" #define CMD_LINE_OPT_NO_LTHREADS "no-lthreads" +#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype" /* Parse the argument given in the command line of the application */ static int @@ -2859,6 +2924,7 @@ parse_args(int argc, char **argv) {CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0}, {CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0}, {CMD_LINE_OPT_NO_LTHREADS, 0, 0, 0}, + {CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0}, {NULL, 0, 0, 0} }; @@ -2935,6 +3001,12 @@ parse_args(int argc, char **argv) lthreads_on = 0; } + if (!strncmp(lgopts[option_index].name, CMD_LINE_OPT_PARSE_PTYPE, + sizeof(CMD_LINE_OPT_PARSE_PTYPE))) { + printf("software packet type parsing enabled\n"); + parse_ptype_on = 1; + } + if (!strncmp(lgopts[option_index].name, CMD_LINE_OPT_ENABLE_JUMBO, sizeof(CMD_LINE_OPT_ENABLE_JUMBO))) { struct option lenopts = {"max-pkt-len", required_argument, 0, @@ -2983,7 +3055,7 @@ parse_args(int argc, char **argv) argv[optind-1] = prgname; ret = optind-1; - optind = 0; /* reset getopt lib */ + optind = 1; /* reset getopt lib */ return ret; } @@ -3623,6 +3695,31 @@ main(int argc, char **argv) rte_eth_promiscuous_enable(portid); } + for (i = 0; i < n_rx_thread; i++) { + lcore_id = rx_thread[i].conf.lcore_id; + if (rte_lcore_is_enabled(lcore_id) == 0) + continue; + + /* check if hw packet type is supported */ + for (queue = 0; queue < rx_thread[i].n_rx_queue; ++queue) { + portid = rx_thread[i].rx_queue_list[queue].port_id; + queueid = rx_thread[i].rx_queue_list[queue].queue_id; + + if (parse_ptype_on) { + if (!rte_eth_add_rx_callback(portid, queueid, + cb_parse_ptype, NULL)) + rte_exit(EXIT_FAILURE, + "Failed to add rx callback: " + "port=%d\n", portid); + } else if (!check_ptype(portid)) + rte_exit(EXIT_FAILURE, + "Port %d cannot parse packet type.\n\n" + "Please add --parse-ptype to use sw " + "packet type analyzer.\n\n", + portid); + } + } + check_all_ports_link_status((uint8_t)nb_ports, enabled_port_mask); if (lthreads_on) { diff --git a/examples/performance-thread/pthread_shim/main.c b/examples/performance-thread/pthread_shim/main.c index f0357218..850b009d 100644 --- a/examples/performance-thread/pthread_shim/main.c +++ b/examples/performance-thread/pthread_shim/main.c @@ -59,6 +59,10 @@ #define DEBUG_APP 0 #define HELLOW_WORLD_MAX_LTHREADS 10 +#ifndef __GLIBC__ /* sched_getcpu() is glibc-specific */ +#define sched_getcpu() rte_lcore_id() +#endif + __thread int print_count; __thread pthread_mutex_t print_lock; @@ -175,12 +179,12 @@ static void initial_lthread(void *args __attribute__((unused))) * use an attribute to pass the desired lcore */ pthread_attr_t attr; - cpu_set_t cpuset; + rte_cpuset_t cpuset; CPU_ZERO(&cpuset); CPU_SET(lcore, &cpuset); pthread_attr_init(&attr); - pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset); + pthread_attr_setaffinity_np(&attr, sizeof(rte_cpuset_t), &cpuset); /* create the thread */ pthread_create(&tid[i], &attr, helloworld_pthread, (void *) i); diff --git a/examples/performance-thread/pthread_shim/pthread_shim.c b/examples/performance-thread/pthread_shim/pthread_shim.c index 0d6100c9..113bafa0 100644 --- a/examples/performance-thread/pthread_shim/pthread_shim.c +++ b/examples/performance-thread/pthread_shim/pthread_shim.c @@ -48,6 +48,21 @@ #define POSIX_ERRNO(x) (x) +/* some releases of FreeBSD 10, e.g. 10.0, don't have CPU_COUNT macro */ +#ifndef CPU_COUNT +#define CPU_COUNT(x) __cpu_count(x) + +static inline unsigned int +__cpu_count(const rte_cpuset_t *cpuset) +{ + unsigned int i, count = 0; + for (i = 0; i < RTE_MAX_LCORE; i++) + if (CPU_ISSET(i, cpuset)) + count++; + return count; +} +#endif + /* * this flag determines at run time if we override pthread * calls and map then to equivalent lthread calls @@ -159,7 +174,7 @@ int (*f_pthread_setschedparam) int (*f_pthread_yield) (void); int (*f_pthread_setaffinity_np) - (pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset); + (pthread_t thread, size_t cpusetsize, const rte_cpuset_t *cpuset); int (*f_nanosleep) (const struct timespec *req, struct timespec *rem); } _sys_pthread_funcs = { @@ -390,11 +405,11 @@ pthread_create(pthread_t *__restrict tid, if (attr != NULL) { /* determine CPU being requested */ - cpu_set_t cpuset; + rte_cpuset_t cpuset; CPU_ZERO(&cpuset); pthread_attr_getaffinity_np(attr, - sizeof(cpu_set_t), + sizeof(rte_cpuset_t), &cpuset); if (CPU_COUNT(&cpuset) != 1) @@ -576,15 +591,26 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *a) return _sys_pthread_funcs.f_pthread_rwlock_wrlock(a); } -int pthread_yield(void) +#ifdef RTE_EXEC_ENV_LINUXAPP +int +pthread_yield(void) { if (override) { lthread_yield(); return 0; } return _sys_pthread_funcs.f_pthread_yield(); - } +#else +void +pthread_yield(void) +{ + if (override) + lthread_yield(); + else + _sys_pthread_funcs.f_pthread_yield(); +} +#endif pthread_t pthread_self(void) { @@ -686,7 +712,7 @@ int nanosleep(const struct timespec *req, struct timespec *rem) int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, - const cpu_set_t *cpuset) + const rte_cpuset_t *cpuset) { if (override) { /* we only allow affinity with a single CPU */ diff --git a/examples/performance-thread/pthread_shim/pthread_shim.h b/examples/performance-thread/pthread_shim/pthread_shim.h index 78bbb5ac..10f87894 100644 --- a/examples/performance-thread/pthread_shim/pthread_shim.h +++ b/examples/performance-thread/pthread_shim/pthread_shim.h @@ -33,7 +33,8 @@ #ifndef _PTHREAD_SHIM_H_ #define _PTHREAD_SHIM_H_ -#include <pthread.h> + +#include <rte_lcore.h> /* * This pthread shim is an example that demonstrates how legacy code |