Click
Loading...
Searching...
No Matches
glue.hh
1// -*- c-basic-offset: 4; related-file-name: "../../lib/glue.cc" -*-
2#ifndef CLICK_GLUE_HH
3#define CLICK_GLUE_HH
4// Removes many common #include <header>s and abstracts differences between
5// kernel and user space, and between operating systems.
6
7// HEADERS
8
9#if CLICK_LINUXMODULE
10
11# define _LOOSE_KERNEL_NAMES 1 /* define ino_t, off_t, etc. */
12# undef __KERNEL_STRICT_NAMES
13# ifndef __OPTIMIZE__
14# define __OPTIMIZE__ 1 /* get ntohl() macros. otherwise undefined. */
15# endif
16# include <click/cxxprotect.h>
17CLICK_CXX_PROTECT
18# ifdef WANT_MOD_USE_COUNT
19# define __NO_VERSION__
20# include <linux/module.h>
21# define HAVE_MOD_USE_COUNT 1
22# endif
23# include <linux/kernel.h>
24# include <linux/string.h>
25# include <linux/skbuff.h>
26# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
27# include <linux/malloc.h>
28# include <linux/vmalloc.h>
29# include <linux/interrupt.h>
30# else
31# include <linux/hardirq.h>
32# endif
33# include <linux/ctype.h>
34# include <linux/time.h>
35# include <linux/errno.h>
36# include <linux/delay.h>
37CLICK_CXX_UNPROTECT
38# include <click/cxxunprotect.h>
39
40#elif CLICK_BSDMODULE
41
42# include <click/cxxprotect.h>
43CLICK_CXX_PROTECT
44# include <sys/ctype.h>
45# include <sys/systm.h>
46# include <sys/time.h>
47# include <sys/param.h>
48# include <sys/kernel.h>
49# include <sys/mbuf.h>
50# include <sys/malloc.h>
51# include <sys/libkern.h>
52# include <sys/proc.h>
53# include <sys/sysproto.h>
54# include <sys/limits.h>
55# include <sys/module.h> /* XXX: for packages */
56CLICK_CXX_UNPROTECT
57# include <click/cxxunprotect.h>
58
59#elif CLICK_MINIOS
60
61# include <click/cxxprotect.h>
62CLICK_CXX_PROTECT
63# include <stdio.h>
64# include <stdlib.h>
65# include <stddef.h>
66# include <stdint.h>
67# include <string.h>
68# include <ctype.h>
69# include <errno.h>
70# include <limits.h>
71# include <time.h>
72# include <sys/socket.h>
73# include <netinet/in.h>
74# include <sys/time.h>
75CLICK_CXX_UNPROTECT
76# include <click/cxxunprotect.h>
77
78#else /* CLICK_USERLEVEL */
79
80# include <stdio.h>
81# include <stdlib.h>
82# include <stddef.h>
83# include <stdint.h>
84# include <string.h>
85# include <ctype.h>
86# include <errno.h>
87# include <unistd.h>
88# include <limits.h>
89# include <time.h>
90# include <sys/socket.h>
91# include <netinet/in.h>
92# include <sys/time.h>
93# if CLICK_NS
94extern "C" int simclick_gettimeofday(struct timeval *);
95# endif
96# if HAVE_MULTITHREAD
97# include <pthread.h>
98# include <sched.h>
99# endif
100
101#if HAVE_DPDK && !CLICK_TOOL
102extern "C" {
103 #include <rte_cycles.h>
104}
105#endif
106#if defined(__MACH__) && defined(__APPLE__)
107# include <mach/mach_time.h>
108#endif
109
110#endif
111
112
113// DEBUGGING OUTPUT
114extern "C" {
115void click_chatter(const char *fmt, ...);
116}
117
118
119// DEBUG MALLOC
120
121#if CLICK_DMALLOC && (CLICK_LINUXMODULE || CLICK_BSDMODULE || CLICK_MINIOS)
122extern uint32_t click_dmalloc_where;
123# define CLICK_DMALLOC_REG(s) do { const unsigned char *__str = reinterpret_cast<const unsigned char *>(s); click_dmalloc_where = (__str[0]<<24) | (__str[1]<<16) | (__str[2]<<8) | __str[3]; } while (0)
124#else
125# define CLICK_DMALLOC_REG(s)
126#endif
127
128
129// LALLOC
130
131#if CLICK_LINUXMODULE
132# define CLICK_DEFAULT_ALIGNMENT ARCH_KMALLOC_MINALIGN
133# define CLICK_LALLOC(size) (click_lalloc((size)))
134# define CLICK_LFREE(p, size) (click_lfree((p), (size)))
135extern "C" {
136void *click_lalloc(size_t size);
137void click_lfree(volatile void *p, size_t size);
138}
139#else
140# ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
141# define CLICK_DEFAULT_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__
142# else
143# define CLICK_DEFAULT_ALIGNMENT 16
144# endif
145# define CLICK_LALLOC(size) ((void *)(new uint8_t[(size)]))
146# define CLICK_LFREE(p, size) delete[] ((void) (size), (uint8_t *)(p))
147#endif
148
149# if HAVE_ALIGNED_ALLOC
150# define CLICK_ALIGNED_ALLOC(size, ...) (aligned_alloc(CLICK_CACHE_LINE_SIZE, size))
151# define CLICK_ALIGNED_ALLOC_T(size,align) (aligned_alloc(align, size))
152# define CLICK_ALIGNED_FREE(p,size) (free(p))
153# else
154# ifndef CLICK_LINUXMODULE
155# warning Using normal allocation instead of aligned one, please use a compiler that supports aligned_alloc
156# endif
157# define CLICK_ALIGNED_ALLOC(size) CLICK_LALLOC(size)
158# define CLICK_ALIGNED_ALLOC_T(size,align) CLICK_LALLOC(size)
159# define CLICK_ALIGNED_FREE(p,size) CLICK_LFREE(p,size);
160# endif
161
162#if HAVE_ALIGNED_NEW
163# define CLICK_ALIGNED_NEW(T,n) (new T[n])
164# define CLICK_ALIGNED_DELETE(p,T,n) (delete[] p)
165#else
166# define CLICK_ALIGNED_NEW(T,n) ({T* v = (T*)CLICK_ALIGNED_ALLOC(sizeof(T) * (n));for (unsigned i = 0; i < (n); i++) {new(&v[i]) T();};v;})
167# define CLICK_ALIGNED_DELETE(p,T,n) {for (unsigned i = 0; i < (n); i++) p[i].~T();CLICK_ALIGNED_FREE(p,sizeof(T)*(n));}
168#endif
169
170#define CLICK_ASSERT_ALIGNED(p) (assert(((intptr_t)p & (intptr_t)(CLICK_CACHE_LINE_SIZE - 1)) == 0))
171
172// RANDOMNESS
173
174CLICK_DECLS
175
176#define assume(cond) do { if (!(cond)) __builtin_unreachable(); } while (0)
177
178#if HAVE_DPDK
179extern bool dpdk_enabled;
180#endif
181
185uint32_t click_random();
186
190uint32_t click_random(uint32_t low, uint32_t high);
191
194uint32_t click_random(uint32_t high);
195
197void click_srandom(uint32_t seed);
198
201void click_random_srandom();
202
203#if CLICK_BSDMODULE
204# define CLICK_RAND_MAX 0x7FFFFFFFU
205#elif !CLICK_LINUXMODULE && RAND_MAX >= 0x7FFFFFFFU
206# define CLICK_RAND_MAX RAND_MAX
207#else
208# define CLICK_RAND_MAX 0x7FFFFFFFU
209extern uint32_t click_random_seed;
210#endif
211
212#if CLICK_NS
213extern uint32_t click_random();
214#else
215inline uint32_t click_random() {
216# if CLICK_BSDMODULE
217 return random();
218# elif CLICK_LINUXMODULE
219 click_random_seed = click_random_seed * 69069L + 5;
220 return (click_random_seed ^ jiffies) & CLICK_RAND_MAX; // XXX jiffies??
221# elif CLICK_MINIOS
222 return rand();
223# elif HAVE_RANDOM && CLICK_RAND_MAX == RAND_MAX
224 // See also click_random() in ns/nsclick.cc
225 return random();
226# else
227 return rand();
228# endif
229}
230#endif
231
232inline void click_srandom(uint32_t seed) {
233#if CLICK_BSDMODULE
234 srandom(seed);
235#elif CLICK_LINUXMODULE
236 click_random_seed = seed;
237#elif CLICK_MINIOS
238 srand(seed);
239#elif CLICK_NS
240 (void) seed; /* XXX */
241#elif HAVE_RANDOM && CLICK_RAND_MAX == RAND_MAX
242 srandom(seed);
243#else
244 srand(seed);
245#endif
246}
247
248CLICK_ENDDECLS
249
250
251// SORTING
252
285int click_qsort(void *base, size_t n, size_t size,
286 int (*compar)(const void *a, const void *b, void *user_data),
287 void *user_data = 0);
288
298int click_qsort(void *base, size_t n, size_t size,
299 int (*compar)(const void *a, const void *b)) CLICK_DEPRECATED;
300
304template <typename T> int click_compare(const void *a, const void *b, void *)
305{
306 const T *ta = static_cast<const T *>(a);
307 const T *tb = static_cast<const T *>(b);
308 return (*ta < *tb ? -1 : (*tb < *ta ? 1 : 0));
309}
310
312template <typename T> int click_qsort(T *base, size_t n)
313{
314 return click_qsort(base, n, sizeof(T), (int (*)(const void *, const void *, void *)) &click_compare<T>);
315}
316
317
318// OTHER
319
320#if CLICK_LINUXMODULE
321
322extern "C" {
323
324long strtol(const char *, char **, int);
325
326inline unsigned long
327strtoul(const char *nptr, char **endptr, int base)
328{
329 return simple_strtoul(nptr, endptr, base);
330}
331
332# if __GNUC__ == 2 && __GNUC_MINOR__ == 96
333int click_strcmp(const char *, const char *);
334
335inline int
336strcmp(const char *a, const char *b)
337{
338 return click_strcmp(a, b);
339}
340# endif
341
342}
343
344#elif CLICK_BSDMODULE
345
346/* Char-type glue */
347
348# define _U 0x01 /* upper */
349# define _L 0x02 /* lower */
350# define _D 0x04 /* digit */
351# define _C 0x08 /* cntrl */
352# define _P 0x10 /* punct */
353# define _S 0x20 /* white space (space/lf/tab) */
354# define _X 0x40 /* hex digit */
355# define _SP 0x80 /* hard space (0x20) */
356
357extern unsigned char _ctype[];
358
359# define __ismask(x) (_ctype[(int)(unsigned char)(x)])
360# define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
361
362# define strchr(s, c) index(s, c)
363
364# if __FreeBSD_version >= 700000 && __FreeBSD_version < 730000
365/* memmove() appeared in the FreeBSD 7.3 kernel */
366extern "C" void *memmove(void *dest, const void *src, size_t len);
367# endif
368
369
370typedef struct ifnet net_device;
371
372#else /* not CLICK_LINUXMODULE || CLICK_BSDMODULE */
373
374// provide a definition for net_device
375typedef struct device net_device;
376
377#endif /* CLICK_LINUXMODULE */
378
379
380// COMPILE-TIME ASSERTION CHECKING
381
382#if (!defined(__cplusplus) || !HAVE_CXX_STATIC_ASSERT) && !defined(static_assert)
383# define static_assert(x, ...) switch ((int) (x)) case 0: case !!((int) (x)):
384#endif
385
386
387// PROCESSOR IDENTITIES
388
389#if CLICK_LINUXMODULE
390typedef uint32_t click_processor_t;
391# define CLICK_CPU_MAX NR_CPUS
392#elif CLICK_USERLEVEL && HAVE_MULTITHREAD
393typedef pthread_t click_processor_t;
394# define CLICK_CPU_MAX 256
395#else
396typedef int8_t click_processor_t;
397# if HAVE_MULTITHREAD
398# define CLICK_CPU_MAX 256
399# else
400# define CLICK_CPU_MAX 1
401# endif
402#endif
403
404inline click_processor_t
405click_get_processor()
406{
407#if CLICK_LINUXMODULE
408# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
409 return get_cpu();
410# else
411 return current->processor;
412# endif
413#elif CLICK_USERLEVEL && HAVE_MULTITHREAD
414 return pthread_self();
415#else
416 return 0;
417#endif
418}
419
420inline void
421click_put_processor()
422{
423#if CLICK_LINUXMODULE
424# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
425# ifdef put_cpu_no_resched
426 put_cpu_no_resched();
427# else
428 put_cpu();
429# endif
430# endif
431#endif
432}
433
434#if CLICK_USERLEVEL && HAVE_MULTITHREAD && HAVE___THREAD_STORAGE_CLASS
435extern __thread int click_current_thread_id;
436#endif
437
438#if CLICK_USERLEVEL
439extern int click_nthreads;
440#endif
441
442inline click_processor_t
443click_current_processor()
444{
445#if CLICK_LINUXMODULE
446# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
447 return smp_processor_id();
448# else
449 return current->processor;
450# endif
451#elif CLICK_USERLEVEL && HAVE_MULTITHREAD
452 return pthread_self();
453#else
454 return 0;
455#endif
456}
457
458inline unsigned
459click_current_cpu_id()
460{
461#if !HAVE_MULTITHREAD
462 return 0;
463#elif CLICK_USERLEVEL
464# if HAVE___THREAD_STORAGE_CLASS
465 return click_current_thread_id & 0xffff;
466# else
467 return sched_getcpu();
468# endif
469#else
470 return click_current_processor();
471#endif
472}
473
477inline unsigned
478click_max_cpu_ids()
479{
480#if CLICK_LINUXMODULE
481 return NR_CPUS;
482#elif CLICK_USERLEVEL && HAVE___THREAD_STORAGE_CLASS
483 return click_nthreads;
484#else //XXX BSDMODULE?
485 return CLICK_CPU_MAX;
486#endif
487}
488
489
490inline click_processor_t
491click_invalid_processor()
492{
493#if CLICK_LINUXMODULE
494 return -1;
495#elif CLICK_USERLEVEL && HAVE_MULTITHREAD
496 return 0;
497#else
498 return -1;
499#endif
500}
501
502// TIMEVALS AND JIFFIES
503// click_jiffies_t is the type of click_jiffies() and must be unsigned.
504// click_jiffies_difference_t is the signed version of click_jiffies_t.
505// CLICK_JIFFIES_MONOTONIC is true if click_jiffies() never goes backwards.
506
507#if CLICK_LINUXMODULE
508# define click_gettimeofday(tvp) (do_gettimeofday(tvp))
509typedef unsigned long click_jiffies_t;
510typedef long click_jiffies_difference_t;
511# define click_jiffies() (jiffies)
512# define CLICK_JIFFIES_MONOTONIC 1
513# define CLICK_HZ HZ
514# define click_jiffies_less(a, b) ((click_jiffies_difference_t) ((a) - (b)) < 0)
515# define HAS_LONG_CLICK_JIFFIES_T 1
516#elif CLICK_BSDMODULE
517# define click_gettimeofday(tvp) (getmicrotime(tvp))
518typedef unsigned click_jiffies_t;
519typedef int click_jiffies_difference_t;
520# define click_jiffies() (ticks)
521# define CLICK_HZ hz
522# define click_jiffies_less(a, b) ((click_jiffies_difference_t) ((a) - (b)) < 0)
523#else
524CLICK_DECLS
525void click_gettimeofday(timeval *tvp) CLICK_DEPRECATED;
526typedef long unsigned click_jiffies_t;
527typedef long int click_jiffies_difference_t;
528click_jiffies_t click_timestamp_jiffies(void*);
529# if HAVE_USER_TIMING
530typedef click_jiffies_t (*click_jiffies_fct_t)(void*);
531extern click_jiffies_fct_t click_jiffies_fct;
532extern void* click_jiffies_fct_data;
533# define click_jiffies() (click_jiffies_fct(click_jiffies_fct_data))
534# define CLICK_HZ 1000
535# else
536# define click_jiffies() (click_timestamp_jiffies(0))
537# define CLICK_HZ 1000
538# endif
539# define HAS_LONG_CLICK_JIFFIES_T 1
540# define click_jiffies_less(a, b) ((click_jiffies_difference_t) ((a) - (b)) < 0)
541CLICK_ENDDECLS
542#endif
543
544#if SIZEOF_CLICK_JIFFIES_T != (HAS_LONG_CLICK_JIFFIES_T ? SIZEOF_LONG : SIZEOF_INT)
545# error "SIZEOF_CLICK_JIFFIES_T declared incorrectly"
546#endif
547
548#if CLICK_LINUXMODULE
549#define sleep(ms) ssleep(ms)
550#endif
551
552// TIMEVAL OPERATIONS
553
554#ifndef timercmp
555// Convenience macros for operations on timevals.
556// NOTE: 'timercmp' does not work for >= or <=.
557# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
558# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
559# define timercmp(a, b, CMP) \
560 (((a)->tv_sec == (b)->tv_sec) ? \
561 ((a)->tv_usec CMP (b)->tv_usec) : \
562 ((a)->tv_sec CMP (b)->tv_sec))
563#endif
564#ifndef timeradd
565# define timeradd(a, b, result) \
566 do { \
567 (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
568 (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
569 if ((result)->tv_usec >= 1000000) \
570 { \
571 ++(result)->tv_sec; \
572 (result)->tv_usec -= 1000000; \
573 } \
574 } while (0)
575#endif
576#ifndef timersub
577# define timersub(a, b, result) \
578 do { \
579 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
580 (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
581 if ((result)->tv_usec < 0) { \
582 --(result)->tv_sec; \
583 (result)->tv_usec += 1000000; \
584 } \
585 } while (0)
586#endif
587
588#ifndef CLICK_TIMEVAL_OPERATORS
589
590inline timeval make_timeval(int sec, int usec) CLICK_DEPRECATED;
591inline bool operator==(const timeval &a, const timeval &b) CLICK_DEPRECATED;
592inline bool operator!=(const timeval &a, const timeval &b) CLICK_DEPRECATED;
593inline bool operator<(const timeval &a, const timeval &b) CLICK_DEPRECATED;
594inline bool operator<=(const timeval &a, const timeval &b) CLICK_DEPRECATED;
595inline bool operator>(const timeval &a, const timeval &b) CLICK_DEPRECATED;
596inline bool operator>=(const timeval &a, const timeval &b) CLICK_DEPRECATED;
597inline timeval &operator+=(timeval &a, const timeval &b) CLICK_DEPRECATED;
598inline timeval &operator-=(timeval &a, const timeval &b) CLICK_DEPRECATED;
599inline timeval operator+(timeval a, const timeval &b) CLICK_DEPRECATED;
600inline timeval operator-(timeval a, const timeval &b) CLICK_DEPRECATED;
601
602inline struct timeval
603make_timeval(int sec, int usec)
604{
605 struct timeval tv;
606 tv.tv_sec = sec;
607 tv.tv_usec = usec;
608 return tv;
609}
610
611inline bool
612operator==(const struct timeval &a, const struct timeval &b)
613{
614 return a.tv_sec == b.tv_sec && a.tv_usec == b.tv_usec;
615}
616
617inline bool
618operator!=(const struct timeval &a, const struct timeval &b)
619{
620 return a.tv_sec != b.tv_sec || a.tv_usec != b.tv_usec;
621}
622
623inline bool
624operator<(const struct timeval &a, const struct timeval &b)
625{
626 return a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_usec < b.tv_usec);
627}
628
629inline bool
630operator<=(const struct timeval &a, const struct timeval &b)
631{
632 return a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_usec <= b.tv_usec);
633}
634
635inline bool
636operator>=(const struct timeval &a, const struct timeval &b)
637{
638 return a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_usec >= b.tv_usec);
639}
640
641inline bool
642operator>(const struct timeval &a, const struct timeval &b)
643{
644 return a.tv_sec > b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_usec > b.tv_usec);
645}
646
647inline struct timeval &
648operator+=(struct timeval &a, const struct timeval &b)
649{
650 timeradd(&a, &b, &a);
651 return a;
652}
653
654inline struct timeval &
655operator-=(struct timeval &a, const struct timeval &b)
656{
657 timersub(&a, &b, &a);
658 return a;
659}
660
661inline struct timeval
662operator+(struct timeval a, const struct timeval &b)
663{
664 timeradd(&a, &b, &a);
665 return a;
666}
667
668inline struct timeval
669operator-(struct timeval a, const struct timeval &b)
670{
671 timersub(&a, &b, &a);
672 return a;
673}
674
675#endif
676
677CLICK_DECLS
678class StringAccum;
679StringAccum &operator<<(StringAccum &, const struct timeval &);
680CLICK_ENDDECLS
681
682
683// BYTE ORDER
684
685#ifndef le16_to_cpu
686# if CLICK_BYTE_ORDER == CLICK_LITTLE_ENDIAN
687# define le16_to_cpu(x) (x)
688# define cpu_to_le16(x) (x)
689# define le32_to_cpu(x) (x)
690# define cpu_to_le32(x) (x)
691# elif CLICK_BYTE_ORDER == CLICK_BIG_ENDIAN && defined(__APPLE__)
692# include <machine/byte_order.h>
693# define le16_to_cpu(x) NXSwapShort((x))
694# define cpu_to_le16(x) NXSwapShort((x))
695# define le32_to_cpu(x) NXSwapInt((x))
696# define cpu_to_le32(x) NXSwapInt((x))
697# elif CLICK_BYTE_ORDER == CLICK_BIG_ENDIAN && HAVE_BYTESWAP_H
698# include <byteswap.h>
699# define le16_to_cpu(x) bswap_16((x))
700# define cpu_to_le16(x) bswap_16((x))
701# define le32_to_cpu(x) bswap_32((x))
702# define cpu_to_le32(x) bswap_32((x))
703# elif CLICK_BYTE_ORDER == CLICK_BIG_ENDIAN
704# define le16_to_cpu(x) ((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8))
705# define cpu_to_le16(x) le16_to_cpu((x))
706# define le32_to_cpu(x) (le16_to_cpu((x) >> 16) | (le16_to_cpu(x) << 16))
707# define cpu_to_le32(x) le32_to_cpu((x))
708# else
709/* leave them undefined */
710# endif
711#endif
712
713
714// CYCLE COUNTS
715
716CLICK_DECLS
717
718#if HAVE_INT64_TYPES
719typedef uint64_t click_cycles_t;
720#else
721typedef uint32_t click_cycles_t;
722#endif
723
724inline click_cycles_t
725click_get_cycles()
726{
727#if defined(__MACH__) && defined(__APPLE__)
728 return mach_absolute_time();
729#elif CLICK_LINUXMODULE && HAVE_INT64_TYPES && __i386__
730 uint64_t x;
731 __asm__ __volatile__ ("rdtsc" : "=A" (x));
732 return x;
733#elif CLICK_LINUXMODULE && HAVE_INT64_TYPES && __x86_64__
734 uint32_t xlo, xhi;
735 __asm__ __volatile__ ("rdtsc" : "=a" (xlo), "=d" (xhi));
736 return xlo | (((uint64_t) xhi) << 32);
737#elif CLICK_LINUXMODULE && __i386__
738 uint32_t xlo, xhi;
739 __asm__ __volatile__ ("rdtsc" : "=a" (xlo), "=d" (xhi));
740 return xlo;
741#elif CLICK_BSDMODULE
742 return rdtsc();
743#elif CLICK_USERLEVEL && HAVE_INT64_TYPES && __i386__
744 uint64_t x;
745 __asm__ __volatile__ ("rdtsc" : "=A" (x));
746 return x;
747#elif CLICK_USERLEVEL && HAVE_INT64_TYPES && __x86_64__
748 uint32_t xlo, xhi;
749 __asm__ __volatile__ ("rdtsc" : "=a" (xlo), "=d" (xhi));
750 return xlo | (((uint64_t) xhi) << 32);
751#elif CLICK_USERLEVEL && __i386__
752 uint32_t xlo, xhi;
753 __asm__ __volatile__ ("rdtsc" : "=a" (xlo), "=d" (xhi));
754 return xlo;
755#elif CLICK_USERLEVEL && __aarch64__
756 uint64_t val;
757 asm volatile("mrs %0, cntvct_el0" : "=r" (val));
758 return val;
759#elif CLICK_USERLEVEL && HAVE_DPDK && defined(_RTE_CYCLES_H_)
760 // On other architectures we use DPDK implementation, if available
761 return rte_get_tsc_cycles();
762#elif CLICK_USERLEVEL
763 #error "click_get_cycles is not implemented for your architecture!"
764 return 0;
765#else
766 // add other architectures here
767 return 0;
768#endif
769}
770
771extern click_cycles_t click_cycles_hz;
772
773inline click_cycles_t cycles_hz() {
774#if HAVE_DPDK && !CLICK_TOOL
775 if (likely(dpdk_enabled)) {
776 return rte_get_timer_hz();
777 }
778 return 0;
779#elif defined(__MACH__) && defined(__APPLE__)
780 mach_timebase_info_data_t _clock_timebase;
781 mach_timebase_info(&_clock_timebase); // Initialize timebase_info
782 return _clock_timebase.denom / _clock_timebase.numer;
783#endif
784 if (click_cycles_hz == 0) {
785 click_cycles_t tsc_freq = click_get_cycles();
786 usleep(100000);
787 click_cycles_hz = (click_get_cycles() - tsc_freq) * 10;
788 }
789 return click_cycles_hz;
790}
791
792// Host to network order
793
794#define TYPE_INIT 0
795#define TYPE_LITEND 1
796#define TYPE_BIGEND 2
797
798#ifndef htonll
799inline unsigned long long htonll(unsigned long long src) {
800 static int typ = TYPE_INIT;
801 unsigned char c;
802 union {
803 unsigned long long ull;
804 unsigned char c[8];
805 } x;
806
807 if (typ == TYPE_INIT) {
808 x.ull = 0x01;
809 typ = (x.c[7] == 0x01ULL) ? TYPE_BIGEND : TYPE_LITEND;
810 }
811
812 if (typ == TYPE_BIGEND)
813 return src;
814
815 x.ull = src;
816 c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c;
817 c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c;
818 c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c;
819 c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c;
820
821 return x.ull;
822}
823#endif
824
825CLICK_ENDDECLS
826
827#endif
Efficiently build up Strings from pieces.
Definition straccum.hh:28
friend StringAccum & operator<<(StringAccum &sa, const String &str)
Append the contents of str to sa.
Definition straccum.hh:601