fork download
  1. /*
  2.  * convenient.h
  3.  *
  4.  * A few convenience macros and routines..
  5.  * Mostly for kernel-space usage, some for user-space as well.
  6.  *
  7.  * Author: Kaiwan N Billimoria <kaiwan@kaiwantech.com>
  8.  * (c) Kaiwan NB, kaiwanTECH
  9.  * GPL / LGPL
  10.  *
  11.  */
  12. #ifndef __CONVENIENT_H__
  13. #define __CONVENIENT_H__
  14.  
  15. #include <asm/param.h> /* HZ */
  16. #include <linux/sched.h>
  17.  
  18. #ifdef __KERNEL__
  19. #include <linux/ratelimit.h>
  20.  
  21. /*
  22.   *** Note: PLEASE READ this documentation: ***
  23.  
  24.   We can reduce the load, and increase readability, by using the trace_printk
  25.   instead of printk. To see the o/p do:
  26.   # cat /sys/kernel/debug/tracing/trace
  27.  
  28.   If we insist on using the regular printk, lets at least rate-limit it.
  29. For the programmers' convenience, this too is programatically controlled
  30. (by an integer var USE_RATELIMITING [default: On]).
  31.  
  32.   *** Kernel module authors Note: ***
  33. To use the trace_printk(), pl #define the symbol USE_FTRACE_PRINT in your Makefile:
  34. EXTRA_CFLAGS += -DUSE_FTRACE_PRINT
  35. If you do not do this, we will use the usual printk() .
  36.  
  37. To view :
  38. printk's : dmesg
  39.   trace_printk's : cat /sys/kernel/debug/tracing/trace
  40.  
  41. Default: printk
  42.  */
  43. // keep this defined to use the FTRACE-style trace_printk(), else will use regular printk()
  44. //#define USE_FTRACE_PRINT
  45. //#undef USE_FTRACE_PRINT
  46.  
  47. #ifdef USE_FTRACE_PRINT
  48. #define DBGPRINT(string, args...) \
  49.   trace_printk(string, ##args);
  50. #else
  51. #define DBGPRINT(string, args...) do { \
  52.   int USE_RATELIMITING=0; \
  53. /* Not supposed to use printk_ratelimit() now.. */ \
  54. if (USE_RATELIMITING) { \
  55.   printk_ratelimited (KERN_INFO pr_fmt(string), ##args); \
  56. } \
  57. else \
  58.   pr_info (pr_fmt(string), ##args); \
  59.  } while (0)
  60. #endif
  61.  
  62. /*------------------------ MSG, QP ------------------------------------*/
  63. #ifdef DEBUG
  64. #ifdef __KERNEL__
  65. #define MSG(string, args...) do { \
  66. DBGPRINT("%s:%d : " string, __FUNCTION__, __LINE__, ##args); \
  67. } while (0)
  68. #else
  69. #define MSG(string, args...) do { \
  70. fprintf(stderr, "%s:%d : " string, __FUNCTION__, __LINE__, ##args); \
  71. } while (0)
  72. #endif
  73.  
  74. #ifdef __KERNEL__
  75. #define MSG_SHORT(string, args...) do { \
  76. DBGPRINT(string, ##args); \
  77. } while (0)
  78. #else
  79. #define MSG_SHORT(string, args...) do { \
  80. fprintf(stderr, string, ##args); \
  81. } while (0)
  82. #endif
  83.  
  84. // QP = Quick Print
  85. #define QP MSG("\n")
  86.  
  87. #ifdef __KERNEL__
  88. #define QPDS do { \
  89. MSG("\n"); \
  90. dump_stack(); \
  91. } while(0)
  92. #endif
  93.  
  94. #ifdef __KERNEL__
  95. #define HexDump(from_addr, len) \
  96.   print_hex_dump_bytes (" ", DUMP_PREFIX_ADDRESS, from_addr, len);
  97. #endif
  98. #else
  99. #define MSG(string, args...)
  100. #define MSG_SHORT(string, args...)
  101. #define QP
  102. #define QPDS
  103. #endif
  104.  
  105. /*------------------------ PRINT_CTX ---------------------------------*/
  106. /*
  107.  An interesting way to print the context info:
  108.  If USE_FTRACE_PRINT is On, it implies we'll use trace_printk(), else the vanilla
  109.  printk().
  110.  If we are using trace_printk(), we will automatically get output in the ftrace
  111.  latency format (see below):
  112.  
  113.  * The Ftrace 'latency-format' :
  114.   _-----=> irqs-off [d]
  115.   / _----=> need-resched [N]
  116.   | / _---=> hardirq/softirq [H|h|s] H=>both h && s
  117.   || / _--=> preempt-depth [#]
  118.   ||| /
  119.  CPU TASK/PID |||| DURATION FUNCTION CALLS
  120.  | | | |||| | | | | | |
  121.  
  122.  However, if we're _not_ using ftrace trace_printk(), then we'll _emulate_ the same
  123.  with the printk() !
  124.  (Of course, without the 'Duration' and 'Function Calls' fields).
  125.  */
  126. #include <linux/sched.h>
  127. #include <linux/interrupt.h>
  128.  
  129. #ifndef USE_FTRACE_PRINT // 'normal' printk(), lets emulate ftrace latency format
  130. #define PRINT_CTX() do { \
  131. char sep='|', intr='.'; \
  132. \
  133.   if (in_interrupt()) { \
  134.   if (in_irq() && in_softirq()) \
  135. intr='H'; \
  136. else if (in_irq()) \
  137. intr='h'; \
  138. else if (in_softirq()) \
  139. intr='s'; \
  140. } \
  141.   else \
  142. intr='.'; \
  143. \
  144. DBGPRINT( \
  145. "PRINT_CTX:: [%03d]%c%s%c:%d %c " \
  146. "%c%c%c%u " \
  147. "\n" \
  148. , smp_processor_id(), \
  149.   (!current->mm?'[':' '), current->comm, (!current->mm?']':' '), current->pid, sep, \
  150. (irqs_disabled()?'d':'.'), \
  151. (need_resched()?'N':'.'), \
  152. intr, \
  153. (preempt_count() && 0xff) \
  154. ); \
  155. } while (0)
  156. #else // using ftrace trace_prink() internally
  157. #define PRINT_CTX() do { \
  158. DBGPRINT("PRINT_CTX:: [cpu %02d]%s:%d\n", smp_processor_id(), __func__, current->pid); \
  159. if (!in_interrupt()) { \
  160.   DBGPRINT(" in process context:%c%s%c:%d\n", \
  161. (!current->mm?'[':' '), current->comm, (!current->mm?']':' '), current->pid); \
  162. } else { \
  163.   DBGPRINT(" in interrupt context: in_interrupt:%3s. in_irq:%3s. in_softirq:%3s. " \
  164. "in_serving_softirq:%3s. preempt_count=0x%x\n", \
  165.   (in_interrupt()?"yes":"no"), (in_irq()?"yes":"no"), (in_softirq()?"yes":"no"), \
  166.   (in_serving_softirq()?"yes":"no"), (preempt_count() && 0xff)); \
  167. } \
  168. } while (0)
  169. #endif
  170. #endif // end ifdef __KERNEL__ at the top
  171.  
  172. /*------------------------ assert ---------------------------------------
  173.  * Hey you, careful!
  174.  * Using assertions is great *but* pl be aware of traps & pitfalls:
  175.  * http://b...content-available-to-author-only...r.org/archives/1096
  176.  *
  177.  * The closest equivalent perhaps, to assert() in the kernel are the BUG()
  178.  * or BUG_ON() and WARN() or WARN_ON() macros. Using BUG*() is _only_ for those
  179.  * cases where recovery is impossible. WARN*() is usally considered a better
  180.  * option. Pl see <asm-generic/bug.h> for details.
  181.  *
  182.  * Here, we just trivially emit a noisy [trace_]printk() to "warn" the dev/user.
  183.  */
  184. #ifdef __KERNEL__
  185. #define assert(expr) do { \
  186.  if (!(expr)) { \
  187.   DBGPRINT("********** Assertion [%s] failed! : %s:%s:%d **********\n", \
  188.   #expr, __FILE__, __func__, __LINE__); \
  189.  } \
  190. } while(0)
  191. #endif
  192.  
  193. /*------------------------ DELAY_LOOP --------------------------------*/
  194. static inline void beep(int what)
  195. {
  196. #ifdef __KERNEL__
  197. DBGPRINT("%c", (char)what);
  198. #else
  199. (void)printf("%c", (char)what);
  200. #endif
  201. }
  202.  
  203. /*
  204.  * DELAY_LOOP macro
  205.  * @val : ASCII value to print
  206.  * @loop_count : times to loop around
  207.  */
  208. #define DELAY_LOOP(val,loop_count) \
  209. { \
  210. int c=0, m;\
  211. unsigned int for_index,inner_index; \
  212. \
  213. for(for_index=0;for_index<loop_count;for_index++) { \
  214. beep((val)); \
  215. c++;\
  216. for(inner_index=0;inner_index<HZ*1000*8;inner_index++) \
  217. for(m=0;m<50;m++); \
  218. } \
  219. /*printf("c=%d\n",c);*/\
  220. }
  221. /*------------------------------------------------------------------------*/
  222.  
  223. #ifdef __KERNEL__
  224. /*------------ DELAY_SEC -------------------------*
  225.  * Delays execution for n seconds.
  226.  * MUST be called from process context.
  227.  *------------------------------------------------*/
  228. #define DELAY_SEC(val) \
  229. { \
  230. if (!in_interrupt()) { \
  231. set_current_state (TASK_INTERRUPTIBLE); \
  232. schedule_timeout (val * HZ); \
  233. } \
  234. }
  235. #endif
  236.  
  237. /* Get time difference between two struct timeval's
  238.  * Credits: Arkaitz Jimenez
  239.  * http://stackoverflow.com/questions/1444428/time-stamp-in-the-c-programming-language
  240.  */
  241. static int timeval_subtract(struct timeval *result, struct timeval *x,
  242. struct timeval *y);
  243. /* Subtract the `struct timeval' values X and Y,
  244.   storing the result in RESULT.
  245.   Return 1 if the difference is negative, otherwise 0. */
  246. __attribute__ ((unused))
  247. int timeval_subtract(struct timeval *result, struct timeval *x,
  248. struct timeval *y)
  249. {
  250. /* Perform the carry for the later subtraction by updating y. */
  251. if (x->tv_usec < y->tv_usec) {
  252. int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
  253. y->tv_usec -= 1000000 * nsec;
  254. y->tv_sec += nsec;
  255. }
  256. if (x->tv_usec - y->tv_usec > 1000000) {
  257. int nsec = (x->tv_usec - y->tv_usec) / 1000000;
  258. y->tv_usec += 1000000 * nsec;
  259. y->tv_sec -= nsec;
  260. }
  261.  
  262. /* Compute the time remaining to wait.
  263. tv_usec is certainly positive. */
  264. result->tv_sec = x->tv_sec - y->tv_sec;
  265. result->tv_usec = x->tv_usec - y->tv_usec;
  266.  
  267. /* Return 1 if result is negative. */
  268. return x->tv_sec < y->tv_sec;
  269. }
  270.  
  271. /*
  272.  * Converts decimal to binary.
  273.  * Credits: vegaseat. URL: http://w...content-available-to-author-only...b.com/software-development/c/code/216349
  274.  * accepts a decimal integer and returns a binary coded string
  275.  *
  276.  * @decimal : decimal value to convert to binary (IN)
  277.  * @binary : the binary result as a string (OUT)
  278.  *
  279.  */
  280. __attribute__ ((unused))
  281. static void dec2bin(long decimal, char *binary)
  282. {
  283. int k = 0, n = 0;
  284. int neg_flag = 0;
  285. int remain;
  286. /*
  287. gcc 4.6.3 : we get the warning:
  288. "warning: variable ‘old_decimal’ set but not used [-Wunused-but-set-variable]"
  289. To get rid of this warning, have #ifdef'd the test... -kaiwan.
  290.  
  291. Keep one of the following below (wrt TESTMODE); comment out the other.
  292. UN-defining by default.
  293. */
  294. //#define TESTMODE
  295. #undef TESTMODE
  296.  
  297. #ifdef TESTMODE
  298. int old_decimal; // for test
  299. #endif
  300. char temp[80];
  301.  
  302. // take care of negative input
  303. if (decimal < 0) {
  304. decimal = -decimal;
  305. neg_flag = 1;
  306. }
  307. do {
  308. #ifdef TESTMODE
  309. old_decimal = decimal; // for test
  310. #endif
  311. remain = decimal % 2;
  312. // whittle down the decimal number
  313. decimal = decimal / 2;
  314. // this is a test to show the action
  315. #ifdef TESTMODE
  316. printf("%d/2 = %d remainder = %d\n", old_decimal, decimal,
  317. remain);
  318. #endif
  319. // converts digit 0 or 1 to character '0' or '1'
  320. temp[k++] = remain + '0';
  321. } while (decimal > 0);
  322.  
  323. if (neg_flag)
  324. temp[k++] = '-'; // add - sign
  325. else
  326. temp[k++] = ' '; // space
  327.  
  328. // reverse the spelling
  329. while (k >= 0)
  330. binary[n++] = temp[--k];
  331.  
  332. binary[n - 1] = 0; // end with NULL
  333. }
  334.  
  335. #ifndef __KERNEL__
  336.  
  337. #define MSG(string, args...) do { \
  338. fprintf(stderr, "%s:%d : " string, __FUNCTION__, __LINE__, ##args); \
  339. } while (0)
  340.  
  341. #define MSG_SHORT(string, args...) do { \
  342. fprintf(stderr, string, ##args); \
  343. } while (0)
  344.  
  345. #define QP MSG("\n")
  346.  
  347. /* Verbose printf ... */
  348. #define VP(verbose, str, args...) \
  349. do { \
  350. if (verbose) \
  351. printf(str, ##args); \
  352. } while (0)
  353.  
  354. static inline int err_exit(char *prg, char *err, int exitcode)
  355. {
  356. char err_str[512];
  357.  
  358. snprintf(err_str, 511, "%s: %s", prg, err);
  359. perror(err_str);
  360. exit(exitcode);
  361. } // err_exit()
  362.  
  363. #endif
  364.  
  365. #endif
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c: In function 'beep':
prog.c:199:8: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
  (void)printf("%c", (char)what);
        ^
prog.c:199:8: warning: incompatible implicit declaration of built-in function 'printf'
prog.c:199:8: note: include '<stdio.h>' or provide a declaration of 'printf'
prog.c: At top level:
prog.c:242:15: warning: 'struct timeval' declared inside parameter list
        struct timeval *y);
               ^
prog.c:242:15: warning: its scope is only this definition or declaration, which is probably not what you want
prog.c:248:15: warning: 'struct timeval' declared inside parameter list
        struct timeval *y)
               ^
prog.c:247:5: error: conflicting types for 'timeval_subtract'
 int timeval_subtract(struct timeval *result, struct timeval *x,
     ^
prog.c:241:12: note: previous declaration of 'timeval_subtract' was here
 static int timeval_subtract(struct timeval *result, struct timeval *x,
            ^
prog.c: In function 'timeval_subtract':
prog.c:251:7: error: dereferencing pointer to incomplete type 'struct timeval'
  if (x->tv_usec < y->tv_usec) {
       ^
prog.c: In function 'err_exit':
prog.c:358:2: warning: implicit declaration of function 'snprintf' [-Wimplicit-function-declaration]
  snprintf(err_str, 511, "%s: %s", prg, err);
  ^
prog.c:358:2: warning: incompatible implicit declaration of built-in function 'snprintf'
prog.c:358:2: note: include '<stdio.h>' or provide a declaration of 'snprintf'
prog.c:359:2: warning: implicit declaration of function 'perror' [-Wimplicit-function-declaration]
  perror(err_str);
  ^
prog.c:360:2: warning: implicit declaration of function 'exit' [-Wimplicit-function-declaration]
  exit(exitcode);
  ^
prog.c:360:2: warning: incompatible implicit declaration of built-in function 'exit'
prog.c:360:2: note: include '<stdlib.h>' or provide a declaration of 'exit'
prog.c: In function 'timeval_subtract':
prog.c:269:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
stdout
Standard output is empty