Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

scbuf.c

00001 #ifndef _SCBUF_C_ /* -*- linux-c -*- */
00002 #define _SCBUF_C_
00003 
00004 #include <linux/config.h>
00005 
00006 /** @file scbuf.c
00007  * @addtogroup scbuf Scratch Buffer
00008  * Scratch Buffer Functions.
00009  * The scratch buffer is for collecting output before storing in a map,
00010  * printing, etc. This is a per-cpu static buffer.  It is necessary because 
00011  * of the limited stack space available in the kernel.
00012  * @todo Need careful review of these to insure safety.
00013  * @{
00014  */
00015 
00016 /** Maximum size of buffer, not including terminating NULL */
00017 #define STP_BUF_LEN 8191
00018 
00019 /** Scratch buffer for printing, building strings, etc */
00020 static char _stp_scbuf[NR_CPUS][STP_BUF_LEN+1];
00021 static int _stp_scbuf_len[NR_CPUS];
00022 
00023 /** Sprint into the scratch buffer.
00024  * Like printf, except output goes into a global scratch buffer
00025  * which will contain the null-terminated output.
00026  * Safe because overflowing the buffer is not allowed.
00027  * Size is limited by length of scratch buffer, STP_BUF_LEN.
00028  *
00029  * @param fmt A printf-style format string followed by a 
00030  * variable number of args.
00031  * @sa _stp_scbuf_clear
00032  */
00033 
00034 void _stp_sprint (const char *fmt, ...)
00035 {
00036         int num;
00037         va_list args;
00038         int cpu = smp_processor_id();
00039         char *buf = _stp_scbuf[cpu] + STP_BUF_LEN - _stp_scbuf_len[cpu];
00040         va_start(args, fmt);
00041         num = vscnprintf(buf, _stp_scbuf_len[cpu], fmt, args);
00042         va_end(args);
00043         if (num > 0)
00044                 _stp_scbuf_len[cpu] -= num;
00045 }
00046 
00047 /** Write a string into the scratch buffer.
00048  * Copies a string into a global scratch buffer.
00049  * Safe because overflowing the buffer is not allowed.
00050  * Size is limited by length of scratch buffer, STP_BUF_LEN.
00051  * This is more efficient than using _stp_sprint().
00052  *
00053  * @param str A string.
00054  */
00055 
00056 void _stp_sprint_str (const char *str)
00057 {
00058         int cpu = smp_processor_id();
00059         char *buf = _stp_scbuf[cpu] + STP_BUF_LEN - _stp_scbuf_len[cpu];
00060         int num = strlen (str);
00061         if (num > _stp_scbuf_len[cpu])
00062                 num = _stp_scbuf_len[cpu];
00063         strncpy (buf, str, num);
00064         _stp_scbuf_len[cpu] -= num;
00065 }
00066 
00067 /** Clear the scratch buffer.
00068  * This function should be called before anything is written to 
00069  * the scratch buffer.  Output will accumulate in the buffer
00070  * until this function is called again.  
00071  * @returns A pointer to the buffer.
00072  */
00073 
00074 char *_stp_scbuf_clear (void)
00075 {
00076         int cpu = smp_processor_id();
00077         _stp_scbuf_len[cpu] = STP_BUF_LEN;
00078         *_stp_scbuf[cpu] = 0;
00079         return _stp_scbuf[cpu];
00080 }
00081 
00082 /** Get the current top of the scratch buffer.
00083  * This returns the address of the location where
00084  * data will be written next in the scratch buffer.
00085  * @returns A pointer
00086  */
00087 
00088 static char *_stp_scbuf_cur (void)
00089 {
00090         int cpu = smp_processor_id();
00091         return _stp_scbuf[cpu] + STP_BUF_LEN - _stp_scbuf_len[cpu];
00092 }
00093 
00094 /** @} */
00095 #endif /* _SCBUF_C_ */