Beispiel #1
0
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;
}
Beispiel #2
0
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
	}
}
Beispiel #3
0
void
mu_runtime_uninit (void)
{
	g_return_if_fail (_initialized);

	runtime_free ();

	_initialized = FALSE;
}
Beispiel #4
0
void
mu_runtime_uninit (void)
{
	if (!_initialized)
		return;

	runtime_free ();

	_initialized = FALSE;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
// 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);
	}
}
Beispiel #8
0
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);
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
// 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);
	}
}