ceptr
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
accumulator.c
Go to the documentation of this file.
1 
11 #include "accumulator.h"
12 #include "semtrex.h"
13 #include "mtree.h"
14 #include "receptor.h"
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include "debug.h"
18 #include "util.h"
19 
20 VMHost *G_vm = 0;
21 
22 #define PATHS_FN "paths"
23 #define SEM_FN "sem"
24 
25 #define __a_vm_state_fn(buf,dir) __a_vm_fn(buf,dir,"state")
26 #define __a_vmfn(buf,dir) __a_vm_fn(buf,dir,"")
27 void __a_vm_fn(char *buf,char *dir,char *suffix) {
28  sprintf(buf,"%s/vmhost%s.x",dir,suffix);
29 }
30 
31 void __a_serializet(T *t,char *name) {
32  char fn[1000];
33  H h =_m_new_from_t(t);
34  S *s = _m_serialize(h.m);
35  __a_vm_fn(fn,G_vm->dir,name);
36  writeFile(fn,s,s->total_size);
37  free(s);
38  _m_free(h);
39 }
40 
41 T *__a_unserializet(char *dir_path,char *name) {
42  char fn[1000];
43  __a_vm_fn(fn,dir_path,name);
44  S *s = readFile(fn,0);
45  H h = _m_unserialize(s);
46  free(s);
47  T *t = _t_new_from_m(h);
48  _m_free(h);
49  return t;
50 }
51 
60 void _a_boot(char *dir_path) {
61 
62  // check if the storage directory exists
63  struct stat st = {0};
64  if (stat(dir_path, &st) == -1) {
65  // if no directory we are firing up an initial instance, so
66  // create directory
67  mkdir(dir_path,0700);
68 
69  // instantiate a VMHost object
70  G_vm = _v_new();
71  // create the basic receptors that all VMHosts have
73  }
74  else {
75  char fn[1000];
76  void *buffer;
77  // unserialize the semtable base tree
78  SemTable *sem = _sem_new();
79  T *t = __a_unserializet(dir_path,SEM_FN);
80  sem->stores[0].definitions = t;
81 
82  // restore definitions to the correct store slots
83  T *paths = __a_unserializet(dir_path,PATHS_FN);
84  int i = 0;
85  int c = _t_children(paths);
86  for(i=1;i<=c;i++) {
87  T *p = _t_child(paths,i);
88  if (semeq(RECEPTOR_PATH,_t_symbol(p))) {
89  T *x = _t_get(t,(int *)_t_surface(p));
90  sem->stores[i-1].definitions = x;
91  }
92  }
93  _t_free(paths);
94  sem->contexts = c+1;
95 
96  // unserialize all of the vmhost's instantiated receptors and other instances
97  __a_vmfn(fn,dir_path);
98  buffer = readFile(fn,0);
99 
100  Receptor *r = _r_unserialize(sem,buffer);
101  G_vm = __v_init(r,sem);
102  free(buffer);
103 
104  // unserialize other vmhost state data
105  S *s;
106  __a_vm_state_fn(fn,dir_path);
107  s = readFile(fn,0);
108  H h = _m_unserialize(s);
109  free(s);
110 
111  H hars; hars.m=h.m; hars.a = _m_child(h,1); // first child is ACTIVE_RECEPTORS
112  H har; har.m=h.m;
113  int j = _m_children(hars);
114  for (i=1;i<=j;i++) {
115  har.a = _m_child(hars,i);
116  if(!semeq(_m_symbol(har),RECEPTOR_XADDR)) raise_error("expecting RECEPTOR_XADDR!");
117  _v_activate(G_vm,*(Xaddr *)_m_surface(har));
118  }
119  _m_free(h);
120  }
121  G_vm->dir = dir_path;
122 
123  // _a_check_vm_host_version_on_the_compository();
124 
125  _v_start_vmhost(G_vm);
126 }
127 
128 
134 void _a_shut_down() {
135  // cleanly close down any processing in the VM_Host
136  __r_kill(G_vm->r);
137 
138  _v_join_thread(&G_vm->clock_thread);
139  _v_join_thread(&G_vm->vm_thread);
140 
141  char fn[1000];
142 
143  // serialize the semtable
144  __a_serializet(_t_root(G_vm->sem->stores[0].definitions),SEM_FN);
145 
146  int i;
147  T *paths = _t_new_root(RECEPTOR_PATHS);
148  for (i=0;i<G_vm->sem->contexts;i++) { // we don't need the path of the root so start at 1
149  int *p = _t_get_path(G_vm->sem->stores[i].definitions);
150  if (p) {
151  _t_new(paths,RECEPTOR_PATH,p,sizeof(int)*(_t_path_depth(p)+1));
152  free(p);
153  }
154  else
155  _t_newr(paths,STRUCTURE_ANYTHING); // should be something like DELETED_CONTEXT
156  }
157  __a_serializet(paths,PATHS_FN);
158  _t_free(paths);
159 
160  // serialize the receptor part of the vmhost
161  void *surface;
162  size_t length;
163  _r_serialize(G_vm->r,&surface,&length);
164  // _r_unserialize(surface);
165  __a_vmfn(fn,G_vm->dir);
166  writeFile(fn,surface,length);
167  free(surface);
168 
169  // serialize other parts of the vmhost
170  H h = _m_newr(null_H,SYS_STATE);
171  H har = _m_newr(h,ACTIVE_RECEPTORS);
172  for (i=0;i<G_vm->active_receptor_count;i++) {
173  _m_new(har,RECEPTOR_XADDR,&G_vm->active_receptors[i].x,sizeof(Xaddr));
174  }
175  S *s = _m_serialize(h.m);
176  __a_vm_state_fn(fn,G_vm->dir);
177  writeFile(fn,s,s->total_size);
178  free(s);
179  _m_free(h);
180 
181  // free the memory used by the SYS_RECEPTOR
182  _v_free(G_vm);
183  G_vm = NULL;
184 }
185 
186 /*------------------------------------------------------------------------*/
187 
188 T *__a_find(T *t,SemanticID sym) {
189  T *p;
190  DO_KIDS(t,
191  p =_t_child(t,i);
192  if (semeq(*(Symbol *)_t_surface(p),sym)) return p;
193  );
194  return NULL;
195 }
196 
197 T *__a_get_instances(Instances *instances) {
198  T *t = *instances;
199  if (!t) return NULL;
200  t = _t_child(t,InstanceStoreInstancesIdx);
201  if (!t) raise_error("Missing INSTANCES");
202  return t;
203 }
204 
205 Xaddr _a_new_instance(Instances *instances,T *t) {
206  T *x = __a_get_instances(instances);
207  if (!x) {
208  x = *instances = _t_new_root(INSTANCE_STORE);
209  x = _t_newr(x,INSTANCES);
210  }
211  Symbol s = _t_symbol(t);
212  T *si = __a_find(x,s);
213  if (!si) si = _t_news(x,SYMBOL_INSTANCES,s);
214  _t_add(si,t);
215  Xaddr result;
216  result.symbol = s;
217  result.addr = _t_children(si);
218  return result;
219 }
220 
221 T *_a_get_instance(Instances *instances,Xaddr x) {
222  T *t = __a_get_instances(instances);
223  if (!t) return NULL;
224  t = __a_find(t,x.symbol);
225  if (t) {
226  t = _t_child(t,x.addr);
227  if (t && !semeq(_t_symbol(t),DELETED_INSTANCE)) return t;
228  }
229  return NULL;
230 }
231 
232 T *_a_set_instance(Instances *instances,Xaddr x,T *r) {
233  //@todo sanity check on t's symbol type?
234  T *t = _a_get_instance(instances,x);
235  if (t) {
237  return t;
238  }
239  return NULL;
240 }
241 
242 void _a_get_instances(Instances *instances,Symbol s,T *t) {
243  T *c;
244  T *x = __a_get_instances(instances);
245  if (!x) return;
246  x = __a_find(x,s);
247  if (x)
248  DO_KIDS(x,
249  c = _t_child(x,i);
250  if (!semeq(_t_symbol(c),DELETED_INSTANCE))
251  _t_add(t,_t_clone(c));
252  );
253 }
254 
255 void _a_delete_instance(Instances *instances,Xaddr x) {
256  T *t = __a_get_instances(instances);
257  if (!t) return;
258  t = __a_find(t,x.symbol);
259  if (t) {
260  t = _t_child(t,x.addr);
261  if (t) {
262  T *d = _t_new_root(DELETED_INSTANCE);
263  _t_replace_node(t,d);
264  }
265  }
266 }
267 
268 void _a_free_instances(Instances *instances) {
269  T *x = *instances;
270  if (x) {
271  _t_free(x);
272  *instances = NULL;
273  }
274 }
275 
276 S *__a_serialize_instances(Instances *instances) {
277  T *x = __a_get_instances(instances);
278  T *t = _t_new_root(PARAMS);
279  if (x) {
280  T *p;
281  Symbol s;
282  DO_KIDS(x,
283  p =_t_child(x,i);
284  s = *(Symbol *)_t_surface(p);
285  T *sym = _t_news(t,STRUCTURE_SYMBOL,s); // just using this symbol to store the symbol type
286  T *c;
287  DO_KIDS(p,
288  c = _t_child(p,i);
289  if (is_receptor(s)) {
290  void *surface;
291  size_t length;
292  Receptor *r = __r_get_receptor(c);
293  _r_serialize(r,&surface,&length);
294  c = _t_new(0,SERIALIZED_RECEPTOR,surface,length);
295  //@todo create a version of _t_new that doesn't have to realloc the surface but can just use it
296  free(surface);
297  }
298  else c = _t_clone(c);
299  _t_add(sym,c);
300  );
301  );
302  }
303  H h = _m_new_from_t(t);
304  S *s = _m_serialize(h.m);
305  _m_free(h);_t_free(t);
306  return s;
307 }
308 
309 // the quick and dirty serialization builds a new tree
310 // which we will just serialize as an mtree.
311 // is is very inefficient @fixme
312 void _a_serialize_instances(Instances *i,char *file) {
313 
314  S *s = __a_serialize_instances(i);
315 
316  FILE *ofp;
317 
318  ofp = fopen(file, "w");
319  if (ofp == NULL) {
320  raise_error("Can't open output file %s!\n",file);
321  }
322  else {
323  fwrite(s,1,s->total_size,ofp);
324  fclose(ofp);
325  }
326  free(s);
327 }
328 
329 void __a_unserialize_instances(SemTable *sem,Instances *instances,S *s) {
330  H h = _m_unserialize(s);
331  T *t = _t_new_from_m(h);
332 
333  _m_free(h);
334  int j,c = _t_children(t);
335  for(j=1;j<=c;j++) {
336  T *u = _t_child(t,j);
337  SemanticID s = *(SemanticID *)_t_surface(u);
338  int is_receptor = is_receptor(s);
339  while(_t_children(u)) {
340  T *i = _t_detach_by_idx(u,1);
341  if (is_receptor) {
342  Receptor *r = _r_unserialize(sem,_t_surface(i));
343  _t_free(i);
344  i = _t_new_receptor(0,s,r);
345  }
346  _a_new_instance(instances, i);
347  }
348  }
349  _t_free(t);
350 }
351 
352 void _a_unserialize_instances(SemTable *sem,Instances *instances,char *file) {
353  FILE *ofp;
354 
355  ofp = fopen(file, "r");
356  if (ofp == NULL) {
357  raise_error("Can't open input file %s!\n",file);
358  }
359  else {
360  Mmagic magic;
361  fread(&magic, 1,sizeof(magic), ofp);
362  // @todo check magic value
363  size_t total_size;
364  fread(&magic, 1,sizeof(magic), ofp);
365  S *s = malloc(total_size);
366  s->magic = magic;
367  s->total_size = total_size;
368  size_t read_size = total_size-sizeof(Mmagic)-sizeof(total_size);
369  fread(&s->levels,1,read_size,ofp);
370  fclose(ofp);
371  __a_unserialize_instances(sem,instances,s);
372  free(s);
373  }
374 }
375 
376 T *__a_get_tokens(Instances *instances) {
377  T *t = *instances;
378  if (!t) raise_error("uninitialized instances");
379  t = _t_child(t,InstanceStoreTokensIdx);
380  return t;
381 }
382 
383 T *_a_gen_token(Instances *instances,Xaddr x,T *dependency) {
384  T *tokens = __a_get_tokens(instances);
385  T *c;
386  if (!tokens) {
387  tokens = _t_newr(*instances,INSTANCE_TOKENS);
388  c = _t_newi64(tokens,LAST_TOKEN,0);
389  }
390  else c = _t_child(tokens,InstanceTokensLastTokenIdx);
391  // @todo semaphore lock
392  uint64_t *l = (uint64_t *)_t_surface(c);
393  (*l)++;
394  T *t = _t_newi64(tokens,INSTANCE_TOKEN,*l);
395  T *result = _t_clone(t);
396 
397  // cheat and add the token xaddr and dependency as leaves of the last token here in the store
398  _t_new(t,TOKEN_XADDR,&x,sizeof(Xaddr));
399  _t_newi(t,DEPENDENCY_HASH,_t_hash(G_sem,dependency));
400 
401  return result;
402 }
403 
404 
405 T *__a_find_token(T *t,uint64_t token) {
406  T *p;
407  int i,c =_t_children(t);
408  for (i=2;i<=c;i++) {
409  p =_t_child(t,i);
410  if (*(uint64_t *)_t_surface(p) == token) return p;
411  }
412  return NULL;
413 }
414 
415 T * __a_find_dependency(T *t,T *dependency) {
416  T *p;
417  TreeHash dh = _t_hash(G_sem,dependency);
418  int i,c =_t_children(t);
419  for (i=2;i<=c;i++) {
420  p =_t_child(t,i);
421  TreeHash h = *(TreeHash *)_t_surface(p);
422  if (h == dh) return p;
423  }
424  return NULL;
425 }
426 
427 Xaddr _a_get_token_xaddr(Instances *instances,T *token,T *dependency) {
428  T *tokens = __a_get_tokens(instances);
429  if (tokens) {
430  T *t = __a_find_token(tokens,*(uint64_t *)_t_surface(token));
431  if (t) {
432  if (__a_find_dependency(t,dependency))
433  return *(Xaddr *)_t_surface(_t_child(t,1));
434  }
435  }
436  return G_null_xaddr;
437 }
438 
439 void _a_add_dependency(Instances *instances,T *token,T *dependency) {
440  T *tokens = __a_get_tokens(instances);
441  if (tokens) {
442  T *t = __a_find_token(tokens,*(uint64_t *)_t_surface(token));
443  if (t) {
444  if (!__a_find_dependency(t,dependency))
445  _t_newi(t,DEPENDENCY_HASH,_t_hash(G_sem,dependency));
446  return;
447  }
448  }
449  raise_error("token not found:%s\n",_t2s(G_sem,token));
450 }
451 
452 void _a_delete_dependency(Instances *instances,T *token,T *dependency) {
453  T *tokens = __a_get_tokens(instances);
454  if (tokens) {
455  T *t = __a_find_token(tokens,*(uint64_t *)_t_surface(token));
456  if (t) {
457  T *d = __a_find_dependency(t,dependency);
458  if (d) {
460  _t_free(d);
461  }
462  return;
463  }
464  }
465  raise_error("token not found:%s\n",_t2s(G_sem,token));
466 }
467 
468 void _a_delete_token(Instances *instances,T *token){
469  T *tokens = __a_get_tokens(instances);
470  if (tokens) {
471  T *t = __a_find_token(tokens,*(uint64_t *)_t_surface(token));
472  if (t) {
473  _t_detach_by_ptr(tokens,t);
474  _t_free(t);
475  }
476  }
477 }
478 
T * _t_new_root(Symbol symbol)
Definition: tree.c:160
Definition: ceptr_types.h:114
void _r_serialize(Receptor *r, void **surfaceP, size_t *lengthP)
Definition: receptor.c:432
H _m_unserialize(S *s)
Definition: mtree.c:743
T * _t_get(T *t, int *p)
Definition: tree.c:1441
Symbol _m_symbol(H h)
Definition: mtree.c:448
void * _m_surface(H h)
Definition: mtree.c:352
T * _t_detach_by_idx(T *t, int i)
Definition: tree.c:278
int _t_path_depth(int *p)
Definition: tree.c:1365
int _t_node_index(T *t)
Definition: tree.c:1284
S * _m_serialize(M *m)
Definition: mtree.c:645
Semantic tree regular expression header file.
T * _t_new_receptor(T *parent, Symbol symbol, Receptor *r)
Definition: tree.c:204
TreeHash _t_hash(SemTable *sem, T *t)
Definition: tree.c:1614
int * _t_get_path(T *t)
Definition: tree.c:1384
void _v_instantiate_builtins(VMHost *v)
Definition: vmhost.c:324
Definition: ceptr_types.h:68
T * _t_clone(T *t)
Definition: tree.c:589
T * _t_root(T *t)
Definition: tree.c:1272
Symbol _t_symbol(T *t)
Definition: tree.c:1228
T * _t_child(T *t, int i)
Definition: tree.c:1251
Receptor * __r_get_receptor(T *installed_receptor)
Definition: receptor.c:1039
void _a_shut_down()
Definition: accumulator.c:134
void _v_free(VMHost *v)
Definition: vmhost.c:71
receptor implementation header file
VMHost * _v_new()
Creates a new virtual machine host.
Definition: vmhost.c:41
void * _t_surface(T *t)
Definition: tree.c:1215
Maddr _m_child(H h, Mindex c)
Definition: mtree.c:383
void _v_activate(VMHost *v, Xaddr x)
Definition: vmhost.c:172
SemTable * sem
Semantic Table for definitions on this host.
Definition: vmhost.h:44
Receptor * _r_unserialize(SemTable *sem, void *surface)
Definition: receptor.c:459
void _t_replace_node(T *t, T *r)
Definition: tree.c:391
T * _t_parent(T *t)
Definition: tree.c:1262
T * _t_new_from_m(H h)
Definition: mtree.c:250
Definition: vmhost.h:40
H _m_new_from_t(T *t)
Definition: mtree.c:206
void _a_boot(char *dir_path)
Definition: accumulator.c:60
ActiveReceptor active_receptors[MAX_ACTIVE_RECEPTORS]
pointer to array that holds all currently active receptors
Definition: vmhost.h:45
Definition: ceptr_types.h:83
Receptor * r
Receptor data for this vm host.
Definition: vmhost.h:43
int _m_children(H h)
Definition: mtree.c:315
semantic tree matrix header file ``
void _t_add(T *t, T *c)
Definition: tree.c:261
int _t_children(T *t)
Definition: tree.c:1205
header file for the accumulator
void _t_replace(T *t, int i, T *r)
Definition: tree.c:372
void _t_detach_by_ptr(T *t, T *c)
Definition: tree.c:291
void _t_free(T *t)
Definition: tree.c:526
H _m_newr(H parent, Symbol s)
Definition: mtree.c:145