Changeset - 9a584f11d162
[Not reviewed]
default
0 1 0
Nathan Brink (binki) - 16 years ago 2009-07-15 13:16:53
ohnobinki@ohnopublishing.net
added and integrated blendjob_remove()
1 file changed with 41 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/server/distrend.c
Show inline comments
 
@@ -16,51 +16,53 @@
 
  You should have received a copy of the GNU Affero General Public License
 
  along with DistRen.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
*/
 

	
 
/* This file contains the code which both processes (renders) jobs as a slave, and the code which distributes frames to slaves after receiving them from the client portion of the codebase. */
 

	
 
 /* Just some notes -- Ethan Zonca
 
 * ++ Make data availible for other apps to parse
 
 * Server<==>Client Communication
 
 * Upload while rendering
 
 */
 

	
 

	
 
#include "execio.h"
 
#include "options.h"
 
#include <confuse.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <malloc.h>
 
#include <unistd.h> /* getopt */
 
#include <time.h>
 

	
 

	
 
/* internally defined funcs */
 
/*
 
  internally defined funcs's prototypes
 
*/
 
void status_report_generator();
 

	
 
void blendjob_remove(struct blendjob **head, struct blendjob *bj);
 

	
 
// Global Vars, try to cut down on these
 
int jobnum = 0; // The next job number to create in the queue
 
int hcfjob; // Highest consecutively finished job
 
int highest_jobnum; // The job number of the most recently created job, this is used when creating new jobs
 

	
 
/* ******************* Structs ************************ */
 

	
 
// Stores config info? editmycomment
 
struct distrend_config
 
{
 
  cfg_t *mycfg;
 
  struct options_common *options;
 
  struct distrend_listen **listens; /*< Null terminated array of structs */
 
};
 

	
 

	
 

	
 
/*
 
 frame[frame] Status Assignments:
 
  "NULL" - don't render me
 
  "0" - canceled
 
  "1" - unassigned
 
  "2" - assigned to slave
 
@@ -131,56 +133,58 @@ void finish_frame(struct blendjob *blend
 
  general_info.total_frames_rendered++; // Increase total frames var for stats
 
}
 

	
 

	
 
// **** Queuer: Adds files to the queue
 
void queue(struct blendjob *blendjob, int type, char *name, char *submitter, char *email, int priority, int mode, int spp, struct frameset *frameset) {
 
	// Type: 1 = blender, add more types later
 
	// jobnum is the next available job number
 
	if(type == 1){
 
    blendjob->name = name;
 
    blendjob->submitter = submitter;
 
    blendjob->email = email;
 
    blendjob->priority = priority;
 
    blendjob->frameset = frameset;
 
  }
 
  else{
 
    // Throw error.
 
  }
 
jobnum++; // Advance the jobnumber for the next queued job
 
}
 

	
 

	
 
/*
 
  Status Report Generator: figures out how much of the job is done, where jobnum corresponds to the job number
 

	
 
  blendjobs_head is a pointer to a pointer because the head of the blendjobs linked list may need to be changed by blendjob_remove
 
*/
 
void status_report_generator(struct blendjob *blendjobs_head)
 
void status_report_generator(struct blendjob **blendjobs_head)
 
{
 
  struct blendjob *blendjob_ptr;
 
  unsigned short workers_working; /*< used to count the total number of workers working */
 
  unsigned int numjobs; /*< used to track number of jobs */
 

	
 
  blendjob_ptr = blendjobs_head;
 
  blendjob_ptr = *blendjobs_head;
 
  workers_working = 0;
 
  numjobs = 0;
 
  
 
  while(blendjob_ptr)
 
    {
 
      if(blendjob_ptr->priority != 0)
 
	/* If the job is not done, scan it */
 
	{
 
	  unsigned int framecounter;  /*< to scan through frames */
 
	  unsigned long finished_frames; /*< variable that counts the completed frames */
 
	  unsigned int pending_frames; /*< variable that counts the assigned frames */
 
	  float percent_frames_finished;  /*< variable that stores the percent done of the blendjob */
 
	  unsigned int total_time;  /*< total time taken to render all the completed frames for a job */
 

	
 
	  framecounter = 0;
 
	  finished_frames = 0;
 
	  pending_frames = 0;
 
	  percent_frames_finished = 0;
 
	  total_time = 0;
 

	
 
	  while(framecounter < blendjob_ptr->total_frames)
 
	    /* scans through frames, based on their status it runs a statement(s) */
 
	    {
 
	      if(blendjob_ptr->frameset[framecounter].frame_status == 2)
 
@@ -193,48 +197,49 @@ void status_report_generator(struct blen
 
	      if(blendjob_ptr->frameset[framecounter].frame_status == 1)
 
		/* If the frame is assigned */
 
		{
 
		  pending_frames ++;
 
		  workers_working ++;
 
		}
 
	      
 
	      framecounter ++;
 
	    } /* while(framecounter < blendjob_ptr->total_frames) */
 

	
 
	  // find the percent of completed frames
 
	  percent_frames_finished = (finished_frames / blendjob_ptr->total_frames) * 100; /*< @LordofWar: extraneous parentheses! */
 

	
 
	  /* updates values in the blendjob struct */
 
	  blendjob_ptr->completed_frames = finished_frames;
 
	  blendjob_ptr->assigned_frames = pending_frames;
 
	  blendjob_ptr->percent_done = percent_frames_finished;
 
	  blendjob_ptr->avg_render_time = (total_time / finished_frames); /*< extraneous parentheses! */
 
	  blendjob_ptr->time_remaining = (blendjob_ptr->avg_render_time * (blendjob_ptr->total_frames - finished_frames)); /*< extraneous parentheses! */
 

	
 
	  if(finished_frames == blendjob_ptr->total_frames)
 
	    /* If all frames are complete */
 
	    {
 
	      blendjob_ptr->priority = 0; /*< set priority to zero to indicate job is complete */
 
	      blendjob_remove(blendjobs_head, blendjob_ptr); /*< remove this job from the linkedlist */
 
	      general_info.total_finished_jobs++; /*< add one to the total finished jobs */
 
	      
 
	    }
 
	  else if (finished_frames > blendjob_ptr->total_frames)
 
	    /* just in case ;-) */
 
	    {
 
	      fprintf(stderr, "%s:%d: finished_frames (%lu) > blendjob_ptr->total_frames (%d)",
 
		      __FILE__, __LINE__, 
 
		      finished_frames, 
 
		      blendjob_ptr->total_frames);
 
	      abort();
 
	    }
 
	}
 

	
 
      general_info.rendering_clients = workers_working; /*< should this be a +=? */
 
      
 
      blendjob_ptr = blendjob_ptr->next; /*< This is the essence of linked lists and iterating through them */
 
      numjobs ++;
 
    } /* while(blendjob_ptr) */
 
  
 
  general_info.jobs_in_queue = (highest_jobnum - general_info.total_finished_jobs); /*< extraneous parentheses! */
 
}
 

	
 

	
 
@@ -312,48 +317,80 @@ void blend_frame_watchdog(struct blendjo
 
{
 
  unsigned short int watchdog_forgiveness; /*< seconds to wait on a frame before re-assigning it */
 
  struct blendjob *blendjob_ptr;
 
  unsigned int counter;
 

	
 
  watchdog_forgiveness = 3; /*< hours of forgiveness before frame is re-assigned */
 
  blendjob_ptr = blendjob_head;
 

	
 
  for(blendjob_ptr = blendjob_head; blendjob_ptr; blendjob_ptr = blendjob_ptr->next)
 
    /* iterate through jobs */
 

	
 
    for(counter = 0; counter < blendjob_ptr->total_frames; counter ++)
 
      /* iterate through all frames for this job*/
 
      {
 
	if((blendjob_ptr->frameset[counter].start_time + (watchdog_forgiveness * 3600)) < clock()) 
 
	  /*
 
	    If frame is not completed within the number of hours specified by watchdog_forgiveness 
 
	    Then change the frame status to unassigned
 
	  */
 
	  blendjob_ptr->frameset[counter].frame_status = 0;
 
      }
 

	
 
}
 

	
 
/**
 
   Removes a blendjob from the blendjob linkelist.
 

	
 
   @arg head a double pointer. the head pointer will have to be changed if blendjob == *head. Thus, make sure that the pointer points to the pointer to the head that all functions use. (I'm going to come back to this and misunderstand myself ;-))
 
 */
 
void blendjob_remove(struct blendjob **head, struct blendjob *bj)
 
{
 
  struct blendjob *previous_blendjob;
 
  
 
  if(bj == *head)
 
    *head = bj->next;
 
  else
 
    {
 
      
 
      for(previous_blendjob = *head;
 
	  previous_blendjob
 
	    && previous_blendjob->next != bj; /*< stop on the blendjob that comes before bj */
 
	  previous_blendjob = previous_blendjob->next)
 
	/* all of the action is in the definition of the for loop itself */;
 
  
 
      /*
 
	This removes references to bj from the linked list. I.E., we now skip bj when iterating through the list
 
       */
 
      previous_blendjob->next = bj->next;
 
    }
 
  
 
  /* 
 
     @lordofwar: the magic deallocation of memory ;-)
 
   */
 
  free(bj);
 
}
 

	
 

	
 
/* ************************** Main ************************* */
 

	
 
int main(int argc, char *argv[])
 
{
 
//// Begin Getopt Sample, EDITME!Sometime
 
		   int aflag = 0;
 
	       int bflag = 0;
 
	       char *cvalue = NULL;
 
	       int index;
 
	       int c;
 

	
 
	       opterr = 0;
 

	
 
	       while ((c = getopt (argc, argv, "abc:")) != -1)
 
	         switch (c)
 
	           {
 
	           case 'a':
 
	             aflag = 1;
 
	             break;
 
	           case 'b':
 
	             bflag = 1;
 
	             break;
 
	           case 'c':
0 comments (0 inline, 0 general)