aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@kernel.org>2016-05-10 01:46:58 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-05-10 10:27:58 -0400
commit5cea57f30a12443c05e0c5273f35d2fcef00d30a (patch)
treeba665d63c69cc0ea73c0d6e8d622a4872c3a2b6e
parent9c7b37cd63d0d910c531233209286f169993cbd9 (diff)
perf tools: Rewrite strbuf not to die()
Rewrite strbuf implementation not to use die() nor xrealloc(). Instead of die(), now most of the API returns error code or 0 if succeeded. Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20160510054658.6158.24080.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/strbuf.c93
-rw-r--r--tools/perf/util/strbuf.h25
2 files changed, 82 insertions, 36 deletions
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c
index 8fb73295ec34..f95f682aa2b2 100644
--- a/tools/perf/util/strbuf.c
+++ b/tools/perf/util/strbuf.c
@@ -1,3 +1,4 @@
1#include "debug.h"
1#include "cache.h" 2#include "cache.h"
2#include <linux/kernel.h> 3#include <linux/kernel.h>
3 4
@@ -17,12 +18,13 @@ int prefixcmp(const char *str, const char *prefix)
17 */ 18 */
18char strbuf_slopbuf[1]; 19char strbuf_slopbuf[1];
19 20
20void strbuf_init(struct strbuf *sb, ssize_t hint) 21int strbuf_init(struct strbuf *sb, ssize_t hint)
21{ 22{
22 sb->alloc = sb->len = 0; 23 sb->alloc = sb->len = 0;
23 sb->buf = strbuf_slopbuf; 24 sb->buf = strbuf_slopbuf;
24 if (hint) 25 if (hint)
25 strbuf_grow(sb, hint); 26 return strbuf_grow(sb, hint);
27 return 0;
26} 28}
27 29
28void strbuf_release(struct strbuf *sb) 30void strbuf_release(struct strbuf *sb)
@@ -42,67 +44,104 @@ char *strbuf_detach(struct strbuf *sb, size_t *sz)
42 return res; 44 return res;
43} 45}
44 46
45void strbuf_grow(struct strbuf *sb, size_t extra) 47int strbuf_grow(struct strbuf *sb, size_t extra)
46{ 48{
47 if (sb->len + extra + 1 <= sb->len) 49 char *buf;
48 die("you want to use way too much memory"); 50 size_t nr = sb->len + extra + 1;
49 if (!sb->alloc) 51
50 sb->buf = NULL; 52 if (nr < sb->alloc)
51 ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); 53 return 0;
54
55 if (nr <= sb->len)
56 return -E2BIG;
57
58 if (alloc_nr(sb->alloc) > nr)
59 nr = alloc_nr(sb->alloc);
60
61 /*
62 * Note that sb->buf == strbuf_slopbuf if sb->alloc == 0, and it is
63 * a static variable. Thus we have to avoid passing it to realloc.
64 */
65 buf = realloc(sb->alloc ? sb->buf : NULL, nr * sizeof(*buf));
66 if (!buf)
67 return -ENOMEM;
68
69 sb->buf = buf;
70 sb->alloc = nr;
71 return 0;
52} 72}
53 73
54void strbuf_addch(struct strbuf *sb, int c) 74int strbuf_addch(struct strbuf *sb, int c)
55{ 75{
56 strbuf_grow(sb, 1); 76 int ret = strbuf_grow(sb, 1);
77 if (ret)
78 return ret;
79
57 sb->buf[sb->len++] = c; 80 sb->buf[sb->len++] = c;
58 sb->buf[sb->len] = '\0'; 81 sb->buf[sb->len] = '\0';
82 return 0;
59} 83}
60 84
61void strbuf_add(struct strbuf *sb, const void *data, size_t len) 85int strbuf_add(struct strbuf *sb, const void *data, size_t len)
62{ 86{
63 strbuf_grow(sb, len); 87 int ret = strbuf_grow(sb, len);
88 if (ret)
89 return ret;
90
64 memcpy(sb->buf + sb->len, data, len); 91 memcpy(sb->buf + sb->len, data, len);
65 strbuf_setlen(sb, sb->len + len); 92 return strbuf_setlen(sb, sb->len + len);
66} 93}
67 94
68static void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap) 95static int strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap)
69{ 96{
70 int len; 97 int len, ret;
71 va_list ap_saved; 98 va_list ap_saved;
72 99
73 if (!strbuf_avail(sb)) 100 if (!strbuf_avail(sb)) {
74 strbuf_grow(sb, 64); 101 ret = strbuf_grow(sb, 64);
102 if (ret)
103 return ret;
104 }
75 105
76 va_copy(ap_saved, ap); 106 va_copy(ap_saved, ap);
77 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); 107 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
78 if (len < 0) 108 if (len < 0)
79 die("your vsnprintf is broken"); 109 return len;
80 if (len > strbuf_avail(sb)) { 110 if (len > strbuf_avail(sb)) {
81 strbuf_grow(sb, len); 111 ret = strbuf_grow(sb, len);
112 if (ret)
113 return ret;
82 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved); 114 len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap_saved);
83 va_end(ap_saved); 115 va_end(ap_saved);
84 if (len > strbuf_avail(sb)) { 116 if (len > strbuf_avail(sb)) {
85 die("this should not happen, your vsnprintf is broken"); 117 pr_debug("this should not happen, your vsnprintf is broken");
118 return -EINVAL;
86 } 119 }
87 } 120 }
88 strbuf_setlen(sb, sb->len + len); 121 return strbuf_setlen(sb, sb->len + len);
89} 122}
90 123
91void strbuf_addf(struct strbuf *sb, const char *fmt, ...) 124int strbuf_addf(struct strbuf *sb, const char *fmt, ...)
92{ 125{
93 va_list ap; 126 va_list ap;
127 int ret;
94 128
95 va_start(ap, fmt); 129 va_start(ap, fmt);
96 strbuf_addv(sb, fmt, ap); 130 ret = strbuf_addv(sb, fmt, ap);
97 va_end(ap); 131 va_end(ap);
132 return ret;
98} 133}
99 134
100ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint) 135ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
101{ 136{
102 size_t oldlen = sb->len; 137 size_t oldlen = sb->len;
103 size_t oldalloc = sb->alloc; 138 size_t oldalloc = sb->alloc;
139 int ret;
140
141 ret = strbuf_grow(sb, hint ? hint : 8192);
142 if (ret)
143 return ret;
104 144
105 strbuf_grow(sb, hint ? hint : 8192);
106 for (;;) { 145 for (;;) {
107 ssize_t cnt; 146 ssize_t cnt;
108 147
@@ -112,12 +151,14 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint)
112 strbuf_release(sb); 151 strbuf_release(sb);
113 else 152 else
114 strbuf_setlen(sb, oldlen); 153 strbuf_setlen(sb, oldlen);
115 return -1; 154 return cnt;
116 } 155 }
117 if (!cnt) 156 if (!cnt)
118 break; 157 break;
119 sb->len += cnt; 158 sb->len += cnt;
120 strbuf_grow(sb, 8192); 159 ret = strbuf_grow(sb, 8192);
160 if (ret)
161 return ret;
121 } 162 }
122 163
123 sb->buf[sb->len] = '\0'; 164 sb->buf[sb->len] = '\0';
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h
index ab9be0fbbd40..54b409297d4a 100644
--- a/tools/perf/util/strbuf.h
+++ b/tools/perf/util/strbuf.h
@@ -51,7 +51,7 @@ struct strbuf {
51#define STRBUF_INIT { 0, 0, strbuf_slopbuf } 51#define STRBUF_INIT { 0, 0, strbuf_slopbuf }
52 52
53/*----- strbuf life cycle -----*/ 53/*----- strbuf life cycle -----*/
54void strbuf_init(struct strbuf *buf, ssize_t hint); 54int strbuf_init(struct strbuf *buf, ssize_t hint);
55void strbuf_release(struct strbuf *buf); 55void strbuf_release(struct strbuf *buf);
56char *strbuf_detach(struct strbuf *buf, size_t *); 56char *strbuf_detach(struct strbuf *buf, size_t *);
57 57
@@ -60,26 +60,31 @@ static inline ssize_t strbuf_avail(const struct strbuf *sb) {
60 return sb->alloc ? sb->alloc - sb->len - 1 : 0; 60 return sb->alloc ? sb->alloc - sb->len - 1 : 0;
61} 61}
62 62
63void strbuf_grow(struct strbuf *buf, size_t); 63int strbuf_grow(struct strbuf *buf, size_t);
64 64
65static inline void strbuf_setlen(struct strbuf *sb, size_t len) { 65static inline int strbuf_setlen(struct strbuf *sb, size_t len) {
66 if (!sb->alloc) 66 int ret;
67 strbuf_grow(sb, 0); 67 if (!sb->alloc) {
68 ret = strbuf_grow(sb, 0);
69 if (ret)
70 return ret;
71 }
68 assert(len < sb->alloc); 72 assert(len < sb->alloc);
69 sb->len = len; 73 sb->len = len;
70 sb->buf[len] = '\0'; 74 sb->buf[len] = '\0';
75 return 0;
71} 76}
72 77
73/*----- add data in your buffer -----*/ 78/*----- add data in your buffer -----*/
74void strbuf_addch(struct strbuf *sb, int c); 79int strbuf_addch(struct strbuf *sb, int c);
75 80
76void strbuf_add(struct strbuf *buf, const void *, size_t); 81int strbuf_add(struct strbuf *buf, const void *, size_t);
77static inline void strbuf_addstr(struct strbuf *sb, const char *s) { 82static inline int strbuf_addstr(struct strbuf *sb, const char *s) {
78 strbuf_add(sb, s, strlen(s)); 83 return strbuf_add(sb, s, strlen(s));
79} 84}
80 85
81__attribute__((format(printf,2,3))) 86__attribute__((format(printf,2,3)))
82void strbuf_addf(struct strbuf *sb, const char *fmt, ...); 87int strbuf_addf(struct strbuf *sb, const char *fmt, ...);
83 88
84/* XXX: if read fails, any partial read is undone */ 89/* XXX: if read fails, any partial read is undone */
85ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 90ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint);