profile.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #include <linux/config.h> /* for CONFIG_NET_PROFILE */
  2. #ifndef _NET_PROFILE_H_
  3. #define _NET_PROFILE_H_ 1
  4. #ifdef CONFIG_NET_PROFILE
  5. #include <linux/types.h>
  6. #include <linux/time.h>
  7. #include <linux/kernel.h>
  8. #include <asm/system.h>
  9. #ifdef CONFIG_X86_TSC
  10. #include <asm/msr.h>
  11. #endif
  12. struct net_profile_slot
  13. {
  14. char   id[16];
  15. struct net_profile_slot *next;
  16. struct timeval entered;
  17. struct timeval accumulator;
  18. struct timeval irq;
  19. int     hits;
  20. int     active;
  21. int underflow;
  22. };
  23. extern atomic_t net_profile_active;
  24. extern struct timeval net_profile_adjust;
  25. extern void net_profile_irq_adjust(struct timeval *entered, struct timeval* leaved);
  26. #ifdef CONFIG_X86_TSC
  27. static inline void  net_profile_stamp(struct timeval *pstamp)
  28. {
  29. rdtsc(pstamp->tv_usec, pstamp->tv_sec);
  30. }
  31. static inline void  net_profile_accumulate(struct timeval *entered,
  32.        struct timeval *leaved,
  33.        struct timeval *acc)
  34. {
  35. __asm__ __volatile__ ("subl %2,%0nt" 
  36.       "sbbl %3,%1nt" 
  37.       "addl %4,%0nt" 
  38.       "adcl %5,%1nt" 
  39.       "subl " SYMBOL_NAME_STR(net_profile_adjust) "+4,%0nt" 
  40.       "sbbl $0,%1nt" 
  41.       : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
  42.       : "g" (entered->tv_usec), "g" (entered->tv_sec),
  43.       "g" (leaved->tv_usec), "g" (leaved->tv_sec),
  44.       "0" (acc->tv_usec), "1" (acc->tv_sec));
  45. }
  46. static inline void  net_profile_sub(struct timeval *sub,
  47. struct timeval *acc)
  48. {
  49. __asm__ __volatile__ ("subl %2,%0nt" 
  50.       "sbbl %3,%1nt" 
  51.       : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
  52.       : "g" (sub->tv_usec), "g" (sub->tv_sec),
  53.       "0" (acc->tv_usec), "1" (acc->tv_sec));
  54. }
  55. static inline void  net_profile_add(struct timeval *add,
  56. struct timeval *acc)
  57. {
  58. __asm__ __volatile__ ("addl %2,%0nt" 
  59.       "adcl %3,%1nt" 
  60.       : "=r" (acc->tv_usec), "=r" (acc->tv_sec)
  61.       : "g" (add->tv_usec), "g" (add->tv_sec),
  62.       "0" (acc->tv_usec), "1" (acc->tv_sec));
  63. }
  64. #elif defined (__alpha__)
  65. extern __u32 alpha_lo;
  66. extern long alpha_hi;
  67. /* On alpha cycle counter has only 32 bits :-( :-( */
  68. static inline void  net_profile_stamp(struct timeval *pstamp)
  69. {
  70. __u32 result;
  71. __asm__ __volatile__ ("rpcc %0" : "r="(result));
  72. if (result <= alpha_lo)
  73. alpha_hi++;
  74. alpha_lo = result;
  75. pstamp->tv_sec = alpha_hi;
  76. pstamp->tv_usec = alpha_lo;
  77. }
  78. static inline void  net_profile_accumulate(struct timeval *entered,
  79.        struct timeval *leaved,
  80.        struct timeval *acc)
  81. {
  82. time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec
  83. - net_profile_adjust.tv_usec;
  84. time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec;
  85. if (usecs >= 0x100000000L) {
  86. usecs -= 0x100000000L;
  87. secs++;
  88. } else if (usecs < -0x100000000L) {
  89. usecs += 0x200000000L;
  90. secs -= 2;
  91. } else if (usecs < 0) {
  92. usecs += 0x100000000L;
  93. secs--;
  94. }
  95. acc->tv_sec = secs;
  96. acc->tv_usec = usecs;
  97. }
  98. static inline void  net_profile_sub(struct timeval *entered,
  99. struct timeval *leaved)
  100. {
  101. time_t usecs = leaved->tv_usec - entered->tv_usec;
  102. time_t secs = leaved->tv_sec - entered->tv_sec;
  103. if (usecs < 0) {
  104. usecs += 0x100000000L;
  105. secs--;
  106. }
  107. leaved->tv_sec = secs;
  108. leaved->tv_usec = usecs;
  109. }
  110. static inline void  net_profile_add(struct timeval *entered, struct timeval *leaved)
  111. {
  112. time_t usecs = leaved->tv_usec + entered->tv_usec;
  113. time_t secs = leaved->tv_sec + entered->tv_sec;
  114. if (usecs >= 0x100000000L) {
  115. usecs -= 0x100000000L;
  116. secs++;
  117. }
  118. leaved->tv_sec = secs;
  119. leaved->tv_usec = usecs;
  120. }
  121. #else
  122. static inline void  net_profile_stamp(struct timeval *pstamp)
  123. {
  124. /* Not "fast" counterpart! On architectures without
  125.    cpu clock "fast" routine is absolutely useless in this
  126.    situation. do_gettimeofday still says something on slow-slow-slow
  127.    boxes, though it eats more cpu time than the subject of
  128.    investigation :-) :-)
  129.  */
  130. do_gettimeofday(pstamp);
  131. }
  132. static inline void  net_profile_accumulate(struct timeval *entered,
  133.        struct timeval *leaved,
  134.        struct timeval *acc)
  135. {
  136. time_t usecs = acc->tv_usec + leaved->tv_usec - entered->tv_usec
  137. - net_profile_adjust.tv_usec;
  138. time_t secs = acc->tv_sec + leaved->tv_sec - entered->tv_sec;
  139. if (usecs >= 1000000) {
  140. usecs -= 1000000;
  141. secs++;
  142. } else if (usecs < -1000000) {
  143. usecs += 2000000;
  144. secs -= 2;
  145. } else if (usecs < 0) {
  146. usecs += 1000000;
  147. secs--;
  148. }
  149. acc->tv_sec = secs;
  150. acc->tv_usec = usecs;
  151. }
  152. static inline void  net_profile_sub(struct timeval *entered,
  153. struct timeval *leaved)
  154. {
  155. time_t usecs = leaved->tv_usec - entered->tv_usec;
  156. time_t secs = leaved->tv_sec - entered->tv_sec;
  157. if (usecs < 0) {
  158. usecs += 1000000;
  159. secs--;
  160. }
  161. leaved->tv_sec = secs;
  162. leaved->tv_usec = usecs;
  163. }
  164. static inline void  net_profile_add(struct timeval *entered, struct timeval *leaved)
  165. {
  166. time_t usecs = leaved->tv_usec + entered->tv_usec;
  167. time_t secs = leaved->tv_sec + entered->tv_sec;
  168. if (usecs >= 1000000) {
  169. usecs -= 1000000;
  170. secs++;
  171. }
  172. leaved->tv_sec = secs;
  173. leaved->tv_usec = usecs;
  174. }
  175. #endif
  176. static inline void net_profile_enter(struct net_profile_slot *s)
  177. {
  178. unsigned long flags;
  179. save_flags(flags);
  180. cli();
  181. if (s->active++ == 0) {
  182. net_profile_stamp(&s->entered);
  183. atomic_inc(&net_profile_active);
  184. }
  185. restore_flags(flags);
  186. }
  187. static inline void net_profile_leave_irq(struct net_profile_slot *s)
  188. {
  189. unsigned long flags;
  190. save_flags(flags);
  191. cli();
  192. if (--s->active <= 0) {
  193. if (s->active == 0) {
  194. struct timeval curr_pstamp;
  195. net_profile_stamp(&curr_pstamp);
  196. net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator);
  197. if (!atomic_dec_and_test(&net_profile_active))
  198. net_profile_irq_adjust(&s->entered, &curr_pstamp);
  199. } else {
  200. s->underflow++;
  201. }
  202. }
  203. s->hits++;
  204. restore_flags(flags);
  205. }
  206. static inline void net_profile_leave(struct net_profile_slot *s)
  207. {
  208. unsigned long flags;
  209. save_flags(flags);
  210. cli();
  211. if (--s->active <= 0) {
  212. if (s->active == 0) {
  213. struct timeval curr_pstamp;
  214. net_profile_stamp(&curr_pstamp);
  215. net_profile_accumulate(&s->entered, &curr_pstamp, &s->accumulator);
  216. atomic_dec(&net_profile_active);
  217. } else {
  218. s->underflow++;
  219. }
  220. }
  221. s->hits++;
  222. restore_flags(flags);
  223. }
  224. #define NET_PROFILE_ENTER(slot) net_profile_enter(&net_prof_##slot)
  225. #define NET_PROFILE_LEAVE(slot) net_profile_leave(&net_prof_##slot)
  226. #define NET_PROFILE_LEAVE_IRQ(slot) net_profile_leave_irq(&net_prof_##slot)
  227. #define NET_PROFILE_SKB_CLEAR(skb) ({ 
  228.  skb->pstamp.tv_usec = 0; 
  229. })
  230. #define NET_PROFILE_SKB_INIT(skb) ({ 
  231.  net_profile_stamp(&skb->pstamp); 
  232. })
  233. #define NET_PROFILE_SKB_PASSED(skb, slot) ({ 
  234.  if (skb->pstamp.tv_usec) { 
  235.    struct timeval cur_pstamp = skb->pstamp; 
  236.    net_profile_stamp(&skb->pstamp); 
  237.    net_profile_accumulate(&cur_pstamp, &skb->pstamp, &net_prof_##slot.accumulator); 
  238.    net_prof_##slot.hits++; 
  239.  }})
  240. #define NET_PROFILE_DECL(slot) 
  241.   extern struct net_profile_slot net_prof_##slot;
  242. #define NET_PROFILE_DEFINE(slot) 
  243.   struct net_profile_slot net_prof_##slot = { #slot, };
  244. #define NET_PROFILE_REGISTER(slot) net_profile_register(&net_prof_##slot)
  245. #define NET_PROFILE_UNREGISTER(slot) net_profile_unregister(&net_prof_##slot)
  246. extern int net_profile_init(void);
  247. extern int net_profile_register(struct net_profile_slot *);
  248. extern int net_profile_unregister(struct net_profile_slot *);
  249. #else
  250. #define NET_PROFILE_ENTER(slot) do { /* nothing */ } while(0)
  251. #define NET_PROFILE_LEAVE(slot) do { /* nothing */ } while(0)
  252. #define NET_PROFILE_LEAVE_IRQ(slot) do { /* nothing */ } while(0)
  253. #define NET_PROFILE_SKB_CLEAR(skb) do { /* nothing */ } while(0)
  254. #define NET_PROFILE_SKB_INIT(skb) do { /* nothing */ } while(0)
  255. #define NET_PROFILE_SKB_PASSED(skb, slot) do { /* nothing */ } while(0)
  256. #define NET_PROFILE_DECL(slot)
  257. #define NET_PROFILE_DEFINE(slot)
  258. #define NET_PROFILE_REGISTER(slot) do { /* nothing */ } while(0)
  259. #define NET_PROFILE_UNREGISTER(slot) do { /* nothing */ } while(0)
  260. #endif
  261. #endif