void startHelper () { while(idling) { PeriodicThread::startHelper(); SystemMutex::scoped_lock cond_lock(mutexCondSleeponit); while(running==false) condSleeponit.wait(cond_lock); } if(!idling) //Regular run PeriodicThread::startHelper(); }
int _session_mgr_thread(void *param) { session_mgr_t *mgr = (session_mgr_t *)param; if (mgr == NULL) { LOG_ERROR("Invalid session mgr"); return ZISS_ERROR; } cond_lock(mgr->exit_cond); do { if (mgr->session_list == NULL) continue; session_mgr_check(mgr); } while (cond_timewait(mgr->exit_cond, 100) == S_WAIT_TIMEOUT); cond_unlock(mgr->exit_cond); return ZISS_OK; }
s32 sys_interrupt_thread_establish(vm::ptr<u32> ih, u32 intrtag, u64 intrthread, u64 arg) { sys_interrupt.Warning("sys_interrupt_thread_establish(ih=*0x%x, intrtag=0x%x, intrthread=%lld, arg=0x%llx)", ih, intrtag, intrthread, arg); const u32 class_id = intrtag >> 8; if (class_id != 0 && class_id != 2) { return CELL_ESRCH; } const auto t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); if (!t) { return CELL_ESRCH; } RawSPUThread& spu = static_cast<RawSPUThread&>(*t); auto& tag = class_id ? spu.int2 : spu.int0; // CELL_ESTAT is not returned (can't detect exact condition) const auto it = Emu.GetCPU().GetThread((u32)intrthread); if (!it) { return CELL_ESRCH; } PPUThread& ppu = static_cast<PPUThread&>(*it); { LV2_LOCK; if (ppu.custom_task) { return CELL_EAGAIN; } if (s32 res = tag.assigned.atomic_op<s32>(CELL_OK, [](s32& value) -> s32 { if (value < 0) { return CELL_ESRCH; } value++; return CELL_OK; })) { return res; } ppu.custom_task = [t, &tag, arg](PPUThread& CPU) { const auto func = vm::ptr<void(u64 arg)>::make(CPU.entry); const auto pc = vm::read32(func.addr()); const auto rtoc = vm::read32(func.addr() + 4); std::unique_lock<std::mutex> cond_lock(tag.handler_mutex); while (!Emu.IsStopped()) { // call interrupt handler until int status is clear if (tag.stat.read_relaxed()) { //func(CPU, arg); CPU.GPR[3] = arg; CPU.FastCall2(pc, rtoc); } tag.cond.wait_for(cond_lock, std::chrono::milliseconds(1)); } }; } *ih = Emu.GetIdManager().make<lv2_int_handler_t>(it); ppu.Exec(); return CELL_OK; }
int main() { cl_int error_code = CL_SUCCESS; try { // find Intel platform cl_uint num_platforms = 0; error_code = clGetPlatformIDs(0, nullptr, &num_platforms); HANDLE_CL_ERROR(clGetPlatformIDs) std::unique_ptr<cl_platform_id[]> platform_ids( new cl_platform_id[static_cast<const std::size_t>(num_platforms)]); error_code = clGetPlatformIDs(num_platforms, platform_ids.get(), nullptr); HANDLE_CL_ERROR(clGetPlatformIDs) cl_platform_id platform = nullptr; for (std::size_t i = 0; i != static_cast<const std::size_t>(num_platforms); ++i) { std::size_t platform_name_size = 0; error_code = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, 0, nullptr, &platform_name_size); HANDLE_CL_ERROR(clGetPlatformInfo) std::unique_ptr<char[]> platform_name(new char[platform_name_size]); error_code = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, platform_name_size, platform_name.get(), nullptr); HANDLE_CL_ERROR(clGetPlatformInfo) if (std::strcmp(beignet_platform_name, platform_name.get()) == 0) { platform = platform_ids[i]; std::cout << "Platform: " << platform_name.get() << std::endl; break; } } if (platform == nullptr) { throw std::runtime_error(std::string("Couldn't find platform with name: ") + beignet_platform_name); } // find Intel GPU cl_device_id device = nullptr; error_code = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, nullptr); HANDLE_CL_ERROR(clGetDeviceIDs) std::size_t device_name_size = 0; error_code = clGetDeviceInfo(device, CL_DEVICE_NAME, 0, nullptr, &device_name_size); HANDLE_CL_ERROR(clGetDeviceInfo) std::unique_ptr<char[]> device_name(new char[device_name_size]); error_code = clGetDeviceInfo(device, CL_DEVICE_NAME, device_name_size, device_name.get(), nullptr); HANDLE_CL_ERROR(clGetDeviceInfo) std::cout << "Device: " << device_name.get() << std::endl; // create OpenCL context, command queue, program and kernel const auto context = clCreateContext(nullptr, 1, &device, nullptr, nullptr, &error_code); HANDLE_CL_ERROR(clCreateContext) const auto command_queue = clCreateCommandQueue(context, device, 0, &error_code); HANDLE_CL_ERROR(clCreateCommandQueue) const char *source_strings[1]; source_strings[0] = kernel_source; const std::size_t source_size = std::strlen(kernel_source); const auto program = clCreateProgramWithSource(context, 1, source_strings, &source_size, &error_code); HANDLE_CL_ERROR(clCreateProgramWithSource) error_code = clBuildProgram(program, 1, &device, "", nullptr, nullptr); HANDLE_CL_ERROR(clBuildProgram) const auto kernel = clCreateKernel(program, "print_hello", &error_code); HANDLE_CL_ERROR(clCreateKernel) // enqueue kernel and set event completion handler cl_event event; std::size_t global_work_size = 1; error_code = clEnqueueNDRangeKernel(command_queue, kernel, 1, nullptr, &global_work_size, nullptr, 0, nullptr, &event); HANDLE_CL_ERROR(clEnqueueNDRangeKernel) error_code = clSetEventCallback(event, CL_COMPLETE, [](cl_event, cl_int, void *) { std::cout << "OpenCL callback" << std::endl; // Notify the waiting thread that the kernel is completed { std::lock_guard<std::mutex> cond_lock(cond_mutex); kernel_complete = true; } cond_var.notify_one(); }, nullptr); HANDLE_CL_ERROR(clSetEventCallback) error_code = clFlush(command_queue); HANDLE_CL_ERROR(clFlush) // simulate work std::this_thread::sleep_for(std::chrono::seconds(1)); // do work, dependent on kernel completion { std::unique_lock<std::mutex> cond_lock(cond_mutex); while (!kernel_complete) { if (cond_var.wait_for(cond_lock, std::chrono::seconds(5)) == std::cv_status::timeout) { std::cout << "WARNING: A 5 second timeout has been reached on the condition variable.\n" " This may be a deadlock." << std::endl; } } } // When using Beignet, this will never be called as a deadlock will occur. std::cout << "Doing work, dependent on the kernel's completion" << std::endl; } catch (const std::exception &e) { std::cout << "Error: " << e.what() << std::endl; } catch (...) { std::cout << "Unknown error" << std::endl; } }