dispatcher.cc revision 11534
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2011-2015 Advanced Micro Devices, Inc. 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only 611308Santhony.gutierrez@amd.com * 711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met: 911308Santhony.gutierrez@amd.com * 1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer. 1211308Santhony.gutierrez@amd.com * 1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation 1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution. 1611308Santhony.gutierrez@amd.com * 1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors 1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software 1911308Santhony.gutierrez@amd.com * without specific prior written permission. 2011308Santhony.gutierrez@amd.com * 2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211308Santhony.gutierrez@amd.com * 3311308Santhony.gutierrez@amd.com * Author: Brad Beckmann, Marc Orr 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com 3711308Santhony.gutierrez@amd.com#include "gpu-compute/dispatcher.hh" 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com#include "cpu/base.hh" 4011308Santhony.gutierrez@amd.com#include "debug/GPUDisp.hh" 4111308Santhony.gutierrez@amd.com#include "gpu-compute/cl_driver.hh" 4211308Santhony.gutierrez@amd.com#include "gpu-compute/cl_event.hh" 4311308Santhony.gutierrez@amd.com#include "gpu-compute/shader.hh" 4411308Santhony.gutierrez@amd.com#include "gpu-compute/wavefront.hh" 4511308Santhony.gutierrez@amd.com#include "mem/packet_access.hh" 4611308Santhony.gutierrez@amd.com 4711308Santhony.gutierrez@amd.comGpuDispatcher *GpuDispatcher::instance = nullptr; 4811308Santhony.gutierrez@amd.com 4911308Santhony.gutierrez@amd.comGpuDispatcher::GpuDispatcher(const Params *p) 5011308Santhony.gutierrez@amd.com : DmaDevice(p), _masterId(p->system->getMasterId(name() + ".disp")), 5111308Santhony.gutierrez@amd.com pioAddr(p->pio_addr), pioSize(4096), pioDelay(p->pio_latency), 5211308Santhony.gutierrez@amd.com dispatchCount(0), dispatchActive(false), cpu(p->cpu), 5311308Santhony.gutierrez@amd.com shader(p->shader_pointer), driver(p->cl_driver), tickEvent(this) 5411308Santhony.gutierrez@amd.com{ 5511308Santhony.gutierrez@amd.com shader->handshake(this); 5611308Santhony.gutierrez@amd.com driver->handshake(this); 5711308Santhony.gutierrez@amd.com 5811308Santhony.gutierrez@amd.com ndRange.wg_disp_rem = false; 5911308Santhony.gutierrez@amd.com ndRange.globalWgId = 0; 6011308Santhony.gutierrez@amd.com 6111308Santhony.gutierrez@amd.com schedule(&tickEvent, 0); 6211308Santhony.gutierrez@amd.com 6311308Santhony.gutierrez@amd.com // translation port for the dispatcher 6411308Santhony.gutierrez@amd.com tlbPort = new TLBPort(csprintf("%s-port%d", name()), this); 6511308Santhony.gutierrez@amd.com 6611308Santhony.gutierrez@amd.com num_kernelLaunched 6711308Santhony.gutierrez@amd.com .name(name() + ".num_kernel_launched") 6811308Santhony.gutierrez@amd.com .desc("number of kernel launched") 6911308Santhony.gutierrez@amd.com ; 7011308Santhony.gutierrez@amd.com} 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.comGpuDispatcher *GpuDispatcherParams::create() 7311308Santhony.gutierrez@amd.com{ 7411308Santhony.gutierrez@amd.com GpuDispatcher *dispatcher = new GpuDispatcher(this); 7511308Santhony.gutierrez@amd.com GpuDispatcher::setInstance(dispatcher); 7611308Santhony.gutierrez@amd.com 7711308Santhony.gutierrez@amd.com return GpuDispatcher::getInstance(); 7811308Santhony.gutierrez@amd.com} 7911308Santhony.gutierrez@amd.com 8011308Santhony.gutierrez@amd.comvoid 8111308Santhony.gutierrez@amd.comGpuDispatcher::serialize(CheckpointOut &cp) const 8211308Santhony.gutierrez@amd.com{ 8311308Santhony.gutierrez@amd.com Tick event_tick = 0; 8411308Santhony.gutierrez@amd.com 8511308Santhony.gutierrez@amd.com if (ndRange.wg_disp_rem) 8611308Santhony.gutierrez@amd.com fatal("Checkpointing not supported during active workgroup execution"); 8711308Santhony.gutierrez@amd.com 8811308Santhony.gutierrez@amd.com if (tickEvent.scheduled()) 8911308Santhony.gutierrez@amd.com event_tick = tickEvent.when(); 9011308Santhony.gutierrez@amd.com 9111308Santhony.gutierrez@amd.com SERIALIZE_SCALAR(event_tick); 9211308Santhony.gutierrez@amd.com 9311308Santhony.gutierrez@amd.com} 9411308Santhony.gutierrez@amd.com 9511308Santhony.gutierrez@amd.comvoid 9611308Santhony.gutierrez@amd.comGpuDispatcher::unserialize(CheckpointIn &cp) 9711308Santhony.gutierrez@amd.com{ 9811308Santhony.gutierrez@amd.com Tick event_tick; 9911308Santhony.gutierrez@amd.com 10011308Santhony.gutierrez@amd.com if (tickEvent.scheduled()) 10111308Santhony.gutierrez@amd.com deschedule(&tickEvent); 10211308Santhony.gutierrez@amd.com 10311308Santhony.gutierrez@amd.com UNSERIALIZE_SCALAR(event_tick); 10411308Santhony.gutierrez@amd.com 10511308Santhony.gutierrez@amd.com if (event_tick) 10611308Santhony.gutierrez@amd.com schedule(&tickEvent, event_tick); 10711308Santhony.gutierrez@amd.com} 10811308Santhony.gutierrez@amd.com 10911308Santhony.gutierrez@amd.comAddrRangeList 11011308Santhony.gutierrez@amd.comGpuDispatcher::getAddrRanges() const 11111308Santhony.gutierrez@amd.com{ 11211308Santhony.gutierrez@amd.com AddrRangeList ranges; 11311308Santhony.gutierrez@amd.com 11411308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "dispatcher registering addr range at %#x size %#x\n", 11511308Santhony.gutierrez@amd.com pioAddr, pioSize); 11611308Santhony.gutierrez@amd.com 11711308Santhony.gutierrez@amd.com ranges.push_back(RangeSize(pioAddr, pioSize)); 11811308Santhony.gutierrez@amd.com 11911308Santhony.gutierrez@amd.com return ranges; 12011308Santhony.gutierrez@amd.com} 12111308Santhony.gutierrez@amd.com 12211308Santhony.gutierrez@amd.comTick 12311308Santhony.gutierrez@amd.comGpuDispatcher::read(PacketPtr pkt) 12411308Santhony.gutierrez@amd.com{ 12511308Santhony.gutierrez@amd.com assert(pkt->getAddr() >= pioAddr); 12611308Santhony.gutierrez@amd.com assert(pkt->getAddr() < pioAddr + pioSize); 12711308Santhony.gutierrez@amd.com 12811308Santhony.gutierrez@amd.com int offset = pkt->getAddr() - pioAddr; 12911308Santhony.gutierrez@amd.com pkt->allocate(); 13011308Santhony.gutierrez@amd.com 13111308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, " read register %#x size=%d\n", offset, pkt->getSize()); 13211308Santhony.gutierrez@amd.com 13311308Santhony.gutierrez@amd.com if (offset < 8) { 13411308Santhony.gutierrez@amd.com assert(!offset); 13511308Santhony.gutierrez@amd.com assert(pkt->getSize() == 8); 13611308Santhony.gutierrez@amd.com 13711308Santhony.gutierrez@amd.com uint64_t retval = dispatchActive; 13811308Santhony.gutierrez@amd.com pkt->set(retval); 13911308Santhony.gutierrez@amd.com } else { 14011308Santhony.gutierrez@amd.com offset -= 8; 14111308Santhony.gutierrez@amd.com assert(offset + pkt->getSize() < sizeof(HsaQueueEntry)); 14211308Santhony.gutierrez@amd.com char *curTaskPtr = (char*)&curTask; 14311308Santhony.gutierrez@amd.com 14411308Santhony.gutierrez@amd.com memcpy(pkt->getPtr<const void*>(), curTaskPtr + offset, pkt->getSize()); 14511308Santhony.gutierrez@amd.com } 14611308Santhony.gutierrez@amd.com 14711308Santhony.gutierrez@amd.com pkt->makeAtomicResponse(); 14811308Santhony.gutierrez@amd.com 14911308Santhony.gutierrez@amd.com return pioDelay; 15011308Santhony.gutierrez@amd.com} 15111308Santhony.gutierrez@amd.com 15211308Santhony.gutierrez@amd.comTick 15311308Santhony.gutierrez@amd.comGpuDispatcher::write(PacketPtr pkt) 15411308Santhony.gutierrez@amd.com{ 15511308Santhony.gutierrez@amd.com assert(pkt->getAddr() >= pioAddr); 15611308Santhony.gutierrez@amd.com assert(pkt->getAddr() < pioAddr + pioSize); 15711308Santhony.gutierrez@amd.com 15811308Santhony.gutierrez@amd.com int offset = pkt->getAddr() - pioAddr; 15911308Santhony.gutierrez@amd.com 16011308Santhony.gutierrez@amd.com#if TRACING_ON 16111308Santhony.gutierrez@amd.com uint64_t data_val = 0; 16211308Santhony.gutierrez@amd.com 16311308Santhony.gutierrez@amd.com switch (pkt->getSize()) { 16411308Santhony.gutierrez@amd.com case 1: 16511308Santhony.gutierrez@amd.com data_val = pkt->get<uint8_t>(); 16611308Santhony.gutierrez@amd.com break; 16711308Santhony.gutierrez@amd.com case 2: 16811308Santhony.gutierrez@amd.com data_val = pkt->get<uint16_t>(); 16911308Santhony.gutierrez@amd.com break; 17011308Santhony.gutierrez@amd.com case 4: 17111308Santhony.gutierrez@amd.com data_val = pkt->get<uint32_t>(); 17211308Santhony.gutierrez@amd.com break; 17311308Santhony.gutierrez@amd.com case 8: 17411308Santhony.gutierrez@amd.com data_val = pkt->get<uint64_t>(); 17511308Santhony.gutierrez@amd.com break; 17611308Santhony.gutierrez@amd.com default: 17711308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "bad size %d\n", pkt->getSize()); 17811308Santhony.gutierrez@amd.com } 17911308Santhony.gutierrez@amd.com 18011308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "write register %#x value %#x size=%d\n", offset, data_val, 18111308Santhony.gutierrez@amd.com pkt->getSize()); 18211308Santhony.gutierrez@amd.com#endif 18311308Santhony.gutierrez@amd.com if (!offset) { 18411308Santhony.gutierrez@amd.com static int nextId = 0; 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.com // The depends field of the qstruct, which was previously unused, is 18711308Santhony.gutierrez@amd.com // used to communicate with simulated application. 18811308Santhony.gutierrez@amd.com if (curTask.depends) { 18911308Santhony.gutierrez@amd.com HostState hs; 19011308Santhony.gutierrez@amd.com shader->ReadMem((uint64_t)(curTask.depends), &hs, 19111308Santhony.gutierrez@amd.com sizeof(HostState), 0); 19211308Santhony.gutierrez@amd.com 19311308Santhony.gutierrez@amd.com // update event start time (in nano-seconds) 19411308Santhony.gutierrez@amd.com uint64_t start = curTick() / 1000; 19511308Santhony.gutierrez@amd.com 19611308Santhony.gutierrez@amd.com shader->WriteMem((uint64_t)(&((_cl_event*)hs.event)->start), 19711308Santhony.gutierrez@amd.com &start, sizeof(uint64_t), 0); 19811308Santhony.gutierrez@amd.com } 19911308Santhony.gutierrez@amd.com 20011308Santhony.gutierrez@amd.com // launch kernel 20111308Santhony.gutierrez@amd.com ++num_kernelLaunched; 20211308Santhony.gutierrez@amd.com 20311308Santhony.gutierrez@amd.com NDRange *ndr = &(ndRangeMap[nextId]); 20411308Santhony.gutierrez@amd.com // copy dispatch info 20511308Santhony.gutierrez@amd.com ndr->q = curTask; 20611308Santhony.gutierrez@amd.com 20711308Santhony.gutierrez@amd.com // update the numDispTask polled by the runtime 20811308Santhony.gutierrez@amd.com accessUserVar(cpu, (uint64_t)(curTask.numDispLeft), 0, 1); 20911308Santhony.gutierrez@amd.com 21011308Santhony.gutierrez@amd.com ndr->numWgTotal = 1; 21111308Santhony.gutierrez@amd.com 21211308Santhony.gutierrez@amd.com for (int i = 0; i < 3; ++i) { 21311308Santhony.gutierrez@amd.com ndr->wgId[i] = 0; 21411308Santhony.gutierrez@amd.com ndr->numWg[i] = divCeil(curTask.gdSize[i], curTask.wgSize[i]); 21511308Santhony.gutierrez@amd.com ndr->numWgTotal *= ndr->numWg[i]; 21611308Santhony.gutierrez@amd.com } 21711308Santhony.gutierrez@amd.com 21811308Santhony.gutierrez@amd.com ndr->numWgCompleted = 0; 21911308Santhony.gutierrez@amd.com ndr->globalWgId = 0; 22011308Santhony.gutierrez@amd.com ndr->wg_disp_rem = true; 22111308Santhony.gutierrez@amd.com ndr->execDone = false; 22211308Santhony.gutierrez@amd.com ndr->addrToNotify = (volatile bool*)curTask.addrToNotify; 22311308Santhony.gutierrez@amd.com ndr->numDispLeft = (volatile uint32_t*)curTask.numDispLeft; 22411308Santhony.gutierrez@amd.com ndr->dispatchId = nextId; 22511435Smitch.hayenga@arm.com ndr->curCid = pkt->req->contextId(); 22611308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "launching kernel %d\n",nextId); 22711308Santhony.gutierrez@amd.com execIds.push(nextId); 22811308Santhony.gutierrez@amd.com ++nextId; 22911308Santhony.gutierrez@amd.com 23011308Santhony.gutierrez@amd.com dispatchActive = true; 23111308Santhony.gutierrez@amd.com 23211308Santhony.gutierrez@amd.com if (!tickEvent.scheduled()) { 23311308Santhony.gutierrez@amd.com schedule(&tickEvent, curTick() + shader->ticks(1)); 23411308Santhony.gutierrez@amd.com } 23511308Santhony.gutierrez@amd.com } else { 23611308Santhony.gutierrez@amd.com // populate current task struct 23711308Santhony.gutierrez@amd.com // first 64 bits are launch reg 23811308Santhony.gutierrez@amd.com offset -= 8; 23911308Santhony.gutierrez@amd.com assert(offset < sizeof(HsaQueueEntry)); 24011308Santhony.gutierrez@amd.com char *curTaskPtr = (char*)&curTask; 24111308Santhony.gutierrez@amd.com memcpy(curTaskPtr + offset, pkt->getPtr<const void*>(), pkt->getSize()); 24211308Santhony.gutierrez@amd.com } 24311308Santhony.gutierrez@amd.com 24411308Santhony.gutierrez@amd.com pkt->makeAtomicResponse(); 24511308Santhony.gutierrez@amd.com 24611308Santhony.gutierrez@amd.com return pioDelay; 24711308Santhony.gutierrez@amd.com} 24811308Santhony.gutierrez@amd.com 24911308Santhony.gutierrez@amd.com 25011308Santhony.gutierrez@amd.comBaseMasterPort& 25111308Santhony.gutierrez@amd.comGpuDispatcher::getMasterPort(const std::string &if_name, PortID idx) 25211308Santhony.gutierrez@amd.com{ 25311308Santhony.gutierrez@amd.com if (if_name == "translation_port") { 25411308Santhony.gutierrez@amd.com return *tlbPort; 25511308Santhony.gutierrez@amd.com } 25611308Santhony.gutierrez@amd.com 25711308Santhony.gutierrez@amd.com return DmaDevice::getMasterPort(if_name, idx); 25811308Santhony.gutierrez@amd.com} 25911308Santhony.gutierrez@amd.com 26011308Santhony.gutierrez@amd.comvoid 26111308Santhony.gutierrez@amd.comGpuDispatcher::exec() 26211308Santhony.gutierrez@amd.com{ 26311308Santhony.gutierrez@amd.com int fail_count = 0; 26411308Santhony.gutierrez@amd.com 26511308Santhony.gutierrez@amd.com // There are potentially multiple outstanding kernel launches. 26611308Santhony.gutierrez@amd.com // It is possible that the workgroups in a different kernel 26711308Santhony.gutierrez@amd.com // can fit on the GPU even if another kernel's workgroups cannot 26811308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "Launching %d Kernels\n", execIds.size()); 26911308Santhony.gutierrez@amd.com 27011308Santhony.gutierrez@amd.com while (execIds.size() > fail_count) { 27111308Santhony.gutierrez@amd.com int execId = execIds.front(); 27211308Santhony.gutierrez@amd.com 27311308Santhony.gutierrez@amd.com while (ndRangeMap[execId].wg_disp_rem) { 27411308Santhony.gutierrez@amd.com //update the thread context 27511435Smitch.hayenga@arm.com shader->updateContext(ndRangeMap[execId].curCid); 27611308Santhony.gutierrez@amd.com 27711308Santhony.gutierrez@amd.com // attempt to dispatch_workgroup 27811308Santhony.gutierrez@amd.com if (!shader->dispatch_workgroups(&ndRangeMap[execId])) { 27911308Santhony.gutierrez@amd.com // if we failed try the next kernel, 28011308Santhony.gutierrez@amd.com // it may have smaller workgroups. 28111308Santhony.gutierrez@amd.com // put it on the queue to rety latter 28211308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "kernel %d failed to launch\n", execId); 28311308Santhony.gutierrez@amd.com execIds.push(execId); 28411308Santhony.gutierrez@amd.com ++fail_count; 28511308Santhony.gutierrez@amd.com break; 28611308Santhony.gutierrez@amd.com } 28711308Santhony.gutierrez@amd.com } 28811308Santhony.gutierrez@amd.com // let's try the next kernel_id 28911308Santhony.gutierrez@amd.com execIds.pop(); 29011308Santhony.gutierrez@amd.com } 29111308Santhony.gutierrez@amd.com 29211308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "Returning %d Kernels\n", doneIds.size()); 29311308Santhony.gutierrez@amd.com 29411308Santhony.gutierrez@amd.com if (doneIds.size() && cpu) { 29511308Santhony.gutierrez@amd.com shader->hostWakeUp(cpu); 29611308Santhony.gutierrez@amd.com } 29711308Santhony.gutierrez@amd.com 29811308Santhony.gutierrez@amd.com while (doneIds.size()) { 29911308Santhony.gutierrez@amd.com // wakeup the CPU if any Kernels completed this cycle 30011308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "WorkGroup %d completed\n", doneIds.front()); 30111308Santhony.gutierrez@amd.com doneIds.pop(); 30211308Santhony.gutierrez@amd.com } 30311308Santhony.gutierrez@amd.com} 30411308Santhony.gutierrez@amd.com 30511308Santhony.gutierrez@amd.comvoid 30611308Santhony.gutierrez@amd.comGpuDispatcher::notifyWgCompl(Wavefront *w) 30711308Santhony.gutierrez@amd.com{ 30811308Santhony.gutierrez@amd.com int kern_id = w->kern_id; 30911308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "notify WgCompl %d\n",kern_id); 31011308Santhony.gutierrez@amd.com assert(ndRangeMap[kern_id].dispatchId == kern_id); 31111308Santhony.gutierrez@amd.com ndRangeMap[kern_id].numWgCompleted++; 31211308Santhony.gutierrez@amd.com 31311308Santhony.gutierrez@amd.com if (ndRangeMap[kern_id].numWgCompleted == ndRangeMap[kern_id].numWgTotal) { 31411308Santhony.gutierrez@amd.com ndRangeMap[kern_id].execDone = true; 31511308Santhony.gutierrez@amd.com doneIds.push(kern_id); 31611308Santhony.gutierrez@amd.com 31711308Santhony.gutierrez@amd.com if (ndRangeMap[kern_id].addrToNotify) { 31811308Santhony.gutierrez@amd.com accessUserVar(cpu, (uint64_t)(ndRangeMap[kern_id].addrToNotify), 1, 31911308Santhony.gutierrez@amd.com 0); 32011308Santhony.gutierrez@amd.com } 32111308Santhony.gutierrez@amd.com 32211308Santhony.gutierrez@amd.com accessUserVar(cpu, (uint64_t)(ndRangeMap[kern_id].numDispLeft), 0, -1); 32311308Santhony.gutierrez@amd.com 32411308Santhony.gutierrez@amd.com // update event end time (in nano-seconds) 32511308Santhony.gutierrez@amd.com if (ndRangeMap[kern_id].q.depends) { 32611308Santhony.gutierrez@amd.com HostState *host_state = (HostState*)ndRangeMap[kern_id].q.depends; 32711308Santhony.gutierrez@amd.com uint64_t event; 32811308Santhony.gutierrez@amd.com shader->ReadMem((uint64_t)(&host_state->event), &event, 32911308Santhony.gutierrez@amd.com sizeof(uint64_t), 0); 33011308Santhony.gutierrez@amd.com 33111308Santhony.gutierrez@amd.com uint64_t end = curTick() / 1000; 33211308Santhony.gutierrez@amd.com 33311308Santhony.gutierrez@amd.com shader->WriteMem((uint64_t)(&((_cl_event*)event)->end), &end, 33411308Santhony.gutierrez@amd.com sizeof(uint64_t), 0); 33511308Santhony.gutierrez@amd.com } 33611308Santhony.gutierrez@amd.com } 33711308Santhony.gutierrez@amd.com 33811308Santhony.gutierrez@amd.com if (!tickEvent.scheduled()) { 33911308Santhony.gutierrez@amd.com schedule(&tickEvent, curTick() + shader->ticks(1)); 34011308Santhony.gutierrez@amd.com } 34111308Santhony.gutierrez@amd.com} 34211308Santhony.gutierrez@amd.com 34311308Santhony.gutierrez@amd.comvoid 34411308Santhony.gutierrez@amd.comGpuDispatcher::scheduleDispatch() 34511308Santhony.gutierrez@amd.com{ 34611308Santhony.gutierrez@amd.com if (!tickEvent.scheduled()) 34711308Santhony.gutierrez@amd.com schedule(&tickEvent, curTick() + shader->ticks(1)); 34811308Santhony.gutierrez@amd.com} 34911308Santhony.gutierrez@amd.com 35011308Santhony.gutierrez@amd.comvoid 35111308Santhony.gutierrez@amd.comGpuDispatcher::accessUserVar(BaseCPU *cpu, uint64_t addr, int val, int off) 35211308Santhony.gutierrez@amd.com{ 35311308Santhony.gutierrez@amd.com if (cpu) { 35411308Santhony.gutierrez@amd.com if (off) { 35511308Santhony.gutierrez@amd.com shader->AccessMem(addr, &val, sizeof(int), 0, MemCmd::ReadReq, 35611308Santhony.gutierrez@amd.com true); 35711308Santhony.gutierrez@amd.com val += off; 35811308Santhony.gutierrez@amd.com } 35911308Santhony.gutierrez@amd.com 36011308Santhony.gutierrez@amd.com shader->AccessMem(addr, &val, sizeof(int), 0, MemCmd::WriteReq, true); 36111308Santhony.gutierrez@amd.com } else { 36211308Santhony.gutierrez@amd.com panic("Cannot find host"); 36311308Santhony.gutierrez@amd.com } 36411308Santhony.gutierrez@amd.com} 36511308Santhony.gutierrez@amd.com 36611308Santhony.gutierrez@amd.comGpuDispatcher::TickEvent::TickEvent(GpuDispatcher *_dispatcher) 36711308Santhony.gutierrez@amd.com : Event(CPU_Tick_Pri), dispatcher(_dispatcher) 36811308Santhony.gutierrez@amd.com{ 36911308Santhony.gutierrez@amd.com} 37011308Santhony.gutierrez@amd.com 37111308Santhony.gutierrez@amd.comvoid 37211308Santhony.gutierrez@amd.comGpuDispatcher::TickEvent::process() 37311308Santhony.gutierrez@amd.com{ 37411308Santhony.gutierrez@amd.com dispatcher->exec(); 37511308Santhony.gutierrez@amd.com} 37611308Santhony.gutierrez@amd.com 37711308Santhony.gutierrez@amd.comconst char* 37811308Santhony.gutierrez@amd.comGpuDispatcher::TickEvent::description() const 37911308Santhony.gutierrez@amd.com{ 38011308Santhony.gutierrez@amd.com return "GPU Dispatcher tick"; 38111308Santhony.gutierrez@amd.com} 38211308Santhony.gutierrez@amd.com 38311308Santhony.gutierrez@amd.com// helper functions for driver to retrieve GPU attributes 38411308Santhony.gutierrez@amd.comint 38511308Santhony.gutierrez@amd.comGpuDispatcher::getNumCUs() 38611308Santhony.gutierrez@amd.com{ 38711308Santhony.gutierrez@amd.com return shader->cuList.size(); 38811308Santhony.gutierrez@amd.com} 38911308Santhony.gutierrez@amd.com 39011534Sjohn.kalamatianos@amd.comint 39111534Sjohn.kalamatianos@amd.comGpuDispatcher::wfSize() const 39211534Sjohn.kalamatianos@amd.com{ 39311534Sjohn.kalamatianos@amd.com return shader->cuList[0]->wfSize(); 39411534Sjohn.kalamatianos@amd.com} 39511534Sjohn.kalamatianos@amd.com 39611308Santhony.gutierrez@amd.comvoid 39711308Santhony.gutierrez@amd.comGpuDispatcher::setFuncargsSize(int funcargs_size) 39811308Santhony.gutierrez@amd.com{ 39911308Santhony.gutierrez@amd.com shader->funcargs_size = funcargs_size; 40011308Santhony.gutierrez@amd.com} 401