2017-04-26 17:20:15 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Copyright (c) 1994 Stanford University */
|
|
|
|
/* */
|
|
|
|
/* All rights reserved. */
|
|
|
|
/* */
|
|
|
|
/* Permission is given to use, copy, and modify this software for any */
|
|
|
|
/* non-commercial purpose as long as this copyright notice is not */
|
|
|
|
/* removed. All other uses, including redistribution in whole or in */
|
|
|
|
/* part, are forbidden without prior written permission. */
|
|
|
|
/* */
|
|
|
|
/* This software is provided with absolutely no warranty and no */
|
|
|
|
/* support. */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* workpool.c
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* This file contains the private data definitions and code for the ray
|
|
|
|
* job work pool. Each processor has its own workpool.
|
|
|
|
*
|
|
|
|
* The workpool consists of a stack of pixel bundles. Each bundle
|
|
|
|
* contains jobs for primary rays for a contiguous 2D pixel screen
|
|
|
|
* region.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
2017-04-26 17:20:15 +02:00
|
|
|
#include "rt.h"
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
|
|
|
|
|
2017-04-26 17:20:15 +02:00
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* PutJob - put another job into pid's work pool
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* VOID PutJob(xs, ys, xe, ye, xbe, ybe, pid)
|
|
|
|
* INT xs, ys; // Start of block.
|
|
|
|
* INT xe, ye; // Extent of block.
|
|
|
|
* INT xbe, ybe; // Extent of bundle.
|
|
|
|
* INT pid; // Process id.
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* Given a block of image screen pixels, this routine generates pixel
|
|
|
|
* bundle entries that are inserted into pid's work pool stack.
|
|
|
|
*
|
|
|
|
* A block includes the starting pixel address, the block size in x and y
|
|
|
|
* dimensions and the bundle size for making pixel jobs.
|
|
|
|
*
|
|
|
|
* Pixel addresses are 0 relative.
|
|
|
|
*
|
|
|
|
* Locking of workpools for job insertion is not required since a given
|
|
|
|
* process only inserts into its own pool and since we use a BARRIER
|
|
|
|
* before jobs can be removed from workpools.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID PutJob(INT xs, INT ys, INT xe, INT ye, INT xbe, INT ybe, INT pid)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
INT i, j;
|
|
|
|
INT xb_addr, yb_addr; /* Bundle pixel address. */
|
|
|
|
INT xb_end, yb_end; /* End bundle pixels. */
|
|
|
|
INT xb_size, yb_size; /* Bundle size. */
|
|
|
|
WPJOB *wpentry; /* New work pool entry. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Starting block pixel address (upper left pixel). */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
xb_addr = xs;
|
|
|
|
yb_addr = ys;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Ending block pixel address (lower right pixel). */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
xb_end = xb_addr + xe - 1;
|
|
|
|
yb_end = yb_addr + ye - 1;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
for (i = 0; i < ye; i += ybe)
|
|
|
|
{
|
|
|
|
for (j = 0; j < xe; j += xbe)
|
|
|
|
{
|
|
|
|
/* Determine bundle size. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if ((xb_addr + xbe - 1) <= xb_end)
|
|
|
|
xb_size = xbe;
|
|
|
|
else
|
|
|
|
xb_size = xb_end - xb_addr + 1;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if ((yb_addr + ybe - 1) <= yb_end)
|
|
|
|
yb_size = ybe;
|
|
|
|
else
|
|
|
|
yb_size = yb_end - yb_addr + 1;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Initialize work pool entry. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
wpentry = GlobalMalloc(sizeof(WPJOB), "workpool.c");
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
wpentry->xpix = xb_addr;
|
|
|
|
wpentry->ypix = yb_addr;
|
|
|
|
wpentry->xdim = xb_size;
|
|
|
|
wpentry->ydim = yb_size;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Add to top of work pool stack. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (!gm->workpool[pid][0])
|
|
|
|
wpentry->next = NULL;
|
|
|
|
else
|
|
|
|
wpentry->next = gm->workpool[pid][0];
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
gm->workpool[pid][0] = wpentry;
|
|
|
|
xb_addr += xbe;
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
xb_addr = xs;
|
|
|
|
yb_addr += ybe;
|
|
|
|
}
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* GetJob - get next job from pid's work pool
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* INT GetJob(job, pid)
|
|
|
|
* RAYJOB *job; // Ray job description.
|
|
|
|
* INT pid; // Process id.
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* Return a primary ray job bundle from the top of the stack. A ray job
|
|
|
|
* bundle consists of the starting primary ray pixel address and the size
|
|
|
|
* of the pixel bundle.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Work pool status code.
|
|
|
|
*/
|
|
|
|
|
|
|
|
INT GetJob(RAYJOB *job, INT pid)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
WPJOB *wpentry; /* Work pool entry. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
ALOCK(gm->wplock, pid)
|
|
|
|
wpentry = gm->workpool[pid][0];
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (!wpentry)
|
|
|
|
{
|
|
|
|
gm->wpstat[pid][0] = WPS_EMPTY;
|
|
|
|
AULOCK(gm->wplock, pid)
|
|
|
|
return (WPS_EMPTY);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
gm->workpool[pid][0] = wpentry->next;
|
|
|
|
AULOCK(gm->wplock, pid)
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Set up ray job information. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
job->x = wpentry->xpix;
|
|
|
|
job->y = wpentry->ypix;
|
|
|
|
job->xcurr = wpentry->xpix;
|
|
|
|
job->ycurr = wpentry->ypix;
|
|
|
|
job->xlen = wpentry->xdim;
|
|
|
|
job->ylen = wpentry->ydim;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
GlobalFree(wpentry);
|
|
|
|
return (WPS_VALID);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* GetJobs - get next job for pid (with job stealing)
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* INT GetJobs(job, pid)
|
|
|
|
* RAYJOB *job; // Ray job pointer from work pool.
|
|
|
|
* INT pid; // Process id.
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Workpool status.
|
|
|
|
*/
|
|
|
|
|
|
|
|
INT GetJobs(RAYJOB *job, INT pid)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
INT i;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
i = pid;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* First, try to get job from pid's own pool (or pool 0). */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (gm->wpstat[i][0] == WPS_VALID)
|
|
|
|
if (GetJob(job, i) == WPS_VALID)
|
|
|
|
{
|
|
|
|
return (WPS_VALID);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/*
|
|
|
|
* If that failed, try to get job from another pid's work
|
|
|
|
* pool.
|
|
|
|
*/
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
i = (pid + 1) % gm->nprocs;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
while (i != pid)
|
|
|
|
{
|
|
|
|
if (gm->wpstat[i][0] == WPS_VALID)
|
|
|
|
if (GetJob(job, i) == WPS_VALID)
|
|
|
|
{
|
|
|
|
return (WPS_VALID);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
i = (i + 1) % gm->nprocs;
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
return (WPS_EMPTY);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* PrintWorkPool - print out the work pool entries for a given process
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* VOID PrintWorkPool(pid)
|
|
|
|
* INT pid; // Process id.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID PrintWorkPool(INT pid)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
WPJOB *j;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
j = gm->workpool[pid][0];
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
while (j)
|
|
|
|
{
|
|
|
|
printf("Workpool entry: pid=%3ld xs=%3ld ys=%3ld xe=%3ld ye=%3ld\n", pid, j->xpix, j->ypix, j->xdim, j->ydim);
|
|
|
|
j = j->next;
|
|
|
|
}
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* InitWorkPool - fill pid's work pool with jobs
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* VOID InitWorkPool(pid)
|
|
|
|
* INT pid; // Process id to initialize.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID InitWorkPool(INT pid)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
INT i;
|
|
|
|
INT x, y;
|
|
|
|
INT xe, ye;
|
|
|
|
INT xsize, ysize;
|
|
|
|
|
|
|
|
gm->wpstat[pid][0] = WPS_VALID;
|
|
|
|
gm->workpool[pid][0] = NULL;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
xsize = Display.xres/blockx;
|
|
|
|
ysize = Display.yres/blocky;
|
|
|
|
|
|
|
|
for (y = 0; y < Display.yres; y += ysize)
|
|
|
|
{
|
|
|
|
if (y + ysize > Display.yres)
|
|
|
|
ye = Display.yres - y;
|
|
|
|
else
|
|
|
|
ye = ysize;
|
|
|
|
|
|
|
|
for (x = 0; x < Display.xres; x += xsize)
|
|
|
|
{
|
|
|
|
if (x + xsize > Display.xres)
|
|
|
|
xe = Display.xres - x;
|
|
|
|
else
|
|
|
|
xe = xsize;
|
|
|
|
|
|
|
|
if (i == pid)
|
|
|
|
PutJob(x, y, xe, ye, bundlex, bundley, pid);
|
|
|
|
|
|
|
|
i = (i + 1)%gm->nprocs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|