예제 #1
0
		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();



		}
예제 #2
0
파일: session_mgr.c 프로젝트: rocflyhi/glow
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;
}
예제 #3
0
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;
    }
}