void *spawn_worker(void* params) { struct execution_parameters *p = (struct execution_parameters *)params; (*p->tsp) = init_execution(p->cluster, p->nb_clusters, p->nb_partitions, p->nb_threads, p->nb_towns, p->seed); wait_barrier (p->barrier); start_execution(*p->tsp); wait_barrier (p->barrier); end_execution(*p->tsp); free(params); return NULL; }
void ExecutionManager::mode_callback(const tangible_msgs::Mode::ConstPtr& mode_msg) { mode = mode_msg->mode; switch(mode) { case tangible_msgs::Mode::IDLE: ROS_INFO("Idle Mode"); // stop all movements stop_execution(); break; case tangible_msgs::Mode::EDIT: ROS_INFO("Edit Mode"); // stop all movements stop_execution(); // clear the program. A new program should be obtained after the edit // NOTE: this requires the compilation node to always hold on to the last valid program clear_program(); break; case tangible_msgs::Mode::EXECUTE: ROS_INFO("Execution Mode"); // a program is a sequence of operations. If the program is not defined, obtain // the program. Else, resume its execution from the first incompelete instruction. // NOTE: instructions are the atomic units of normal program execution. if(program.empty()) get_program(); start_execution(); break; default: ROS_ERROR("Invalid Mode"); break; } }
void pal_main (PAL_NUM pal_token, void * pal_addr, const char * pal_name, int argc, const char ** argv, const char ** envp, PAL_HANDLE parent_handle, PAL_HANDLE thread_handle, PAL_HANDLE exec_handle, PAL_HANDLE manifest_handle) { int ret; bool is_parent = !parent_handle; #if PROFILING == 1 __pal_control.host_specific_startup_time = _DkSystemTimeQuery() - pal_state.start_time; #endif pal_state.pal_token = pal_token; pal_state.pal_addr = pal_addr; pal_state.parent_handle = parent_handle; pal_state.pagesize = _DkGetPagesize(); pal_state.alloc_align = _DkGetAllocationAlignment(); pal_state.alloc_shift = pal_state.alloc_align - 1; pal_state.alloc_mask = ~pal_state.alloc_shift; init_slab_mgr(pal_state.alloc_align); char * exec = NULL, * manifest = NULL; if (exec_handle) { exec = __alloca(URI_MAX); ret = _DkStreamGetName(exec_handle, exec, URI_MAX); if (ret < 0) init_fail(-ret, "cannot get executable name"); } if (manifest_handle) { manifest = __alloca(URI_MAX); ret = _DkStreamGetName(manifest_handle, manifest, URI_MAX); if (ret < 0) init_fail(-ret, "cannot get manifest name"); } else { if (is_parent) { #if PROFILING == 1 unsigned long before_find_manifest = _DkSystemTimeQuery(); #endif do { if (exec_handle) { assert(!!exec); /* try open "<exec>.manifest" */ manifest = __alloca(URI_MAX); snprintf(manifest, URI_MAX, "%s.manifest", exec); ret = _DkStreamOpen(&manifest_handle, manifest, PAL_ACCESS_RDONLY, 0, 0, 0); if (!ret) break; } /* try open "file:manifest" */ manifest = "file:manifest"; ret = _DkStreamOpen(&manifest_handle, manifest, PAL_ACCESS_RDONLY, 0, 0, 0); if (!ret) break; /* well, there is no manifest file, leave it alone */ if (!manifest_handle) printf("Can't fine any manifest, will run without one\n"); } while (0); #if PROFILING == 1 pal_state.manifest_loading_time += _DkSystemTimeQuery() - before_find_manifest; #endif } } /* load manifest if there is one */ if (manifest_handle) { #if PROFILING == 1 unsigned long before_load_manifest = _DkSystemTimeQuery(); #endif PAL_STREAM_ATTR attr; ret = _DkStreamAttributesQuerybyHandle(manifest_handle, &attr); if (ret < 0) init_fail(-ret, "cannot open manifest file"); void * cfg_addr = NULL; int cfg_size = attr.pending_size; ret = _DkStreamMap(manifest_handle, &cfg_addr, PAL_PROT_READ, 0, ALLOC_ALIGNUP(cfg_size)); if (ret < 0) init_fail(-ret, "cannot open manifest file"); struct config_store * root_config = malloc(sizeof(struct config_store)); root_config->raw_data = cfg_addr; root_config->raw_size = cfg_size; root_config->malloc = malloc; root_config->free = free; const char * errstring = NULL; if ((ret = read_config(root_config, loader_filter, &errstring)) < 0) init_fail(-ret, errstring); pal_state.root_config = root_config; #if PROFILING == 1 pal_state.manifest_loading_time += _DkSystemTimeQuery() - before_load_manifest; #endif } /* if there is no executable, try to find one in the manifest */ if (is_parent && !exec_handle) { exec = __alloca(URI_MAX); assert(!!pal_state.root_config); ret = get_config(pal_state.root_config, "loader.exec", exec, URI_MAX); if (ret > 0) { ret = _DkStreamOpen(&exec_handle, exec, PAL_ACCESS_RDONLY, 0, 0, 0); if (ret < 0) init_fail(-ret, "cannot open executable"); /* must be a ELF */ if (check_elf_object(exec_handle) < 0) init_fail(PAL_ERROR_INVAL, "executable is not a ELF binary"); } else { exec = NULL; } } if (is_parent && !exec_handle && !manifest_handle) { printf("USAGE: %s [executable|manifest] args ...\n", pal_name); _DkProcessExit(0); return; } pal_state.manifest = manifest; pal_state.manifest_handle = manifest_handle; pal_state.exec = exec; pal_state.exec_handle = exec_handle; const char * first_argv = *argv; argc--; argv++; if (is_parent && exec_handle) { first_argv = exec; if (pal_state.root_config) { char cfgbuf[CONFIG_MAX]; ret = get_config(pal_state.root_config, "loader.execname", cfgbuf, CONFIG_MAX); if (ret > 0) first_argv = remalloc(cfgbuf, ret + 1); } } if (pal_state.root_config) load_libraries(); if (exec_handle) { #if PROFILING == 1 unsigned long before_load_exec = _DkSystemTimeQuery(); #endif ret = load_elf_object_by_handle(exec_handle, OBJECT_EXEC); if (ret < 0) init_fail(ret, PAL_STRERROR(ret)); #if PROFILING == 1 pal_state.linking_time += _DkSystemTimeQuery() - before_load_exec; #endif } #if PROFILING == 1 unsigned long before_tail = _DkSystemTimeQuery(); #endif if (pal_state.root_config) { read_envs(&envp); set_debug_type(); set_syscall_symbol(); } __pal_control.process_id = _DkGetProcessId(); __pal_control.host_id = _DkGetHostId(); __pal_control.manifest_handle = manifest_handle; __pal_control.executable = exec; __pal_control.parent_process = parent_handle; __pal_control.first_thread = thread_handle; _DkGetAvailableUserAddressRange(&__pal_control.user_address.start, &__pal_control.user_address.end); __pal_control.pagesize = pal_state.pagesize; __pal_control.alloc_align = pal_state.alloc_align; __pal_control.broadcast_stream = _DkBroadcastStreamOpen(); _DkGetCPUInfo(&__pal_control.cpu_info); __pal_control.mem_info.mem_total = _DkMemoryQuota(); #if PROFILING == 1 pal_state.tail_startup_time += _DkSystemTimeQuery() - before_tail; __pal_control.relocation_time = pal_state.relocation_time; __pal_control.linking_time = pal_state.linking_time; __pal_control.manifest_loading_time = pal_state.manifest_loading_time; __pal_control.allocation_time = pal_state.slab_time; __pal_control.child_creation_time = is_parent ? 0 : pal_state.start_time - pal_state.process_create_time; #endif /* Now we will start the execution */ start_execution(first_argv, argc, argv, envp); /* We wish we will never reached here */ init_fail(PAL_ERROR_DENIED, "unexpected termination"); }
void run3dsx(Handle executable, u32* argbuf) { initSrv(); gspGpuInit(); // free extra data pages if any freeDataPages(0x14000000); freeDataPages(0x30000000); // reset menu ropbin (in case of a crash) { u32 _argbuf = 0; svc_controlMemory((u32*)&gspHeap, 0x0, 0x0, 0x01000000, 0x10003, 0x3); patchMenuRop(1, &_argbuf, 4); svc_controlMemory((u32*)&gspHeap, (u32)gspHeap, 0x0, 0x01000000, MEMOP_FREE, 0x0); } // duplicate service list on the stack // also add hid:SPVR as hid:USER if appropriate // (for backwards compat as old homebrew only supports hid:USER) u8 serviceBuffer[0x4+0xC*(_serviceList.num + 1)]; service_list_t* serviceList = (service_list_t*)serviceBuffer; serviceList->num = _serviceList.num; int i; for(i=0; i<_serviceList.num; i++) { memcpy(serviceList->services[i].name, _serviceList.services[i].name, 8); svc_duplicateHandle(&serviceList->services[i].handle, _serviceList.services[i].handle); } // handle hid:USER missing case { Handle hidUSER = 0; if(srv_getServiceHandle(NULL, &hidUSER, "hid:USER") && !srv_getServiceHandle(NULL, &hidUSER, "hid:SPVR")) { memcpy(serviceList->services[serviceList->num].name, "hid:USER", 8); serviceList->services[serviceList->num].handle = hidUSER; serviceList->num++; }else svc_closeHandle(hidUSER); } vu32* targetProcessIndex = &_targetProcessIndex; if(*targetProcessIndex == -2) { // create local copy of process map u32 _customProcessBuffer[0x40]; memorymap_t* const _customProcessMap = (memorymap_t*)_customProcessBuffer; memcpy(_customProcessBuffer, customProcessBuffer, sizeof(_customProcessBuffer)); // adjust it given the information we now have such as text size, data location and size... MemInfo minfo; PageInfo pinfo; // get .text info Result ret = svc_queryMemory(&minfo, &pinfo, 0x00100000); _customProcessMap->header.text_end = minfo.size + 0x00100000; // get rodata info ret = svc_queryMemory(&minfo, &pinfo, _customProcessMap->header.text_end); _customProcessMap->header.data_address = minfo.size + _customProcessMap->header.text_end; // get data info ret = svc_queryMemory(&minfo, &pinfo, _customProcessMap->header.data_address); _customProcessMap->header.data_size = minfo.size; // setup 3dsx with custom local map setup3dsx(executable, (memorymap_t*)_customProcessMap, serviceList, argbuf); }else setup3dsx(executable, (memorymap_t*)app_maps[*targetProcessIndex], serviceList, argbuf); FSFILE_Close(executable); gspGpuExit(); exitSrv(); // grab ns:s handle Handle nssHandle = 0x0; for(i=0; i<_serviceList.num; i++)if(!strcmp(_serviceList.services[i].name, "ns:s"))nssHandle=_serviceList.services[i].handle; if(!nssHandle)*(vu32*)0xCAFE0001=0; // use ns:s to launch/kill process and invalidate icache in the process // Result ret = NSS_LaunchTitle(&nssHandle, 0x0004013000003702LL, 0x1); Result ret = NSS_LaunchTitle(&nssHandle, 0x0004013000002A02LL, 0x1); if(ret)*(u32*)0xCAFE0002=ret; svc_sleepThread(100*1000*1000); // ret = NSS_TerminateProcessTID(&nssHandle, 0x0004013000003702LL, 100*1000*1000); ret = NSS_TerminateProcessTID(&nssHandle, 0x0004013000002A02LL, 100*1000*1000); if(ret)*(u32*)0xCAFE0003=ret; // invalidate_icache(); // free heap (has to be the very last thing before jumping to app as contains bss) u32 out; svc_controlMemory(&out, (u32)_heap_base, 0x0, _heap_size, MEMOP_FREE, 0x0); start_execution(); }