void __a_serializet(T *t,char *name) { char fn[1000]; H h =_m_new_from_t(t); S *s = _m_serialize(h.m); __a_vm_fn(fn,G_vm->dir,name); writeFile(fn,s,s->total_size); free(s); _m_free(h); }
/** * clean shutdown of the the ceptr system * * should be called by the thread that called _a_boot() (or _a_start_vmhost()) */ void _a_shut_down() { // cleanly close down any processing in the VM_Host __r_kill(G_vm->r); _v_join_thread(&G_vm->clock_thread); _v_join_thread(&G_vm->vm_thread); char fn[1000]; // serialize the semtable __a_serializet(_t_root(G_vm->sem->stores[0].definitions),SEM_FN); int i; T *paths = _t_new_root(RECEPTOR_PATHS); for (i=0;i<G_vm->sem->contexts;i++) { // we don't need the path of the root so start at 1 int *p = _t_get_path(G_vm->sem->stores[i].definitions); if (p) { _t_new(paths,RECEPTOR_PATH,p,sizeof(int)*(_t_path_depth(p)+1)); free(p); } else _t_newr(paths,STRUCTURE_ANYTHING); // should be something like DELETED_CONTEXT } __a_serializet(paths,PATHS_FN); _t_free(paths); // serialize the receptor part of the vmhost void *surface; size_t length; _r_serialize(G_vm->r,&surface,&length); // _r_unserialize(surface); __a_vmfn(fn,G_vm->dir); writeFile(fn,surface,length); free(surface); // serialize other parts of the vmhost H h = _m_newr(null_H,SYS_STATE); H har = _m_newr(h,ACTIVE_RECEPTORS); for (i=0;i<G_vm->active_receptor_count;i++) { _m_new(har,RECEPTOR_XADDR,&G_vm->active_receptors[i].x,sizeof(Xaddr)); } S *s = _m_serialize(h.m); __a_vm_state_fn(fn,G_vm->dir); writeFile(fn,s,s->total_size); free(s); _m_free(h); // free the memory used by the SYS_RECEPTOR _v_free(G_vm); G_vm = NULL; }
/** * create a serialized version of an mtree * * @param[in] oh handle of mtree node to detach from the mtree * @param[inout] sizeP pointer to size_t value to return length of serialized data * @returns pointer to newly malloced buffer of serialized tree data */ S *_m_serialize(M *m) { uint32_t s_size = SERIALIZED_HEADER_SIZE(m->levels); uint32_t levels_size = 0; size_t blob_size = 0; Mindex i; H h = {m,{0,0}}; // calculate level and blob sizes so we can allocate for(h.a.l=0; h.a.l<m->levels; h.a.l++) { L *l = GET_LEVEL(h); levels_size += SERIALIZED_LEVEL_SIZE(l); for(h.a.i=0;h.a.i < l->nodes;h.a.i++) { N *n = GET_NODE(h,l); blob_size+=n->size; } } size_t total_size = s_size+levels_size+blob_size; S *s = malloc(total_size); memset(s,0,total_size); s->magic = m->magic; s->total_size = total_size; s->levels = m->levels; s->blob_offset = s_size+levels_size; void *blob = s->blob_offset + (void *)s; levels_size = 0; blob_size = 0; for(h.a.l=0; h.a.l<m->levels; h.a.l++) { s->level_offsets[h.a.l] = levels_size; L *sl = (L *) (((void *)s) + s_size + levels_size); L *l = GET_LEVEL(h); levels_size += SERIALIZED_LEVEL_SIZE(l); sl->nodes = l->nodes; N *sn = sizeof(Mindex)+(void *)sl; for(h.a.i=0;h.a.i < l->nodes;h.a.i++) { N *n = GET_NODE(h,l); *sn = *n; // raise(SIGINT); if (n->flags & TFLAG_SURFACE_IS_RECEPTOR) { raise_error("can't serialize receptors"); } if (n->flags & TFLAG_SURFACE_IS_TREE && !(n->flags & TFLAG_SURFACE_IS_RECEPTOR)) { H sh = *(H *)n->surface; S *ss = _m_serialize(sh.m); *(size_t *)&sn->surface = blob_size; // orth tree size wasn't included in the original total size so // we have to realloc the buffer and increase the size // @todo, a better way to do this would have been to serialize the orthogonal // trees ahead of time in the size calculation loop so as not to have to // realloc here, instead we could just copy the tree in size_t new_total_size = s->total_size + ss->total_size; s = realloc(s,new_total_size); s->total_size = new_total_size; // reset pointers into the serialized block because of the realloc: // blob, sl and sn blob = s->blob_offset + (void *)s; sl = (L *) (((void *)s) + s_size + levels_size); sn = sizeof(Mindex)+(void *)sl + SERIALIZED_NODE_SIZE*h.a.i; memcpy(blob+blob_size,ss,ss->total_size); blob_size+=ss->total_size; free(ss); } else if (n->flags & TFLAG_ALLOCATED) { *(size_t *)&sn->surface = blob_size; memcpy(blob+blob_size,n->surface,n->size); blob_size+=n->size; } else { memcpy(&sn->surface,&n->surface,n->size); } sn = (N *) (SERIALIZED_NODE_SIZE + ((void*)sn)); } } return s; }