示例#1
0
mrb_state*
mrb_open()
{
  mrb_state *mrb = mrb_open_allocf(allocf);

  return mrb;
}
示例#2
0
文件: state.c 项目: Ancurio/mruby
mrb_state*
mrb_open(void)
{
  mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL);

  return mrb;
}
示例#3
0
文件: state.c 项目: nin2/mruby
mrb_state*
mrb_open(void)
{
  mrb_state *mrb = mrb_open_allocf(allocf, NULL);

  return mrb;
}
示例#4
0
static mrb_value
mrb_thread_init(mrb_state* mrb, mrb_value self) {
  mrb_value proc = mrb_nil_value();
  mrb_int argc;
  mrb_value* argv;
  mrb_get_args(mrb, "&*", &proc, &argv, &argc);
  if (!mrb_nil_p(proc) && MRB_PROC_CFUNC_P(mrb_proc_ptr(proc))) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "forking C defined block");
  }
  if (!mrb_nil_p(proc)) {
    int i, l;
    mrb_thread_context* context = (mrb_thread_context*) malloc(sizeof(mrb_thread_context));
    context->mrb_caller = mrb;
    context->mrb = mrb_open_allocf(mrb->allocf, mrb->allocf_ud);
    migrate_all_symbols(mrb, context->mrb);
    context->proc = mrb_proc_new(mrb, mrb_proc_ptr(proc)->body.irep);
    context->proc->target_class = context->mrb->object_class;
    context->argc = argc;
    context->argv = calloc(sizeof (mrb_value), context->argc);
    context->result = mrb_nil_value();
    context->alive = TRUE;
    for (i = 0; i < context->argc; i++) {
      context->argv[i] = migrate_simple_value(mrb, argv[i], context->mrb);
    }

    {
      mrb_value gv = mrb_funcall(mrb, self, "global_variables", 0, NULL);
      l = RARRAY_LEN(gv);
      for (i = 0; i < l; i++) {
        mrb_int len;
        int ai = mrb_gc_arena_save(mrb);
        mrb_value k = mrb_ary_entry(gv, i);
        mrb_value o = mrb_gv_get(mrb, mrb_symbol(k));
        if (is_safe_migratable_simple_value(mrb, o, context->mrb)) {
          const char *p = mrb_sym2name_len(mrb, mrb_symbol(k), &len);
          mrb_gv_set(context->mrb,
            mrb_intern_static(context->mrb, p, len),
            migrate_simple_value(mrb, o, context->mrb));
        }
        mrb_gc_arena_restore(mrb, ai);
      }
    }

    mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "context"), mrb_obj_value(
      Data_Wrap_Struct(mrb, mrb->object_class,
      &mrb_thread_context_type, (void*) context)));

    pthread_create(&context->thread, NULL, &mrb_thread_func, (void*) context);
  }
  return self;
}
示例#5
0
int init_plugin_from_file(Plugin *plugin, const char *path, const char *plugin_name)
{
  int fds[2], flags, buffer_size, n;
  
  printf("Loading plugin %s...\n", path);
  plugin->mrb = mrb_open_allocf(profiler_allocf, (void *)path);
  setup_api(plugin->mrb);
  execute_file(plugin->mrb, path);
  execute_file(plugin->mrb, config_path);
  
  C_CHECK("socketpair", socketpair(PF_UNIX, SOCK_DGRAM, 0, fds));
  
  buffer_size = PIPE_BUFFER_SIZE;
  n = sizeof(buffer_size);
  C_CHECK("setsockopt 0 snd", setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, (void *)&buffer_size, n));
  C_CHECK("setsockopt 0 rcv", setsockopt(fds[0], SOL_SOCKET, SO_RCVBUF, (void *)&buffer_size, n));
  
  C_CHECK("setsockopt 1 snd", setsockopt(fds[1], SOL_SOCKET, SO_SNDBUF, (void *)&buffer_size, n));
  C_CHECK("setsockopt 1 snd", setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, (void *)&buffer_size, n));
  
  flags = fcntl(fds[0], F_GETFL);
  flags |= O_NONBLOCK;
  if( fcntl(fds[0], F_SETFL, flags) == -1 ){
    perror("fcntl");
    return -1;
  }
  
  
  plugin->host_pipe = fds[0];
  plugin->plugin_pipe = wrap_io(plugin->mrb, fds[1], "w");
  strncpy(plugin->name, plugin_name, sizeof(plugin->name) - 1);
  
  // set ivs
  // struct RClass *rprobe = mrb_class_get(plugin->mrb, "D3Probe");
  // mrb_value probe_klass = mrb_obj_value(rprobe);
  mrb_sym plugin_iv_sym = mrb_intern_cstr(plugin->mrb, "@plugin");
  
  plugin->plugin_obj = mrb_iv_get(plugin->mrb, mrb_obj_value(plugin->mrb->top_self), plugin_iv_sym);
  // pp(plugin->mrb, plugin->plugin_obj, 0);
  
  // associates the c structure with the ruby object
  DATA_PTR(plugin->plugin_obj)  = (void*)plugin;
  
  mrb_funcall(plugin->mrb, plugin->plugin_obj, "after_config", 0);
  check_exception("after_config", plugin->mrb);
  
  return 0;
}
示例#6
0
bool init_mruby()
{
    Serial2.println("init_mruby enter");
    g_mrb = mrb_open_allocf(myallocfCCM, NULL);
    // g_mrb = mrb_open_allocf(myallocf, NULL);
    Serial2.print("mrb_open done. total allocated : ");
    Serial2.println(total_size, DEC);

    mrb_load_irep(g_mrb, blinker);

    RClass *freeRTOSModule = mrb_define_module(g_mrb, "FreeRTOS");
    mrb_define_module_function(g_mrb, freeRTOSModule, "sleep", mrb_freertos_sleep, ARGS_REQ(1));

    Serial2.println("mruby initialized");

    return true;
}
示例#7
0
void
grn_ctx_impl_mrb_init(grn_ctx *ctx)
{
  if (!grn_ctx_impl_mrb_mruby_enabled) {
    ctx->impl->mrb.state = NULL;
    ctx->impl->mrb.base_directory[0] = '\0';
    ctx->impl->mrb.module = NULL;
    ctx->impl->mrb.object_class = NULL;
    ctx->impl->mrb.checked_procs = NULL;
    ctx->impl->mrb.registered_plugins = NULL;
    ctx->impl->mrb.builtin.time_class = NULL;
    ctx->impl->mrb.groonga.operator_class = NULL;
  } else {
    mrb_state *mrb;
    mrb = mrb_open_allocf(grn_ctx_impl_mrb_allocf, ctx);
    ctx->impl->mrb.state = mrb;
    ctx->impl->mrb.base_directory[0] = '\0';
    grn_ctx_impl_mrb_init_bindings(ctx);
    if (ctx->impl->mrb.state->exc) {
      mrb_value reason;
      reason = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
      ERR(GRN_UNKNOWN_ERROR,
          "failed to initialize mruby: %.*s",
          RSTRING_LEN(reason), RSTRING_PTR(reason));
      mrb_close(ctx->impl->mrb.state);
      ctx->impl->mrb.state = NULL;
    } else {
      ctx->impl->mrb.checked_procs =
        grn_hash_create(ctx, NULL, sizeof(grn_id), 0, GRN_HASH_TINY);
      ctx->impl->mrb.registered_plugins =
        grn_hash_create(ctx, NULL, sizeof(grn_id), 0, GRN_HASH_TINY);
      GRN_VOID_INIT(&(ctx->impl->mrb.buffer.from));
      GRN_VOID_INIT(&(ctx->impl->mrb.buffer.to));
      ctx->impl->mrb.builtin.time_class = mrb_class_get(mrb, "Time");
    }
  }
}
示例#8
0
int main(int argc, char const *argv[])
{
#ifdef _MEM_PROFILER
  uint8_t checkpoint_set = 0;
#endif
  fd_set rfds;
  char buffer[PIPE_BUFFER_SIZE];
  int i, n;
  Plugin plugins[MAX_PLUGINS];
  int plugins_count = 0;
  mrb_state *mrb;
  mrb_value r_output, r_plugins_list;
  mrb_sym output_gv_sym, plugins_to_load_gv_sym;
  
  printf("Version: %s\n", PROBE_VERSION);
  
  if( argc != 2 ){
    printf("Usage: %s <config_path>\n", argv[0]);
    exit(1);
  }
  
#ifdef _MEM_PROFILER
  init_profiler();
#endif
  
  config_path = argv[1];
  
  printf("Initializing core...\n");
  mrb = mrb_open_allocf(profiler_allocf, "main");
  output_gv_sym = mrb_intern_cstr(mrb, "$output");
  plugins_to_load_gv_sym = mrb_intern_cstr(mrb, "$plugins_to_load");
  setup_api(mrb);
  execute_file(mrb, "plugins/main.rb");
  execute_file(mrb, config_path);
  
  printf("Loading plugins...\n");
  r_plugins_list = mrb_gv_get(mrb, plugins_to_load_gv_sym);
  for(i = 0; i< mrb_ary_len(mrb, r_plugins_list); i++){
    char *path, tmp[100];
    int ssize;
    
    mrb_value r_plugin_name = mrb_ary_ref(mrb, r_plugins_list, i);
    const char *plugin_name = mrb_string_value_cstr(mrb, &r_plugin_name);
    
    snprintf(tmp, sizeof(tmp) - 1, "plugins/%s.rb", plugin_name);
    ssize = strlen(tmp);
    
    path = malloc(ssize + 1);
    strncpy(path, tmp, ssize);
    path[ssize] = '\0';
    
    if( access(path, F_OK) == -1 ){
      printf("cannot open plugin file \"%s\": %s\n", path, strerror(errno));
      exit(1);
    }
    
    init_plugin_from_file(&plugins[plugins_count], path, plugin_name); plugins_count++;
  }
  
  printf("Instanciating output class...\n");
  r_output = mrb_gv_get(mrb, output_gv_sym);
  interval = mrb_fixnum(mrb_funcall(mrb, r_output, "interval", 0));
  
  printf("Interval set to %dms\n", (int)interval);
  
  printf("Sending initial report...\n");
  mrb_funcall(mrb, r_output, "send_report", 0);
  
  if (mrb->exc) {
    mrb_print_error(mrb);
    
    exit(1);
  }

  
  // start all the threads
  for(i= 0; i< plugins_count; i++){
    // printf("== plugin %d\n", i);
    n = pthread_create(&plugins[i].thread, NULL, plugin_thread, (void *)&plugins[i]);
    if( n < 0 ){
      fprintf(stderr, "create failed\n");
    }
  }
  
  if( signal(SIGINT, clean_exit) == SIG_ERR){
    perror("signal");
    exit(1);
  }
  
  while(running){
    int fds[MAX_PLUGINS];
    int maxfd = 0, ai;
    struct timeval tv;
    mrb_value r_buffer;
    struct timeval cycle_started_at, cycle_completed_at;
    
    gettimeofday(&cycle_started_at, NULL);
    
    bzero(fds, sizeof(int) * MAX_PLUGINS);
    
    // ask every plugin to send their data
    for(i= 0; i< plugins_count; i++){
      strcpy(buffer, "request");
      if( send(plugins[i].host_pipe, buffer, strlen(buffer), 0) == -1 ){
        printf("send error when writing in pipe connected to plugin '%s'\n", plugins[i].name);
      }
      fds[i] = plugins[i].host_pipe;
      // printf("sent request to %d\n", i);
    }
    
    // printf("waiting answers...\n");
    // and now wait for each answer
    while(1){
      int left = 0;
      
      FD_ZERO(&rfds);
      
      for(i = 0; i< MAX_PLUGINS; i++){
        if( fds[i] != NOPLUGIN_VALUE ){
          FD_SET(fds[i], &rfds);
          left++;
          if( fds[i] > maxfd )
            maxfd = fds[i];
        }
      }
      
      // printf("left: %d %d\n", left, left <= 0);
      
      if( !running || (0 == left) )
        break;
      
      // substract 20ms to stay below the loop delay
      fill_timeout(&tv, cycle_started_at, interval - 20);
      // printf("before select\n");
      n = select(maxfd + 1, &rfds, NULL, NULL, &tv);
      // printf("after select: %d\n", n);
      if( n > 0 ){
        // find out which pipes have data
        for(i = 0; i< MAX_PLUGINS; i++){
          if( (fds[i] != NOPLUGIN_VALUE) && FD_ISSET(fds[i], &rfds) ){
            while (1){
              struct timeval answered_at;
              n = read(fds[i], buffer, sizeof(buffer));
              if( n == -1 ){
                if( errno != EAGAIN )
                  perror("read");
                break;
              }
              
              if( n == PIPE_BUFFER_SIZE ){
                printf("PIPE_BUFFER_SIZE is too small, increase it ! (value: %d)\n", PIPE_BUFFER_SIZE);
                continue;
              }
              
              gettimeofday(&answered_at, NULL);
              // printf("received answer from %s in %u ms\n", (const char *) plugins[i].mrb->ud,
              //     (uint32_t)((answered_at.tv_sec - cycle_started_at.tv_sec) * 1000 +
              //     (answered_at.tv_usec - cycle_started_at.tv_usec) / 1000)
              //   );
              
              buffer[n] = 0x00;
              
              ai = mrb_gc_arena_save(mrb);
              r_buffer = mrb_str_buf_new(mrb, n);
              mrb_str_buf_cat(mrb, r_buffer, buffer, n);
              
              // mrb_funcall(mrb, r_output, "tick", 0);
              mrb_funcall(mrb, r_output, "add", 1, r_buffer);
              check_exception("add", mrb);
              
              // pp(mrb, r_output, 0);
              
              mrb_gc_arena_restore(mrb, ai);
            }
            
            fds[i] = 0;
          }
        }
      }
      else if( n == 0 )  {
        printf("no responses received from %d plugins.\n", left);
        break;
        // timeout
      }
      else {
        perror("select");
      }
    }
    
    int idx = mrb_gc_arena_save(mrb);
    mrb_funcall(mrb, r_output, "flush", 0);
    check_exception("flush", mrb);
    mrb_gc_arena_restore(mrb, idx);
    
    // and now sleep until the next cycle
    gettimeofday(&cycle_completed_at, NULL);
    
  #ifdef _MEM_PROFILER
    if( checkpoint_set ){
      print_allocations();
    }
  #endif
    
    // force a gc run at the end of each cycle
    mrb_full_gc(mrb);
    // printf("[main] capa: %d / %d\n", mrb->arena_idx, mrb->arena_capa);
    // for(i= 0; i< plugins_count; i++){
    //   printf("[%s] capa: %d / %d\n", plugins[i].name, plugins[i].mrb->arena_idx, plugins[i].mrb->arena_capa);
    // }
  
  #ifdef _MEM_PROFILER
    checkpoint_set = 1;
    // and set starting point
    profiler_set_checkpoint();
  #endif

    
  #ifdef _MEM_PROFILER_RUBY
    // dump VMS state
    dump_state(mrb);
    for(i= 0; i< plugins_count; i++){
      dump_state(plugins[i].mrb);
    }
  #endif
    
    fflush(stdout);
    sleep_delay(&cycle_started_at, &cycle_completed_at, interval);
  }
  
  printf("Sending exit signal to all plugins...\n");
  strcpy(buffer, "exit");
  for(i= 0; i< plugins_count; i++){
    C_CHECK("send", send(plugins[i].host_pipe, buffer, strlen(buffer), 0) );
  }
  
  printf("Giving some time for threads to exit...\n\n");
  really_sleep(2000);
  
  
  for(i= 0; i< plugins_count; i++){
    int ret = pthread_kill(plugins[i].thread, 0);
    
    // if a success is returned then the thread is still alive
    // which means the thread did not acknoledged the exit message
    // kill it.
    if( ret == 0 ){
      printf("    - plugin \"%s\" failed to exit properly, killing it...\n", (const char *) plugins[i].mrb->ud);
      pthread_cancel(plugins[i].thread);
    }
    else {
      printf("    - plugin \"%s\" exited properly.\n", (const char *) plugins[i].mrb->allocf_ud);
    }
    
    if( pthread_join(plugins[i].thread, NULL) < 0){
      fprintf(stderr, "join failed\n");
    }
    
    mrb_close(plugins[i].mrb);
  }
  
  mrb_close(mrb);
  
  printf("Exited !\n");
  return 0;
}