static void resizefintab(Fintab *tab) { Fintab newtab; void *k; int32 i; runtime_memclr((byte*)&newtab, sizeof newtab); newtab.max = tab->max; if(newtab.max == 0) newtab.max = 3*3*3; else if(tab->ndead < tab->nkey/2) { // grow table if not many dead values. // otherwise just rehash into table of same size. newtab.max *= 3; } newtab.fkey = runtime_mallocgc(newtab.max*sizeof newtab.fkey[0], FlagNoPointers, 0, 1); newtab.val = runtime_mallocgc(newtab.max*sizeof newtab.val[0], 0, 0, 1); for(i=0; i<tab->max; i++) { k = tab->fkey[i]; if(k != nil && k != (void*)-1) addfintab(&newtab, k, tab->val[i].fn, tab->val[i].ft); } runtime_free(tab->fkey); runtime_free(tab->val); tab->fkey = newtab.fkey; tab->val = newtab.val; tab->nkey = newtab.nkey; tab->ndead = newtab.ndead; tab->max = newtab.max; }
static void runfinq(void* dummy) { Finalizer *f, *next; USED(dummy); for(;;) { pthread_mutex_lock(&finqlock); f = finq; finq = nil; if(f == nil) { fingwait = 1; pthread_cond_wait(&finqcond, &finqlock); pthread_mutex_unlock(&finqlock); continue; } pthread_mutex_unlock(&finqlock); for(; f; f=next) { void *params[1]; next = f->next; params[0] = &f->arg; reflect_call(f->ft, (void*)f->fn, 0, params, nil); f->fn = nil; f->arg = nil; f->next = nil; runtime_free(f); } runtime_gc(1); // trigger another gc to clean up the finalized objects, if possible } }
void mu_runtime_uninit (void) { g_return_if_fail (_initialized); runtime_free (); _initialized = FALSE; }
void mu_runtime_uninit (void) { if (!_initialized) return; runtime_free (); _initialized = FALSE; }
gboolean mu_runtime_init (const char* muhome_arg, const char *name) { gchar *muhome; g_return_val_if_fail (!_initialized, FALSE); g_return_val_if_fail (name, FALSE); setlocale (LC_ALL, ""); #ifndef GLIB_VERSION_2_36 g_type_init (); #endif /*GLIB_VERSION_2_36*/ if (muhome_arg) muhome = g_strdup (muhome_arg); else muhome = mu_util_guess_mu_homedir (); if (!mu_util_create_dir_maybe (muhome, 0700, TRUE)) { g_printerr ("mu: invalid mu homedir specified;" " use --muhome=<dir>\n"); runtime_free (); return FALSE; } _data = g_new0 (MuRuntimeData, 1); _data->_str[MU_RUNTIME_PATH_MUHOME] = muhome; init_paths (muhome, _data); _data->_name = g_strdup (name); if (!init_log (muhome, name, MU_LOG_OPTIONS_BACKUP)) { runtime_free (); g_free (muhome); return FALSE; } return _initialized = TRUE; }
gboolean mu_runtime_init_from_cmdline (int *pargc, char ***pargv, const char *name) { g_return_val_if_fail (!_initialized, FALSE); g_return_val_if_fail (name, FALSE); setlocale (LC_ALL, ""); g_type_init (); _data = g_new0 (MuRuntimeData, 1); _data->_config = mu_config_init (pargc, pargv); if (!_data->_config) { runtime_free (); return FALSE; } if (!mu_util_create_dir_maybe (_data->_config->muhome, 0700, TRUE)) { g_printerr ("mu: invalid mu homedir specified;" " use --muhome=<dir>\n"); runtime_free (); return FALSE; } _data->_name = g_strdup (name); _data->_str[MU_RUNTIME_PATH_MUHOME] = g_strdup (_data->_config->muhome); init_paths (_data->_str[MU_RUNTIME_PATH_MUHOME], _data); if (!init_log (runtime_path(MU_RUNTIME_PATH_MUHOME), name, _data->_config->log_stderr, _data->_config->quiet, _data->_config->debug)) { runtime_free (); return FALSE; } return _initialized = TRUE; }
// Run all deferred functions for the current goroutine. static void rundefer(void) { Defer *d; while((d = g->defer) != nil) { void (*pfn)(void*); pfn = d->__pfn; d->__pfn = nil; if (pfn != nil) (*pfn)(d->__arg); g->defer = d->__next; runtime_free(d); } }
void gapp_free(GraceApp *gapp) { unsigned int i; if (!gapp) { return; } for (i = 0; i < gapp->gpcount; i++) { gproject_free(gapp->gplist[i]); } xfree(gapp->gplist); quark_free(gapp->pc); gui_free(gapp->gui); runtime_free(gapp->rt); grace_free(gapp->grace); xfree(gapp); }
FILE *profile_fopen(const char *fname, const char *mode) { char *key = NULL, *val = NULL, *rsp = NULL, *domStr = NULL, *diskname = NULL; uint32_t req, rsptype, rsplen, domId; XenStorePaths *xsp = NULL; uint64_t store_mptr; FILE *retval = NULL; int vallen; long res; if(strncmp(mode, "w", 1) != 0) goto fail; if(strncmp(fname, "HaLVM.prof", 11) == 0) diskname = "xvdp1"; if(strncmp(fname, "HaLVM.hp", 9) == 0) diskname = "xvdp2"; if(!diskname) goto fail; store_mptr = (uint64_t)system_start_info->store_mfn << 12; unmask_channel(system_start_info->store_evtchn); xsint = (struct xenstore_domain_interface*)machine_to_virtual(store_mptr); if(!xsint) { printf("PROFILING ERROR: Could not map XenStore page.\n"); goto fail; } /* Try to run "ls devices/vbd" */ req = xenstore_write(XS_DIRECTORY, strlen("device/vbd") + 1, "device/vbd"); rsplen = xenstore_read(req, &rsptype, (void**)&rsp); if(rsptype == XS_ERROR) { printf("PROFILING: XenStore read error. Did you forget to add a disk?\n"); goto fail; } if(rsptype != XS_DIRECTORY) { printf("PROFILING: XenStore has gone weird. Giving up.\n"); goto fail; } /* Find the XenStore paths associated with the disk we want */ xsp = find_xs_paths(diskname, rsp, rsplen); if(!xsp) { printf("PROFILING: Couldn't find file to open.\n"); goto fail; } /* Pull out the other's domId */ key = malloc(256); snprintf(key, 256, "%s/backend-id", xsp->feDir); domStr = xenstore_getkey(key); domId = atoi(domStr); /* allocate the return structure and buffers */ retval = malloc(sizeof(FILE)); if(!retval) goto fail; memset(retval, 0, sizeof(FILE)); retval->cur_block_num = 1; retval->block = runtime_alloc(NULL, 4096, PROT_READ|PROT_WRITE); if(!retval->block) goto fail; assert( (((uintptr_t)retval->block) & 4095) == 0 ); retval->ring.sring = runtime_alloc(NULL, 4096, PROT_READ|PROT_WRITE); if(!retval->ring.sring) goto fail; assert( (((uintptr_t)retval->ring.sring) & 4095) == 0 ); SHARED_RING_INIT(retval->ring.sring); FRONT_RING_INIT(&(retval->ring), retval->ring.sring, 4096); /* get the device handle */ snprintf(key, 256, "%s/virtual-device", xsp->feDir); val = xenstore_getkey(key); retval->disk_handle = atoi(val); /* allocate the grant references and event channel */ res = alloc_grant(domId, retval->ring.sring, 4096, 0, &retval->ring_grant); if(res) { printf("PROFILING: Failed to allocate ring grant reference: %d\n", res); goto fail; } res = alloc_grant(domId, retval->block, 4096, 0, &retval->block_grant); if(res) { printf("PROFILING: Failed to allocate block grant reference: %d\n", res); goto fail; } res = channel_alloc(DOMID_SELF, domId); if(res < 0) { printf("PROFILING: Failed to allocate grant reference: %d\n", res); goto fail; } retval->chan = (uint32_t)res; set_c_handler(retval->chan, handler); /* write them into our tree */ val = malloc(256); /* */ snprintf(key, 256, "%s/ring-ref", xsp->feDir); vallen = snprintf(val, 256, "%d", retval->ring_grant); if(!xenstore_setkey(key, val, vallen)) goto fail; /* */ snprintf(key, 256, "%s/event-channel", xsp->feDir); vallen = snprintf(val, 256, "%d", retval->chan); if(!xenstore_setkey(key, val, vallen)) goto fail; /* */ snprintf(key, 256, "%s/state", xsp->feDir); vallen = snprintf(val, 256, "%d", XenbusStateInitialised); if(!xenstore_setkey(key, val, vallen)) goto fail; /* wait for the other side to sync up */ do { char *state; runtime_block(1); snprintf(key, 256, "%s/state", xsp->beDir); state = xenstore_getkey(key); res = atoi(state); free(state); } while(res != XenbusStateConnected); /* write out that we're good */ /* */ snprintf(key, 256, "%s/state", xsp->feDir); vallen = snprintf(val, 256, "%d", XenbusStateConnected); if(!xenstore_setkey(key, val, vallen)) goto fail; return retval; fail: if(key) free(key); if(val) free(val); if(rsp) free(rsp); if(xsp) { free(xsp->feDir); free(xsp->beDir); free(xsp); } if(domStr) free(domStr); if(retval) { if(retval->block_grant) end_grant(retval->block_grant); if(retval->ring_grant) end_grant(retval->ring_grant); if(retval->block) runtime_free(retval->block, 4096); if(retval->ring.sring) runtime_free(retval->ring.sring, 4096); if(retval->chan) channel_close(retval->chan); free(retval); } errno = -EACCES; return NULL; }
RunTime *runtime_new(GraceApp *gapp) { RunTime *rt; char *s; rt = xmalloc(sizeof(RunTime)); if (!rt) { return NULL; } memset(rt, 0, sizeof(RunTime)); rt->P = gapp; /* allocatables */ rt->print_dests = NULL; rt->print_cmd = NULL; rt->gapp_editor = NULL; rt->help_viewer = NULL; rt->workingdir = NULL; #ifdef HAVE_CUPS rt->use_cups = TRUE; #else rt->use_cups = FALSE; #endif /* print command */ if ((s = getenv("GRACE_PRINT_CMD")) == NULL) { s = bi_print_cmd(); } rt->print_cmd = copy_string(NULL, s); if (rt->use_cups) { rt->ptofile = FALSE; } else /* if no print command defined, print to file by default */ if (string_is_empty(rt->print_cmd)) { rt->ptofile = TRUE; } else { rt->ptofile = FALSE; } /* editor */ if ((s = getenv("GRACE_EDITOR")) == NULL) { s = bi_editor(); } rt->gapp_editor = copy_string(NULL, s); /* html viewer */ if ((s = getenv("GRACE_HELPVIEWER")) == NULL) { s = bi_helpviewer(); } rt->help_viewer = copy_string(NULL, s); if (!strstr(rt->help_viewer, "%s")) { rt->help_viewer = concat_strings(rt->help_viewer, " %s"); } /* working directory */ rt->workingdir = xmalloc(GR_MAXPATHLEN); if (!getcwd(rt->workingdir, GR_MAXPATHLEN - 1)) { runtime_free(rt); return NULL; } if (rt->workingdir[strlen(rt->workingdir)-1] != '/') { rt->workingdir = concat_strings(rt->workingdir, "/"); } if (!rt->print_cmd || !rt->gapp_editor || !rt->help_viewer || !rt->workingdir) { runtime_free(rt); return NULL; } if (gapp_init_print(rt) != RETURN_SUCCESS) { runtime_free(rt); return NULL; } rt->print_file[0] = '\0'; rt->tdevice = 0; rt->hdevice = 0; rt->date_hint = FMT_nohint; rt->timer_delay = 200; rt->autoscale_onread = AUTOSCALE_XY; rt->scrollper = 0.05; rt->shexper = 0.05; rt->resfp = NULL; rt->emergency_save = FALSE; rt->interrupts = 0; return rt; }
// add finalizer; caller is responsible for making sure not already in table void runtime_addfinalizer(void *p, void (*f)(void*), const struct __go_func_type *ft) { Fintab newtab; int32 i; uint32 *ref; byte *base; Finalizer *e; e = nil; if(f != nil) { e = runtime_mal(sizeof *e); e->fn = f; e->ft = ft; } runtime_lock(&finlock); if(!runtime_mlookup(p, &base, nil, nil, &ref) || p != base) { runtime_unlock(&finlock); runtime_throw("addfinalizer on invalid pointer"); } if(f == nil) { if(*ref & RefHasFinalizer) { lookfintab(&fintab, p, 1); *ref &= ~RefHasFinalizer; } runtime_unlock(&finlock); return; } if(*ref & RefHasFinalizer) { runtime_unlock(&finlock); runtime_throw("double finalizer"); } *ref |= RefHasFinalizer; if(fintab.nkey >= fintab.max/2+fintab.max/4) { // keep table at most 3/4 full: // allocate new table and rehash. runtime_memclr((byte*)&newtab, sizeof newtab); newtab.max = fintab.max; if(newtab.max == 0) newtab.max = 3*3*3; else if(fintab.ndead < fintab.nkey/2) { // grow table if not many dead values. // otherwise just rehash into table of same size. newtab.max *= 3; } newtab.key = runtime_mallocgc(newtab.max*sizeof newtab.key[0], RefNoPointers, 0, 1); newtab.val = runtime_mallocgc(newtab.max*sizeof newtab.val[0], 0, 0, 1); for(i=0; i<fintab.max; i++) { void *k; k = fintab.key[i]; if(k != nil && k != (void*)-1) addfintab(&newtab, k, fintab.val[i]); } runtime_free(fintab.key); runtime_free(fintab.val); fintab = newtab; } addfintab(&fintab, p, e); runtime_unlock(&finlock); }
// add finalizer; caller is responsible for making sure not already in table void runtime_addfinalizer(void *p, void (*f)(void*), const struct __go_func_type *ft) { Fintab newtab; int32 i; byte *base; Finalizer *e; e = nil; if(f != nil) { e = runtime_mal(sizeof *e); e->fn = f; e->ft = ft; } if(!__sync_bool_compare_and_swap(&m->holds_finlock, 0, 1)) runtime_throw("finalizer deadlock"); runtime_lock(&finlock); if(!runtime_mlookup(p, &base, nil, nil) || p != base) { runtime_unlock(&finlock); __sync_bool_compare_and_swap(&m->holds_finlock, 1, 0); runtime_throw("addfinalizer on invalid pointer"); } if(f == nil) { lookfintab(&fintab, p, 1); goto unlock; } if(lookfintab(&fintab, p, 0)) { runtime_unlock(&finlock); __sync_bool_compare_and_swap(&m->holds_finlock, 1, 0); runtime_throw("double finalizer"); } runtime_setblockspecial(p); if(fintab.nkey >= fintab.max/2+fintab.max/4) { // keep table at most 3/4 full: // allocate new table and rehash. runtime_memclr((byte*)&newtab, sizeof newtab); newtab.max = fintab.max; if(newtab.max == 0) newtab.max = 3*3*3; else if(fintab.ndead < fintab.nkey/2) { // grow table if not many dead values. // otherwise just rehash into table of same size. newtab.max *= 3; } newtab.key = runtime_mallocgc(newtab.max*sizeof newtab.key[0], FlagNoPointers, 0, 1); newtab.val = runtime_mallocgc(newtab.max*sizeof newtab.val[0], 0, 0, 1); for(i=0; i<fintab.max; i++) { void *k; k = fintab.key[i]; if(k != nil && k != (void*)-1) addfintab(&newtab, k, fintab.val[i]); } runtime_free(fintab.key); runtime_free(fintab.val); fintab = newtab; } addfintab(&fintab, p, e); unlock: runtime_unlock(&finlock); __sync_bool_compare_and_swap(&m->holds_finlock, 1, 0); if(__sync_bool_compare_and_swap(&m->gcing_for_finlock, 1, 0)) { __go_run_goroutine_gc(200); } }