Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 102430
b: refs/heads/master
c: c890398
h: refs/heads/master
v: v3
  • Loading branch information
Allan Stephens authored and David S. Miller committed May 5, 2008
1 parent 5fe9e26 commit c3384cc
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 95 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 40dbfae440abe6860167f12e0296bd7a1a599839
refs/heads/master: c89039850bdf8047472b4ee6132048dacef2cf5a
7 changes: 4 additions & 3 deletions trunk/net/tipc/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@

struct tipc_msg;
extern struct print_buf *TIPC_NULL, *TIPC_CONS, *TIPC_LOG;
extern struct print_buf *TIPC_TEE(struct print_buf *, struct print_buf *);
void tipc_msg_print(struct print_buf*,struct tipc_msg *,const char*);
void tipc_printf(struct print_buf *, const char *fmt, ...);
void tipc_dump(struct print_buf*,const char *fmt, ...);
Expand Down Expand Up @@ -98,11 +97,13 @@ void tipc_dump(struct print_buf*,const char *fmt, ...);
* TIPC_CONS : system console
* TIPC_LOG : TIPC log buffer
* &buf : user-defined buffer (struct print_buf *)
* TIPC_TEE(&buf_a,&buf_b) : list of buffers (eg. TIPC_TEE(TIPC_CONS,TIPC_LOG))
*
* Note: TIPC_LOG is configured to echo its output to the system console;
* user-defined buffers can be configured to do the same thing.
*/

#ifndef TIPC_OUTPUT
#define TIPC_OUTPUT TIPC_TEE(TIPC_CONS,TIPC_LOG)
#define TIPC_OUTPUT TIPC_LOG
#endif

#ifndef DBG_OUTPUT
Expand Down
163 changes: 74 additions & 89 deletions trunk/net/tipc/dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,44 @@
#include "config.h"
#include "dbg.h"

static char print_string[TIPC_PB_MAX_STR];
static DEFINE_SPINLOCK(print_lock);
/*
* TIPC pre-defines the following print buffers:
*
* TIPC_NULL : null buffer (i.e. print nowhere)
* TIPC_CONS : system console
* TIPC_LOG : TIPC log buffer
*
* Additional user-defined print buffers are also permitted.
*/

static struct print_buf null_buf = { NULL, 0, NULL, NULL };
static struct print_buf null_buf = { NULL, 0, NULL, 0 };
struct print_buf *TIPC_NULL = &null_buf;

static struct print_buf cons_buf = { NULL, 0, NULL, NULL };
static struct print_buf cons_buf = { NULL, 0, NULL, 1 };
struct print_buf *TIPC_CONS = &cons_buf;

static struct print_buf log_buf = { NULL, 0, NULL, NULL };
static struct print_buf log_buf = { NULL, 0, NULL, 1 };
struct print_buf *TIPC_LOG = &log_buf;

/*
* Locking policy when using print buffers.
*
* 1) tipc_printf() uses 'print_lock' to protect against concurrent access to
* 'print_string' when writing to a print buffer. This also protects against
* concurrent writes to the print buffer being written to.
*
* 2) tipc_dump() and tipc_log_XXX() leverage the aforementioned
* use of 'print_lock' to protect against all types of concurrent operations
* on their associated print buffer (not just write operations).
*
* Note: All routines of the form tipc_printbuf_XXX() are lock-free, and rely
* on the caller to prevent simultaneous use of the print buffer(s) being
* manipulated.
*/

static char print_string[TIPC_PB_MAX_STR];
static DEFINE_SPINLOCK(print_lock);


#define FORMAT(PTR,LEN,FMT) \
{\
Expand All @@ -60,35 +86,22 @@ struct print_buf *TIPC_LOG = &log_buf;
*(PTR + LEN) = '\0';\
}

/*
* Locking policy when using print buffers.
*
* The following routines use 'print_lock' for protection:
* 1) tipc_printf() - to protect its print buffer(s) and 'print_string'
* 2) TIPC_TEE() - to protect its print buffer(s)
* 3) tipc_dump() - to protect its print buffer(s) and 'print_string'
* 4) tipc_log_XXX() - to protect TIPC_LOG
*
* All routines of the form tipc_printbuf_XXX() rely on the caller to prevent
* simultaneous use of the print buffer(s) being manipulated.
*/

/**
* tipc_printbuf_init - initialize print buffer to empty
* @pb: pointer to print buffer structure
* @raw: pointer to character array used by print buffer
* @size: size of character array
*
* Makes the print buffer a null device that discards anything written to it
* if the character array is too small (or absent).
* Note: If the character array is too small (or absent), the print buffer
* becomes a null device that discards anything written to it.
*/

void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)
{
pb->buf = raw;
pb->crs = raw;
pb->size = size;
pb->next = NULL;
pb->echo = 0;

if (size < TIPC_PB_MIN_SIZE) {
pb->buf = NULL;
Expand All @@ -105,7 +118,11 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size)

void tipc_printbuf_reset(struct print_buf *pb)
{
tipc_printbuf_init(pb, pb->buf, pb->size);
if (pb->buf != NULL) {
pb->crs = pb->buf;
pb->buf[0] = 0;
pb->buf[pb->size - 1] = ~0;
}
}

/**
Expand Down Expand Up @@ -182,7 +199,6 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
strcpy(pb_to->buf, "*** PRINT BUFFER MOVE ERROR ***");
pb_to->buf[pb_to->size - 1] = ~0;
pb_to->crs = strchr(pb_to->buf, 0);
pb_to->next = NULL;
return;
}

Expand All @@ -205,8 +221,8 @@ void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from)
}

/**
* tipc_printf - append formatted output to print buffer chain
* @pb: pointer to chain of print buffers (may be NULL)
* tipc_printf - append formatted output to print buffer
* @pb: pointer to print buffer
* @fmt: formatted info to be printed
*/

Expand All @@ -215,66 +231,36 @@ void tipc_printf(struct print_buf *pb, const char *fmt, ...)
int chars_to_add;
int chars_left;
char save_char;
struct print_buf *pb_next;

spin_lock_bh(&print_lock);

FORMAT(print_string, chars_to_add, fmt);
if (chars_to_add >= TIPC_PB_MAX_STR)
strcpy(print_string, "*** PRINT BUFFER STRING TOO LONG ***");

while (pb) {
if (pb == TIPC_CONS)
printk(print_string);
else if (pb->buf) {
chars_left = pb->buf + pb->size - pb->crs - 1;
if (chars_to_add <= chars_left) {
strcpy(pb->crs, print_string);
pb->crs += chars_to_add;
} else if (chars_to_add >= (pb->size - 1)) {
strcpy(pb->buf, print_string + chars_to_add + 1
- pb->size);
pb->crs = pb->buf + pb->size - 1;
} else {
strcpy(pb->buf, print_string + chars_left);
save_char = print_string[chars_left];
print_string[chars_left] = 0;
strcpy(pb->crs, print_string);
print_string[chars_left] = save_char;
pb->crs = pb->buf + chars_to_add - chars_left;
}
if (pb->buf) {
chars_left = pb->buf + pb->size - pb->crs - 1;
if (chars_to_add <= chars_left) {
strcpy(pb->crs, print_string);
pb->crs += chars_to_add;
} else if (chars_to_add >= (pb->size - 1)) {
strcpy(pb->buf, print_string + chars_to_add + 1
- pb->size);
pb->crs = pb->buf + pb->size - 1;
} else {
strcpy(pb->buf, print_string + chars_left);
save_char = print_string[chars_left];
print_string[chars_left] = 0;
strcpy(pb->crs, print_string);
print_string[chars_left] = save_char;
pb->crs = pb->buf + chars_to_add - chars_left;
}
pb_next = pb->next;
pb->next = NULL;
pb = pb_next;
}
spin_unlock_bh(&print_lock);
}

/**
* TIPC_TEE - perform next output operation on both print buffers
* @b0: pointer to chain of print buffers (may be NULL)
* @b1: pointer to print buffer to add to chain
*
* Returns pointer to print buffer chain.
*/

struct print_buf *TIPC_TEE(struct print_buf *b0, struct print_buf *b1)
{
struct print_buf *pb = b0;
if (pb->echo)
printk(print_string);

if (!b0 || (b0 == b1))
return b1;

spin_lock_bh(&print_lock);
while (pb->next) {
if ((pb->next == b1) || (pb->next == b0))
pb->next = pb->next->next;
else
pb = pb->next;
}
pb->next = b1;
spin_unlock_bh(&print_lock);
return b0;
}

/**
Expand Down Expand Up @@ -323,31 +309,28 @@ static void printbuf_dump(struct print_buf *pb)
}

/**
* tipc_dump - dump non-console print buffer(s) to console
* @pb: pointer to chain of print buffers
* tipc_dump - dump (non-console) print buffer to console
* @pb: pointer to print buffer
*/

void tipc_dump(struct print_buf *pb, const char *fmt, ...)
{
struct print_buf *pb_next;
int len;

if (pb == TIPC_CONS)
return;

spin_lock_bh(&print_lock);

FORMAT(print_string, len, fmt);
printk(print_string);

for (; pb; pb = pb->next) {
if (pb != TIPC_CONS) {
printk("\n---- Start of %s log dump ----\n\n",
(pb == TIPC_LOG) ? "global" : "local");
printbuf_dump(pb);
tipc_printbuf_reset(pb);
printk("\n---- End of dump ----\n");
}
pb_next = pb->next;
pb->next = NULL;
pb = pb_next;
}
printk("\n---- Start of %s log dump ----\n\n",
(pb == TIPC_LOG) ? "global" : "local");
printbuf_dump(pb);
tipc_printbuf_reset(pb);
printk("\n---- End of dump ----\n");

spin_unlock_bh(&print_lock);
}

Expand All @@ -368,8 +351,10 @@ int tipc_log_resize(int log_size)
if (log_size) {
if (log_size < TIPC_PB_MIN_SIZE)
log_size = TIPC_PB_MIN_SIZE;
res = TIPC_LOG->echo;
tipc_printbuf_init(TIPC_LOG, kmalloc(log_size, GFP_ATOMIC),
log_size);
TIPC_LOG->echo = res;
res = !TIPC_LOG->buf;
}
spin_unlock_bh(&print_lock);
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/tipc/dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@
* @buf: pointer to character array containing print buffer contents
* @size: size of character array
* @crs: pointer to first unused space in character array (i.e. final NUL)
* @next: used to link print buffers when printing to more than one at a time
* @echo: echo output to system console if non-zero
*/

struct print_buf {
char *buf;
u32 size;
char *crs;
struct print_buf *next;
int echo;
};

#define TIPC_PB_MIN_SIZE 64 /* minimum size for a print buffer's array */
Expand Down

0 comments on commit c3384cc

Please sign in to comment.