Ejemplo n.º 1
0
/*!
 * This method is executed as a task. It is very clarifying to see that local
 * variables are not preserved. The integers value1 and value2 are global 
 * variables, and their value is preserved under all the jump actions on the 
 * stack. However, value3 is a local variable. Incrementing it gives as result
 * -1076728219 on my machine.
 */
void *real_main(void * context) {
  int value3 = 22, *p_value3 = &value3;
  printf("\nDispatch increment tasks.\n");
  dispatch_task(inc, p_value1);
  dispatch_task(inc, p_value2);
  dispatch_task(inc, p_value3);
  printf("Tasks dispatched. You can see that the actual execution of those ");
  printf("tasks is later on.\n\n");
  return NULL;
}
Ejemplo n.º 2
0
END_TEST

START_TEST(test_one)
  {
  int rc;
  initialize_all_tasks_array(&task_list_event);
  initialize_task_recycler();

  if (task_list_timed == NULL)
    task_list_timed = new std::list<timed_task>();

  rc = initialize_threadpool(&request_pool, 5, 50, 60);
  fail_unless(rc == PBSE_NONE, "initalize_threadpool failed", rc);

  struct work_task *pWorkTask = set_task(WORK_Timed,357,check_nodes,NULL,0);
  fail_unless(pWorkTask != NULL);
  struct work_task *pWorkTask2 = set_task(WORK_Timed,356,check_nodes,NULL,0);
  fail_unless(pWorkTask2 != NULL);
  struct work_task *pWorkTask3 = set_task(WORK_Timed,358,check_nodes,NULL,0);
  fail_unless(pWorkTask3 != NULL);

  rc = dispatch_task(pWorkTask);
  fail_unless(rc == PBSE_NONE, "dispatch_task failed", rc);
  delete_task(pWorkTask);

  int iter = -1;
  struct work_task *pRecycled = next_task_from_recycler(&tr.tasks,&iter);
  fprintf(stderr,"%p %p\n",(void *)pWorkTask,(void *)pRecycled);
  fail_unless(pRecycled == pWorkTask);
  fail_unless(task_is_in_threadpool(pWorkTask2));
  }
Ejemplo n.º 3
0
time_t
default_next_task(void)
{

	time_t		   delay;
	struct work_task  *nxt;
	struct work_task  *ptask;

	/*
	 * tilwhen is the basic "idle" time if there is nothing pending sooner
	 * for the Server (timed-events, call scheduler, IO)
	 * It used to be 10, but that caused a delay of outgoing RPP packets
	 * in some cases, and we don't burn too many extr cycles doing nothing
	 * if the delay is shorted to 2.
	 */
	time_t		   tilwhen = 2;  /* basic cycle time */


	time_now = time((time_t *)0);

	if (svr_delay_entry) {
		ptask = (struct work_task *)GET_NEXT(task_list_event);
		while (ptask) {
			nxt = (struct work_task *)GET_NEXT(ptask->wt_linkall);
			if (ptask->wt_type == WORK_Deferred_Cmp)
				dispatch_task(ptask);
			ptask = nxt;
		}
		svr_delay_entry = 0;
	}

	while ((ptask=(struct work_task *)GET_NEXT(task_list_immed)) != NULL)
		dispatch_task(ptask);

	while ((ptask=(struct work_task *)GET_NEXT(task_list_timed))!=NULL) {
		if ((delay = ptask->wt_event - time_now) > 0) {
			if (tilwhen > delay)
				tilwhen = delay;
			break;
		} else {
			dispatch_task(ptask);	/* will delete link */
		}

	}

	return (tilwhen);
}
Ejemplo n.º 4
0
void process_Dreply(

  int sock)

  {
  int    handle;

  struct work_task *ptask;
  int    rc;

  struct batch_request *request;

  /* find the work task for the socket, it will point us to the request */

  ptask = (struct work_task *)GET_NEXT(task_list_event);

  handle = svr_conn[sock].cn_handle;

  while (ptask != NULL)
    {
    if ((ptask->wt_type == WORK_Deferred_Reply) &&
        (ptask->wt_event == handle))
      break;

    ptask = (struct work_task *)GET_NEXT(ptask->wt_linkall);
    }

  if (ptask == NULL)
    {
    log_err(-1, "process_Dreply", msg_err_malloc);

    close_conn(sock);

    return;
    }

  request = ptask->wt_parm1;

  /* read and decode the reply */

  if ((rc = DIS_reply_read(sock, &request->rq_reply)) != 0)
    {
    close_conn(sock);

    request->rq_reply.brp_code = rc;
    request->rq_reply.brp_choice = BATCH_REPLY_CHOICE_NULL;
    }

  /* now dispatch the reply to the routine in the work task */

  dispatch_task(ptask);

  return;
  }  /* END process_Dreply() */
Ejemplo n.º 5
0
/*! \brief
 * A bootstrapping (pseudo-)main. Initializes and starts the abbey.  
 * 
 * In the real_main method the first task is dispatched. This task will
 * dispatch others, etc.
 */
int main() 
{
  printf("---------------------\n");
  printf("Starting the engines!\n");
  printf("---------------------\n");
  initialize_abbey(2, 4);
  printf("Dispatch main task.\n");
  dispatch_task(real_main, NULL);
  printf("Main task dispatched.\n");
  start_abbey();
  //what follows is unreachable, abbey starts scheduling forever
  printf("Hi, I will never be printed FWIW.\n");
  return 0;
}
Ejemplo n.º 6
0
struct mpi_queue_task *mpi_queue_wait(struct mpi_queue *q, int timeout)
{
	struct mpi_queue_task *t;
	time_t stoptime;
	int result;

	if(timeout == MPI_QUEUE_WAITFORTASK) {
		stoptime = 0;
	} else {
		stoptime = time(0) + timeout;
	}


	while(1) {
		// If a task is already complete, return it
		t = list_pop_head(q->complete_list);
		if(t)
			return t;

		if(list_size(q->ready_list) == 0 && itable_size(q->active_list) == 0)
			break;

		// Wait no longer than the caller's patience.
		int msec;
		int sec;
		if(stoptime) {
			sec = MAX(0, stoptime - time(0));
			msec = sec * 1000;
		} else {
			sec = 5;
			msec = 5000;
		}

		if(!q->mpi_link) {
			q->mpi_link = link_accept(q->master_link, stoptime);
			if(q->mpi_link) {
				char working_dir[MPI_QUEUE_LINE_MAX];
				link_tune(q->mpi_link, LINK_TUNE_INTERACTIVE);
				link_usleep(q->mpi_link, msec, 0, 1);
				getcwd(working_dir, MPI_QUEUE_LINE_MAX);
				link_putfstring(q->mpi_link, "workdir %s\n", stoptime, working_dir);
				result = link_usleep(q->mpi_link, msec, 1, 1);
			} else {
				result = 0;
			}
		} else {
			debug(D_MPI, "Waiting for link to be ready\n");
			result = link_usleep(q->mpi_link, msec, 1, 1);
		}

		// If nothing was awake, restart the loop or return without a task.
		if(result <= 0) {
			if(stoptime && time(0) >= stoptime) {
				return 0;
			} else {
				continue;
			}
		}

		debug(D_MPI, "sending %d tasks to the MPI master process\n", list_size(q->ready_list));
		// Send all ready tasks to the MPI master process
		while(list_size(q->ready_list)) {
			struct mpi_queue_task *t = list_pop_head(q->ready_list);
			result = dispatch_task(q->mpi_link, t, msec/1000);
			if(result <= 0)
				return 0;
			itable_insert(q->active_list, t->taskid, t);
		}

		// Receive any results back
		result = get_results(q->mpi_link, q->active_list, q->complete_list, msec/1000);
		if(result < 0) {
			return 0;
		}
	}

	return 0;
}
Ejemplo n.º 7
0
/**
 * @brief
 * 		process the reply received for a request issued to
 *		  another server via issue_request()
 *
 * 		Reads the reply from the RPP stream and executes the work task associated
 * 		with the RPP reply message. The RPP request for which this reply arrived
 * 		is matched by comparing the msgid of the reply with the msgid of the work
 * 		tasks stored in the msr_deferred_cmds list of the mom for this stream.
 *
 * @param[in] handle - RPP handle on which reply/close arrived
 *
 * @return void
 */
void
process_DreplyRPP(int handle)
{
	struct work_task	*ptask;
	int			 rc;
	struct batch_request	*request;
	struct batch_reply *reply;
	char 		*msgid = NULL;
	mominfo_t *pmom = 0;

	if ((pmom = tfind2((u_long) handle, 0, &streams)) == NULL)
		return;

	DIS_rpp_reset();

	/* find the work task for the socket, it will point us to the request */
	msgid = disrst(handle, &rc);

	if (!msgid || rc) { /* rpp connection actually broke, cull all pending requests */
		while ((ptask = (struct work_task *)GET_NEXT((((mom_svrinfo_t *) (pmom->mi_data))->msr_deferred_cmds)))) {
			/* no need to compare wt_event with handle, since the
			 * task list is for this mom and so it will always match
			 */
			if (ptask->wt_type == WORK_Deferred_Reply) {
				request = ptask->wt_parm1;
				if (request) {
					request->rq_reply.brp_code = rc;
					request->rq_reply.brp_choice = BATCH_REPLY_CHOICE_NULL;
				}
			}

			ptask->wt_aux = PBSE_NORELYMOM;
			pbs_errno = PBSE_NORELYMOM;

			if (ptask->wt_event2)
				free(ptask->wt_event2);

			dispatch_task(ptask);
		}
	} else {
		/* we read msgid fine, so proceed to match it and process the respective task */

		/* get the task list */
		ptask = (struct work_task *)GET_NEXT((((mom_svrinfo_t *) (pmom->mi_data))->msr_deferred_cmds));

		while (ptask) {

			char *cmd_msgid = ptask->wt_event2;

			if (strcmp(cmd_msgid, msgid) == 0) {

				if (ptask->wt_type == WORK_Deferred_Reply)
					request = ptask->wt_parm1;
				else
					request = NULL;

				if (!request) {
					if ((reply = (struct batch_reply *) malloc(sizeof(struct batch_reply))) == 0) {
						delete_task(ptask);
						free(cmd_msgid);
						log_err(errno, msg_daemonname, "Out of memory creating batch reply");
						return;
					}
					(void) memset(reply, 0, sizeof(struct batch_reply));
				} else {
					reply = &request->rq_reply;
				}

				/* read and decode the reply */
				if ((rc = DIS_reply_read(handle, reply, 1)) != 0) {
					reply->brp_code = rc;
					reply->brp_choice = BATCH_REPLY_CHOICE_NULL;
					ptask->wt_aux = PBSE_NORELYMOM;
					pbs_errno = PBSE_NORELYMOM;
				} else {
					ptask->wt_aux = reply->brp_code;
					pbs_errno = reply->brp_code;
				}

				ptask->wt_parm3 = reply; /* set the reply in case callback fn uses without having a preq */

				dispatch_task(ptask);

				if (!request)
					PBSD_FreeReply(reply);

				free(cmd_msgid);

				break;
			}
			ptask = (struct work_task *) GET_NEXT(ptask->wt_linkobj2);
		}
		free(msgid); /* the msgid read should be free after use in matching */
	}
}
Ejemplo n.º 8
0
/**
 * @brief
 * 		process the reply received for a request issued to
 *		another server via issue_request() over TCP
 *
 * @param[in] sock - TCP socket over which reply arrived
 *
 * @return	void
 */
void
process_Dreply(int sock)
{
	int			 handle;
	struct work_task	*ptask;
	int			 rc;
	struct batch_request	*request;
#ifdef WIN32
	int                     i;
#endif

	conn_t *conn;
	conn = get_conn(sock);
	if(!conn)
		return;

	/* find the work task for the socket, it will point us to the request */

	ptask = (struct work_task *)GET_NEXT(task_list_event);

#ifdef WIN32
	handle = -1;
	for (i=0;i < PBS_MAX_CONNECTIONS; i++) {
		if (connection[i].ch_inuse && connection[i].ch_socket == sock) {
			handle = i;
			break;
		}
	}
#else
	handle = conn->cn_handle;
#endif

	while (ptask) {
		if ((ptask->wt_type == WORK_Deferred_Reply) &&
			(ptask->wt_event == handle))
			break;
		ptask = (struct work_task *)GET_NEXT(ptask->wt_linkall);
	}
	if (!ptask) {
		close_conn(sock);
		return;
	}

	request = ptask->wt_parm1;

	/* read and decode the reply */
	/* set long timeout on I/O   */

	pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_LONG;

	if ((rc = DIS_reply_read(sock, &request->rq_reply, 0)) != 0) {
		close_conn(sock);
		request->rq_reply.brp_code = rc;
		request->rq_reply.brp_choice = BATCH_REPLY_CHOICE_NULL;
	}
	pbs_tcp_timeout = PBS_DIS_TCP_TIMEOUT_SHORT;	/* short timeout */

	/* now dispatch the reply to the routine in the work task */

	dispatch_task(ptask);
	return;
}