NEURON
symbol.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 /* /local/src/master/nrn/src/oc/symbol.cpp,v 1.9 1999/02/25 18:01:58 hines Exp */
3 /* version 7.2.1 2-jan-89 */
4 
5 #if HAVE_POSIX_MEMALIGN
6 #define HAVE_MEMALIGN 1
7 #endif
8 #if defined(DARWIN) /* posix_memalign seems not to work on Darwin 10.6.2 */
9 #undef HAVE_MEMALIGN
10 #endif
11 #if HAVE_MEMALIGN
12 #undef _XOPEN_SOURCE /* avoid warnings about redefining this */
13 #define _XOPEN_SOURCE 600
14 #endif
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include "hoc.h"
20 #include "parse.hpp"
21 #include "hoclist.h"
22 #if MAC
23 #undef HAVE_MALLOC_H
24 #endif
25 #if HAVE_MALLOC_H
26 #include <malloc.h>
27 #endif
28 #if HAVE_ALLOC_H
29 #include <alloc.h> /* at least for turbo C 2.0 */
30 #endif
31 
32 #include "nrnmpiuse.h"
33 
34 #if defined(__APPLE__) && defined(__MACH__)
35 #include <mach/mach.h>
36 #endif
37 
38 #if OOP
39 Symlist *hoc_built_in_symlist = (Symlist *)0; /* keywords, built-in functions,
40  all name linked into hoc. Look in this list last */
41 Symlist *hoc_top_level_symlist = (Symlist *)0; /* all user names seen at top-level
42  (non-public names inside templates do not appear here) */
44 #endif /*OOP*/
45 
46 Symlist *symlist = (Symlist *)0; /* the current user symbol table: linked list */
47 Symlist *p_symlist = (Symlist *)0; /* current proc, func, or temp table */
48  /* containing constants, strings, and auto */
49  /* variables. Discarding these lists at */
50  /* appropriate times prevents storage leakage. */
51 
52 void print_symlist(const char* s, Symlist* tab) {
53  Symbol *sp;
54  Printf("%s\n", s);
55  if (tab) for (sp=tab->first ; sp != (Symbol *) 0; sp = sp->next) {
56  Printf("%s %p\n", sp->name, sp);
57  }
58 }
59 
60 Symbol *hoc_table_lookup(const char* s, Symlist* tab) /* find s in specific table */
61 {
62  Symbol *sp;
63  if (tab) for (sp=tab->first ; sp != (Symbol *) 0; sp = sp->next) {
64  if (strcmp(sp->name, s) == 0) {
65  return sp;
66  }
67  }
68  return (Symbol *)0;
69 }
70 
71 Symbol* lookup(const char* s) /* find s in symbol table */
72  /* look in p_symlist then built_in_symlist then symlist */
73 {
74  Symbol *sp;
75 
76  if ((sp = hoc_table_lookup(s, p_symlist)) != (Symbol *)0) {
77  return sp;
78  }
79  if ((sp = hoc_table_lookup(s, symlist)) != (Symbol *)0) {
80  return sp;
81  }
82 #if OOP
83  if ((sp = hoc_table_lookup(s, hoc_built_in_symlist)) != (Symbol *)0) {
84  return sp;
85  }
86 #endif
87 
88  return 0; /* 0 ==> not found */
89 }
90 
91 Symbol* install( /* install s in the list symbol table */
92  const char *s,
93  int t,
94  double d,
95  Symlist **list
96 ){
97  Symbol *sp;
98 
99  sp = (Symbol *) emalloc(sizeof(Symbol));
100  sp->name = (char *)emalloc((unsigned)(strlen(s)+1)); /* +1 for '\0' */
101  Strcpy(sp->name, s);
102  sp->type = t;
103  sp->subtype = NOTUSER;
104  sp->defined_on_the_fly = 0;
105  sp->cpublic = 0;
106  sp->s_varn = 0;
107  sp->arayinfo = (Arrayinfo *)0;
108  sp->extra = (HocSymExtension*)0;
109  if (!(*list)) {
110  *list = (Symlist *)emalloc(sizeof(Symlist));
111  (*list)->first = (*list)->last = (Symbol *)0;
112  }
113  hoc_link_symbol(sp, *list);
114  switch (t) {
115  case NUMBER:
116  sp->u.pnum = (double *)emalloc(sizeof(double));
117  *sp->u.pnum = d;
118  break;
119  case VAR:
121  OPVAL(sp) = (double *)emalloc(sizeof(double));
122  *(OPVAL(sp)) = d;
123  break;
124  case PROCEDURE:
125  case FUNCTION:
126  case FUN_BLTIN:
127  case OBFUNCTION:
128  case STRFUNCTION:
129  sp->u.u_proc = (Proc *)ecalloc(1, sizeof(Proc));
130  sp->u.u_proc->list = (Symlist*)0;
131  sp->u.u_proc->size = 0;
132  break;
133  default:
134  sp->u.pnum = (double *)0;
135  break;
136  }
137  return sp;
138 }
139 
140 Symbol* hoc_install_var(const char* name, double* pval){
141  Symbol* s;
142  s = hoc_install(name, UNDEF, 0.0, &symlist);
143  s->type = VAR;
144  s->u.pval = pval;
145  s->subtype = USERDOUBLE;
146  return s;
147 }
148 
150 {
151  Symbol *sp;
152  assert(list);
153 
154  if (list->first == s) {
155  list->first = s->next;
156  if (list->last == s) {
157  list->last = (Symbol*)0;
158  }
159  }else {
160  for (sp = list->first ; sp != (Symbol *) 0; sp = sp->next) {
161  if (sp->next == s) {
162  break;
163  }
164  }
165  assert(sp);
166  sp->next = s->next;
167  if (list->last == s) {
168  list->last = sp;
169  }
170  }
171  s->next = (Symbol*)0;
172 }
173 
174 void hoc_link_symbol(Symbol* sp, Symlist* list) {
175  /* put at end of list */
176  if (list->last) {
177  list->last->next = sp;
178  }else{
179  list->first= sp;
180  }
181  list->last = sp;
182  sp->next = (Symbol *)0;
183 }
184 
185 static int emalloc_error=0;
186 
187 extern "C" void hoc_malchk(void) {
188  if (emalloc_error) {
189  emalloc_error = 0;
190  execerror("out of memory", (char *) 0);
191  }
192 }
193 
194 extern "C" void* hoc_Emalloc(size_t n) { /* check return from malloc */
195  void *p;
196 
197  p = malloc(n);
198  if (p == 0)
199  emalloc_error = 1;
200  return p;
201 }
202 
203 void* emalloc(size_t n) {
204  void* p = hoc_Emalloc(n);
205  if (emalloc_error) { hoc_malchk(); }
206  return p;
207 }
208 
209 extern "C" void* hoc_Ecalloc(size_t n, size_t size) { /* check return from calloc */
210  void *p;
211 
212  if (n == 0) {
213  return nullptr;
214  }
215  p = calloc(n, size);
216  if (p == 0)
217  emalloc_error = 1;
218  return p;
219 }
220 
221 extern "C" void* ecalloc(size_t n, size_t size) {
222  void* p = hoc_Ecalloc(n, size);
223  if (emalloc_error) { hoc_malchk(); }
224  return p;
225 }
226 
227 void* nrn_cacheline_alloc(void** memptr, size_t size) {
228 #if HAVE_MEMALIGN
229  static int memalign_is_working = 1;
230  if (memalign_is_working) {
231  if (posix_memalign(memptr, 64, size) != 0) {
232 fprintf(stderr, "posix_memalign not working, falling back to using malloc\n");
233  memalign_is_working = 0;
234  *memptr = hoc_Emalloc(size); hoc_malchk();
235  }
236  }else
237 #endif
238  *memptr = hoc_Emalloc(size); hoc_malchk();
239  return *memptr;
240 }
241 
242 void* nrn_cacheline_calloc(void** memptr, size_t nmemb, size_t size) {
243  int i, n;
244 #if HAVE_MEMALIGN
245  nrn_cacheline_alloc(memptr, nmemb*size);
246  memset(*memptr, 0, nmemb*size);
247 #else
248  *memptr = hoc_Ecalloc(nmemb, size); hoc_malchk();
249 #endif
250  return *memptr;
251 }
252 
253 void* hoc_Erealloc(void* ptr, size_t size) {/* check return from realloc */
254  void* p;
255 
256  if (!ptr) {
257  return hoc_Emalloc(size);
258  }
259  p = realloc(ptr, size);
260  if (p == 0) {
261  free(ptr);
262  emalloc_error = 1;
263  }
264  return p;
265 }
266 
267 extern "C" void* erealloc(void* ptr, size_t size) {
268  void* p = hoc_Erealloc(ptr, size);
269  if (emalloc_error) { hoc_malchk(); }
270  return p;
271 }
272 
273 void hoc_free_symspace(Symbol* s1) { /* frees symbol space. Marks it UNDEF */
274  if (s1 && s1->cpublic != 2) {
275  switch (s1->type)
276  {
277  case UNDEF:
278  break;
279  case STRING:
280  break;
281  case VAR:
282  break;
283  case NUMBER:
284  free((char *)(s1->u.pnum));
285  break;
286  case CSTRING:
287  free(s1->u.cstr);
288  break;
289  case PROCEDURE:
290  case FUNCTION:
291  if (s1->u.u_proc != (Proc *)0) {
292  if (s1->u.u_proc->defn.in != STOP)
293  free((char *) s1->u.u_proc->defn.in);
294  free_list(&(s1->u.u_proc->list));
295  free((char *) s1->u.u_proc);
296  }
297  break;
298  case AUTO:
299  case AUTOOBJ:
300  break;
301  case TEMPLATE:
302 hoc_free_allobjects(s1->u.ctemplate, hoc_top_level_symlist, hoc_top_level_data);
303  free_list(&(s1->u.ctemplate->symtable));
304  {hoc_List* l = s1->u.ctemplate->olist;
305  if (l->next == l) {
307  free(s1->u.ctemplate);
308  }else{
309 hoc_warning("didn't free all objects created with the old template:", s1->name);
310  }
311  }
312  break;
313  case OBJECTVAR:
314 #if 0 /* should have been freed above, otherwise I don't know the exact objects*/
315  if (s1->arayinfo) {int i, j, k=0;
316  for (i = 0; i < s1->arayinfo->nsub; i++) {
317  for (j=0; j < s1->arayinfo->sub[i]; j++) {
318  hoc_dec_refcount(OPOBJ(s1) + k);
319  ++k;
320  }
321  }
322  }else{
323  hoc_dec_refcount(OPOBJ(s1));
324  }
325  free((char *)OPOBJ(s1));
326 #endif
327  break;
328  case OBJECTALIAS:
329  hoc_obj_unref(s1->u.object_);
330  break;
331  case VARALIAS:
332  break;
333  default:
334 Fprintf(stderr, "In free_symspace may not free all of %s of type=%d\n", s1->name, s1->type);
335  }
336  if (s1->arayinfo != (Arrayinfo *)0) {
338  s1->arayinfo = (Arrayinfo *)0;
339  }
340  }
341  if (s1->extra) {
342  if (s1->extra->parmlimits) {
343  free(s1->extra->parmlimits);
344  }
345  if (s1->extra->units) {
346  free(s1->extra->units);
347  }
348  free(s1->extra);
349  s1->extra = (HocSymExtension*)0;
350  }
351  s1->type = UNDEF;
352 }
353 
355  if (!sym->extra) {
356  sym->extra = (HocSymExtension*)ecalloc(1, sizeof(HocSymExtension));
357  }
358 }
359 
360 void free_list(Symlist** list) { /* free the space in a symbol table */
361  Symbol *s1, *s2;
362 
363  if (*list) {
364  for (s1 = (*list)->first; s1; s1 = s2){
365  s2 = s1->next;
366  hoc_free_symspace(s1);
367  if (s1->name) {
368  free(s1->name);
369  }
370  free((char *) s1);
371  }
372  free((char *)(*list));
373  }
374  *list = (Symlist *)0;
375 }
376 
377 void hoc_free_val(double* p) {
378  notify_freed(p);
379  free(p);
380 }
381 
382 void hoc_free_val_array(double* p, size_t size) {
383  notify_freed_val_array(p, size);
384  free(p);
385 }
386 
388  if (p) {
390  free(p);
391  }
392 }
393 
394 void hoc_free_string(char* p) {
395  free(p);
396 }
397 
398 void hoc_free_pstring(char** p) {
399  notify_freed((void*)p);
400  if (*p) {
401  free(*p);
402  free(p);
403  }
404 }
405 
406 extern "C" unsigned long long nrn_mallinfo(int item) {
407 #if defined(__APPLE__) && defined(__MACH__)
408  /* OSX ------------------------------------------------------
409  * Returns the current resident set size (physical memory use) measured
410  * in bytes, or zero if the value cannot be determined on this OS.
411  */
412  struct mach_task_basic_info info;
413  mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
414  if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
415  (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
416  return (size_t)0L; /* Can't access? */
417  return (size_t)info.resident_size;
418 #elif HAVE_MALLINFO
419  /* *NIX PLATFORMS WITH MALLINFO ------------------------------ */
420  int r;
421  struct mallinfo m;
422  m = mallinfo();
423  if (item == 1) {
424  r = m.uordblks;
425  }else if (item == 2) {
426  r = m.hblkhd;
427  }else if (item == 3) {
428  r = m.arena;
429  }else if (item == 4) {
430  r = m.fordblks;
431  }else if (item == 5) {
432  r = m.hblks;
433  }else if (item == 6) {
434  r = m.hblkhd + m.arena;
435  }else{
436  r = m.hblkhd + m.uordblks;
437  }
438  return (unsigned long long)r;
439 #else
440  /* UNSUPPORTED PLATFORM ------------------------------------ */
441  return 0;
442 #endif
443 }
444 
445 int hoc_mallinfo(void) {
446  int i;
447  unsigned long long x;
448  extern double chkarg(int, double, double);
449  i = (int) chkarg(1, 0., 10.);
450  x = nrn_mallinfo(i);
451  hoc_ret();
452  pushx((double) x);
453  return 0;
454 }
455 
456 
float * parmlimits
Definition: hocdec.h:111
int hoc_mallinfo(void)
Definition: symbol.cpp:445
Definition: hocdec.h:84
#define Printf
Definition: model.h:252
#define OPOBJ(sym)
Definition: hocdec.h:306
void pushx(double d)
Definition: code.cpp:641
#define assert(ex)
Definition: hocassrt.h:26
void print_symlist(const char *s, Symlist *tab)
Definition: symbol.cpp:52
char * units
Definition: hocdec.h:112
short type
Definition: model.h:58
void hoc_link_symbol(Symbol *sp, Symlist *list)
Definition: symbol.cpp:174
void * hoc_Emalloc(size_t n)
Definition: symbol.cpp:194
int nsub
Definition: hocdec.h:70
#define VARALIAS
Definition: hocdec.h:108
Symbol * lookup(char *s)
Definition: symbol.cpp:22
Symlist * symtable
Definition: hocdec.h:196
HocStruct Symbol * last
Definition: hocdec.h:86
size_t p
void notify_freed_val_array(double *p, size_t size)
Definition: ivoc.cpp:104
void * erealloc(void *ptr, size_t size)
Definition: symbol.cpp:267
char * name
Definition: model.h:72
unsigned long size
Definition: hocdec.h:77
void hoc_free_string(char *p)
Definition: symbol.cpp:394
#define Fprintf
Definition: model.h:249
void hoc_l_freelist(hoc_List **)
HocStruct Symlist * list
Definition: hocdec.h:78
void hoc_free_val_array(double *p, size_t size)
Definition: symbol.cpp:382
static philox4x32_key_t k
Definition: nrnran123.cpp:11
hoc_List * olist
Definition: hocdec.h:203
Symbol * hoc_install(const char *, int, double, Symlist **)
Symbol * install(char *s, int t)
Definition: symbol.cpp:53
unsigned long long nrn_mallinfo(int item)
Definition: symbol.cpp:406
void hoc_ret()
unsigned s_varn
Definition: hocdec.h:157
Objectdata * hoc_top_level_data
Definition: hoc_oop.cpp:134
void hoc_malchk(void)
Definition: symbol.cpp:187
int sub[1]
Definition: hocdec.h:72
#define NOTUSER
Definition: hocdec.h:91
int const size_t const size_t n
Definition: nrngsl.h:12
_CONST char * s
Definition: system.cpp:74
void hoc_obj_unref(Object *obj)
Definition: hoc_oop.cpp:1998
void notify_freed(void *p)
Definition: ivoc.cpp:95
void hoc_free_object(Object *p)
Definition: symbol.cpp:387
void * emalloc(size_t n)
Definition: symbol.cpp:203
#define STOP
Definition: hocdec.h:66
Arrayinfo * arayinfo
Definition: hocdec.h:158
void hoc_free_allobjects(cTemplate *ctemplate, Symlist *sl, Objectdata *data)
Definition: hoc_oop.cpp:1875
Symlist * hoc_top_level_symlist
Neuron/Java Interface code.
Definition: symbol.cpp:41
int
Definition: nrnmusic.cpp:71
void hoc_warning(const char *, const char *)
#define STRING
Definition: bbslsrv.cpp:9
void hoc_dec_refcount(Object **pobj)
Definition: hoc_oop.cpp:1986
Proc * u_proc
Definition: hocdec.h:144
double * pval
Definition: hocdec.h:136
Inst defn
Definition: hocdec.h:76
char * cstr
Definition: hocdec.h:138
size_t j
#define USERDOUBLE
Definition: hocdec.h:93
fprintf(stderr, "Don't know the location of params at %p\, pp)
Definition: model.h:57
HocStruct Object * object_
Definition: hocdec.h:137
HocSymExtension * extra
Definition: hocdec.h:159
char * name
Definition: init.cpp:16
void free_list(Symlist **list)
Definition: symbol.cpp:360
void notify_pointer_freed(void *pt)
Definition: ivoc.cpp:83
void free_arrayinfo(Arrayinfo *a)
Definition: hoc.cpp:637
Symbol * hoc_table_lookup(const char *s, Symlist *tab)
Definition: symbol.cpp:60
void hoc_unlink_symbol(Symbol *s, Symlist *list)
Definition: symbol.cpp:149
#define Strcpy
Definition: model.h:253
void * ecalloc(size_t n, size_t size)
Definition: symbol.cpp:221
HocStruct Symbol * next
Definition: hocdec.h:161
#define OPVAL(sym)
Definition: hocdec.h:304
long subtype
Definition: model.h:59
void hoc_install_object_data_index(Symbol *sp)
Definition: hoc_oop.cpp:304
Symlist * p_symlist
Definition: symbol.cpp:47
short cpublic
Note: public is a reserved keyword.
Definition: hocdec.h:125
#define FUNCTION(a, b)
Definition: nrngsl.h:6
struct hoc_Item * next
Definition: hoclist.h:50
void * nrn_cacheline_calloc(void **memptr, size_t nmemb, size_t size)
Definition: symbol.cpp:242
Definition: hocdec.h:226
HocStruct cTemplate * ctemplate
Definition: hocdec.h:151
short defined_on_the_fly
Definition: hocdec.h:129
void sym_extra_alloc(Symbol *sym)
Definition: symbol.cpp:354
#define i
Definition: md1redef.h:12
List * symlist[128]
Definition: symbol.cpp:8
#define execerror
Definition: section.h:36
#define OBJECTALIAS
Definition: hocdec.h:107
union Symbol::@18 u
double t
Definition: init.cpp:123
void hoc_free_pstring(char **p)
Definition: symbol.cpp:398
#define pval
Definition: md1redef.h:32
Definition: hocdec.h:75
static int emalloc_error
Definition: symbol.cpp:185
void * hoc_Ecalloc(size_t n, size_t size)
Definition: symbol.cpp:209
Symbol * hoc_install_var(const char *name, double *pval)
Definition: symbol.cpp:140
void hoc_free_symspace(Symbol *s1)
Definition: symbol.cpp:273
void * nrn_cacheline_alloc(void **memptr, size_t size)
Definition: symbol.cpp:227
double chkarg(int, double low, double high)
Definition: code2.cpp:608
double * pnum
Definition: hocdec.h:139
void hoc_free_val(double *p)
Definition: symbol.cpp:377
Symlist * hoc_built_in_symlist
Definition: symbol.cpp:39
void * hoc_Erealloc(void *ptr, size_t size)
Definition: symbol.cpp:253
HocStruct Symbol * first
Definition: hocdec.h:85
HocUnion Inst * in
Definition: hocdec.h:60