ROSS
tw-util.c
Go to the documentation of this file.
1 #include <ross.h>
2 
3 /**
4  * Rollback-aware printf, i.e. if the event gets rolled back, undo the printf.
5  * We can'd do that of course so we store the message in a buffer until GVT.
6  */
7 int
8 tw_output(tw_lp *lp, const char *fmt, ...)
9 {
10  int ret = 0;
11  va_list ap;
12  tw_event *cev;
13  tw_out *temp;
14 
16  va_start(ap, fmt);
17  vfprintf(stdout, fmt, ap);
18  va_end(ap);
19  return 0;
20  }
21 
23  if (!out) {
24  tw_printf(TW_LOC, "kp (%d) has no available output buffers\n", lp->kp->id);
25  tw_printf(TW_LOC, "This event may be rolled back!");
26  va_start(ap, fmt);
27  vfprintf(stdout, fmt, ap);
28  va_end(ap);
29  return 0;
30  }
31 
32  cev = lp->pe->cur_event;
33 
34  if (cev->out_msgs == 0) {
35  cev->out_msgs = out;
36  }
37  else {
38  // Attach it to the end
39  temp = cev->out_msgs;
40 
41  while (temp->next != 0) {
42  temp = temp->next;
43  }
44  temp->next = out;
45  }
46 
47  va_start(ap, fmt);
48  ret = vsnprintf(out->message, sizeof(out->message), fmt, ap);
49  va_end(ap);
50  if (ret >= 0 && (unsigned)ret < sizeof(out->message)) {
51  // Should be successful
52  }
53  else {
54  tw_printf(TW_LOC, "Message may be too large?");
55  }
56 
57  return ret;
58 }
59 
60 void
61 tw_printf(const char *file, int line, const char *fmt, ...)
62 {
63  va_list ap;
64 
65  va_start(ap, fmt);
66  fprintf(stdout, "%s:%i: ", file, line);
67  vfprintf(stdout, fmt, ap);
68  fprintf(stdout, "\n");
69  fflush(stdout);
70  va_end(ap);
71 }
72 
73 void
74 tw_error(const char *file, int line, const char *fmt, ...)
75 {
76  va_list ap;
77 
78  va_start(ap, fmt);
79  fprintf(stdout, "node: %ld: error: %s:%i: ", g_tw_mynode, file, line);
80  vfprintf(stdout, fmt, ap);
81  fprintf(stdout, "\n");
82  fflush(stdout);
83  fflush(stdout);
84  va_end(ap);
85 
86  tw_net_abort();
87 }
88 
89 void
90 tw_warning(const char *file, int line, const char *fmt, ...)
91 {
92  va_list ap;
93 
94  va_start(ap, fmt);
95  fprintf(stdout, "node: %ld: warning: %s:%i: ", g_tw_mynode, file, line);
96  vfprintf(stdout, fmt, ap);
97  fprintf(stdout, "\n");
98  fflush(stdout);
99  fflush(stdout);
100  va_end(ap);
101 }
102 
103 struct mem_pool
104 {
106  char *next_free;
107  char *end_free;
108 }__attribute__((aligned(8)));
109 
110 static struct mem_pool *main_pool;
111 
112 //static const size_t pool_size = 512 * 1024 - sizeof(struct mem_pool);
113 static const size_t pool_size = (512 * 1024) - 32;
114 static const size_t pool_align = ROSS_MAX(sizeof(double),sizeof(void*));
115 static size_t total_allocated;
116 static unsigned malloc_calls;
117 static void* my_malloc(size_t len);
118 
119 void
121  size_t *bytes_alloc,
122  size_t *bytes_wasted)
123 {
124  struct mem_pool *p;
125 
126  *bytes_alloc = total_allocated;
127  *bytes_wasted = malloc_calls * (sizeof(void*) + sizeof(size_t));
128 
129  for (p = main_pool; p; p = p->next_pool)
130  *bytes_wasted += p->end_free - p->next_free;
131 }
132 
133 /* debug version - don't use pool allocator so tools like valgrind can
134  * detect memory bugs */
135 #ifdef ROSS_ALLOC_DEBUG
136 
137 void*
138 tw_calloc(
139  const char *file,
140  int line,
141  const char *for_who,
142  size_t e_sz,
143  size_t n)
144 {
145  void *r = calloc(e_sz, n);
146  if (!r){
147  tw_error(
148  file, line,
149  "Cannot allocate %lu bytes for %u %s",
150  (unsigned long)e_sz,
151  n,
152  for_who);
153  }
154  return r;
155 }
156 
157 #else
158 
159 static void*
160 pool_alloc(size_t len)
161 {
162  struct mem_pool *p;
163  void *r;
164 
165  for (p = main_pool; p; p = p->next_pool)
166  if ((unsigned)(p->end_free - p->next_free) >= len)
167  break;
168 
169  if (!p) {
170  if (len >= pool_size) {
171  r = my_malloc(len);
172  goto ret;
173  }
174 
175  p = (struct mem_pool *) my_malloc(pool_size + 32);
176  if (!p) {
177  r = NULL;
178  goto ret;
179  }
180 
181  p->next_pool = main_pool;
182  //p->next_free = (char*)(p + 1);
183  p->next_free = (char *)((size_t)32 + (size_t)p);
184  if( 7 & (size_t)(p->next_free) )
185  printf("pool_alloc: WARNING found pool start address (%p) NOT 8 byte aligned\n", p->next_free);
186  p->end_free = p->next_free + pool_size;
187  main_pool = p;
188  }
189 
190  r = p->next_free;
191  p->next_free += len;
192 
193  if( 7 & (size_t)r || 7 & (size_t)(p->next_free) )
194  printf("pool_alloc: WARNING found return ptr (%p) or next_free (%p) NOT 8 bytes aligned\n", r, p->next_free );
195 
196 ret:
197  if (r)
198  total_allocated += len;
199  return r;
200 }
201 
202 void*
204  const char *file,
205  int line,
206  const char *for_who,
207  size_t e_sz,
208  size_t n)
209 {
210  void *r;
211 
212  if(e_sz & (pool_align - 1))
213  {
214  e_sz += pool_align - (e_sz & (pool_align - 1));
215  // printf("%s:%d:%s: realigned size to %d \n", file, line, for_who, e_sz );
216  }
217 
218  e_sz *= n;
219  if (!e_sz)
220  return NULL;
221 
222  r = pool_alloc(e_sz);
223  if (!r)
224  tw_error(
225  file, line,
226  "Cannot allocate %lu bytes for %u %s"
227  " (need total of %lu KiB)",
228  (unsigned long)e_sz,
229  n,
230  for_who,
231  (unsigned long)((total_allocated + e_sz) / 1024));
232  memset(r, 0, e_sz);
233  return r;
234 }
235 
236 #endif
237 
238 #undef malloc
239 static void*
240 my_malloc(size_t len)
241 {
242  malloc_calls++;
243  return malloc(len);
244 }
245 
246 #undef realloc
tw_synch g_tw_synchronization_protocol
Definition: ross-global.c:18
#define TW_LOC
Definition: ross-extern.h:164
void * tw_calloc(const char *file, int line, const char *for_who, size_t e_sz, size_t n)
Definition: tw-util.c:203
char message[256-2 *sizeof(void *)]
Definition: ross-types.h:240
int tw_output(tw_lp *lp, const char *fmt,...)
Definition: tw-util.c:8
tw_out * out_msgs
Output messages.
Definition: ross-types.h:289
struct mem_pool * next_pool
Definition: tw-util.c:105
tw_kp * kp
kp – Kernel process that we belong to (must match pe).
Definition: ross-types.h:313
Event Stucture.
Definition: ross-types.h:250
tw_event * cur_event
Current event being processed.
Definition: ross-types.h:385
char * end_free
Definition: tw-util.c:107
struct tw_out * next
Definition: ross-types.h:237
#define __attribute__(x)
Definition: ross.h:96
tw_peid g_tw_mynode
Definition: ross-global.c:88
void tw_error(const char *file, int line, const char *fmt,...)
Definition: tw-util.c:74
void tw_printf(const char *file, int line, const char *fmt,...)
Definition: tw-util.c:61
void tw_warning(const char *file, int line, const char *fmt,...)
Definition: tw-util.c:90
void tw_net_abort(void)
Definition: network-mpi.c:147
void tw_calloc_stats(size_t *bytes_alloc, size_t *bytes_wasted)
Definition: tw-util.c:120
tw_pe * pe
Definition: ross-types.h:308
static const size_t pool_align
Definition: tw-util.c:114
static void * my_malloc(size_t len)
Definition: tw-util.c:240
char * next_free
Definition: tw-util.c:106
#define ROSS_MAX(a, b)
static unsigned malloc_calls
Definition: tw-util.c:116
tw_kpid id
ID number, otherwise its not available to the app.
Definition: ross-types.h:341
Rollback-aware output mechanism.
Definition: ross-types.h:236
static size_t total_allocated
Definition: tw-util.c:115
static const size_t pool_size
Definition: tw-util.c:113
static struct mem_pool * main_pool
Definition: tw-util.c:110
tw_out * tw_kp_grab_output_buffer(tw_kp *kp)
Definition: tw-kp.c:162
static void * pool_alloc(size_t len)
Definition: tw-util.c:160
LP State Structure.
Definition: ross-types.h:304