Esempio n. 1
0
/* Registers a callback with the process waiter, but will not start the process waiter
 * if it is not running.  Note that this will not stop the process waiter if it is already
 * running.
 *
 * Callbacks will be removed if their watched pid is greater than -1 and the received
 * pid from 'wait()' equals the watched pid.  If the watched pid is less than 0, then
 * the callback will never be removed from the event list unless manually removed by
 * calling 'proc_waiter_deregister()'.
 *
 * Parameters:
 * 		pid: The process ID returned by 'wait()' that should call 'proc_exited' callback.
 * 			If <0, the callback will be called for any PID that is returned by 'wait()'.
 * 		proc_exited: The callback called when 'wait()' returns a PID that matches 'pid'.
 * 		user_data: Data to be passed to the callback when called. */
alib_error proc_waiter_register_no_start(int pid, proc_exited_cb proc_exited,
		void* user_data)
{
	if(!proc_waiter_is_initialized())
		return(ALIB_STATE_ERR);

	int err;
	proc_waiter* pw = malloc(sizeof(proc_waiter));
	if(!pw)return(ALIB_MEM_ERR);

	pw->pid = pid;
	pw->cb = proc_exited;
	pw->user_data = user_data;

	/* Ensure our globals are allocated. */
	if((err = allocate_globals()))
		goto f_error;

	/* Add the proc waiter to the list. */
	if(!ArrayList_add(PROC_WAITER_CB_LIST, pw))
	{
		err = ALIB_MEM_ERR;
		goto f_error;
	}
	else
		pthread_cond_broadcast(PROC_WAITER_T_COND);

	return(ALIB_OK);

f_error:
	free(pw);
	return(err);
}
Esempio n. 2
0
/* Thread safe version of 'proc_waiter_register()'.
 *
 * Locks the ArrayList mutex. */
alib_error proc_waiter_register_tsafe(int pid, proc_exited_cb proc_exited, void* user_data)
{
	allocate_globals();

	alib_error err;
	ArrayList_lock(PROC_WAITER_CB_LIST);
	err = proc_waiter_register(pid, proc_exited, user_data);
	ArrayList_unlock(PROC_WAITER_CB_LIST);

	return(err);
}
Esempio n. 3
0
int 
main(int argc, char *argv[])
{
	uint32_t num_objs = 0;
	uint32_t num_snaps = 0;
	uint32_t iters = 0;

	printf("Usage: <prog> <num_objs> <num_snaps> <num_iters>\n");

	if (argc >= 2) {
		num_objs = atoi(argv[1]);
	}
	if ((num_objs == 0) || (num_objs > MAX_OBJECTS)) {
		printf("Setting num_objs to MAX_OBJECTS=%u\n", MAX_OBJECTS);
		fflush(stdout);
		num_objs = MAX_OBJECTS;
	}

	if (argc >= 3) {
		num_snaps = atoi(argv[2]);
	}

	if ((num_snaps == 0) || (num_snaps > MAX_SNAPSHOTS)) {
		printf("Setting num_snaps to %u\n", MAX_SNAPSHOTS);
		fflush(stdout);
		num_snaps = MAX_SNAPSHOTS;
	}

	if (argc >= 4) {
		iters = atoi(argv[3]);
	}
	if (iters == 0) {
		iters = num_snaps + 1;
	}

	allocate_globals(num_objs);

	printf("Starting test with %u objs %u snapshots and %u iterations\n",
	        num_objs, num_snaps, iters);
	fflush(stdout);

	ZSInit(&zs_state);

	do_rw_test(num_objs, iters, num_snaps);
	do_rangeupdate_test(num_objs, iters, num_snaps);
	do_delete_test(num_objs, iters, num_snaps);
	do_quiesce_test(num_objs, iters, num_snaps);

	ZSShutdown(zs_state);

	return 0;
}
Esempio n. 4
0
/* Starts the thread.  If the thread is already running
 * ALIB_OK will be returned.
 *
 * Waiting for child processes to close is handled on a separate thread. */
alib_error proc_waiter_start()
{
	int err = allocate_globals();
	if(err)return(err);

	/* Make sure we don't call start at the same time from two different threads. */
	pthread_mutex_lock(PROC_WAITER_MUTEX);

	/* Setup the flags as needed. */
	flag_lower(&PROC_WAITER_FLAG_POLE, THREAD_STOP);

	if((PROC_WAITER_FLAG_POLE & THREAD_IS_RUNNING) &&
			(PROC_WAITER_FLAG_POLE & THREAD_CREATED))
	{
		err = ALIB_OK;
		goto f_unlock;
	}

	/* Check to see if we are still running. */
	if(PROC_WAITER_FLAG_POLE & THREAD_IS_RUNNING)
		proc_waiter_stop_now();

	/* Ensure our thread is cleaned up. */
	if(PROC_WAITER_FLAG_POLE & THREAD_CREATED)
		pthread_join(*PROC_WAITER_THREAD, NULL);

	/* Raise the THREAD_IS_RUNNING flag before creating the thread so that the flag
	 * will never misrepresent the state of the thread. */
	flag_raise(&PROC_WAITER_FLAG_POLE, THREAD_IS_RUNNING | THREAD_CREATED);
	if(pthread_create(PROC_WAITER_THREAD, NULL, thread_proc, NULL))
	{
		flag_lower(&PROC_WAITER_FLAG_POLE, THREAD_IS_RUNNING | THREAD_CREATED);
		err = ALIB_THREAD_ERR;
		goto f_unlock;
	}

f_unlock:
	pthread_mutex_unlock(PROC_WAITER_MUTEX);

	return(err);
}
Esempio n. 5
0
int spai
(matrix *A, matrix **spai_mat,
 FILE *messages_arg,   /* file for warning messages */
 double epsilon_arg,   /* tolerance */
 int nbsteps_arg,      /* max number of "improvement" steps per line */
 int max_arg,          /* max dimensions of I, q, etc. */
 int maxnew_arg,       /* max number of new entries per step */
 int cache_size_arg,   /* one of (1,2,3,4,5,6) indicting size of cache */
                       /* cache_size == 0 indicates no caching */
 int verbose_arg,
 int spar_arg,
 int lower_diag_arg,
 int upper_diag_arg,
 double tau_arg)
{
  matrix *M;
  int col,ierr;

  int cache_sizes[6];

  /* Only create resplot for the numprocs=1 case. */
  if (debug && (A->numprocs == 1)) {
    resplot_fptr = fopen("resplot","w");
    fprintf(resplot_fptr,
	    "ep=%5.5lf ns=%d mn=%d bs=%d\n",
	    epsilon_arg,nbsteps_arg,maxnew_arg,A->bs);
    fprintf(resplot_fptr,"\n");
    fprintf(resplot_fptr,"scol: scalar column number\n");
    fprintf(resplot_fptr,"srn:  scalar resnorm\n");
    fprintf(resplot_fptr,"bcol: block column number\n");
    fprintf(resplot_fptr,"brn:  block resnorm\n");
    fprintf(resplot_fptr,"* indicates epsilon not attained\n");
    fprintf(resplot_fptr,"\n");
    fprintf(resplot_fptr,"   scol   srn       bcol   brn\n");
  }


  start_col = 0;
  num_bad_cols = 0;

  cache_sizes[0] = 101;
  cache_sizes[1] = 503;
  cache_sizes[2] = 2503;
  cache_sizes[3] = 12503;
  cache_sizes[4] = 62501;
  cache_sizes[5] = 104743;



  if (verbose_arg && !A->myid) {
    if (spar_arg == 0)
       printf("\n\nComputing SPAI: epsilon = %f\n",epsilon_arg);
    else if (spar_arg == 1)
       printf("\n\nComputing SPAI: tau = %f\n",tau_arg);
    else if (spar_arg == 2)
       printf("\n\nComputing SPAI: # diagonals = %d\n",
       lower_diag_arg+upper_diag_arg+1);
    fflush(stdout);
  }

  epsilon = epsilon_arg;
  message = messages_arg;
  maxnew = maxnew_arg;
  max_dim = max_arg;

  /* Determine maximum number of scalar nonzeros
     for any column of M */
  if (spar_arg == 0)
    {
     nbsteps = nbsteps_arg;
     maxapi = A->max_block_size * (1 + maxnew*nbsteps);
    }
  else if(spar_arg == 1)
    {
     nbsteps = A->maxnz;
     maxapi = A->max_block_size * (1 + nbsteps);
    }
  else
    {
     nbsteps = lower_diag_arg+upper_diag_arg+1;
     maxapi = A->max_block_size * (1 + nbsteps);
    }
  allocate_globals(A);

#ifdef MPI
  MPI_Barrier(A->comm);
#endif

  if ((cache_size_arg < 0) || (cache_size_arg > 6)) {
    fprintf(stderr,"illegal cache size in spai\n");
    exit(1);
  }

  if (cache_size_arg > 0)
    ht = init_hash_table(cache_sizes[cache_size_arg-1]);

  M = clone_matrix(A);

  ndone = 0;
  Im_done = 0;
  all_done = 0;
  next_line = 0;

  /* Timing of SPAI starts here.
     In a "real production" code everything before this could be static.
  */
  if (verbose_arg) start_timer(ident_spai);

  if ((ierr = precompute_column_square_inverses(A)) != 0)  return ierr;

#ifdef MPI
  MPI_Barrier(A->comm);
#endif

  for (;;) {

    col = grab_Mline(A, M, A->comm);

    if (debug && col >= 0) {
      fprintf(fptr_dbg,"col=%d of %d\n",col,A->n);
      fflush(fptr_dbg);
    }

    if (col < 0 ) break;
    if ((ierr =
         spai_line(A,col,spar_arg,lower_diag_arg,upper_diag_arg,tau_arg,M)) != 0)  return ierr;

  }

#ifdef MPI

  say_Im_done(A,M);

  do {
    com_server(A,M);
  }
  while (! all_done);
  MPI_Barrier(A->comm);

#endif

#ifdef MPI
  MPI_Barrier(A->comm);
#endif

  if (verbose_arg) {
    stop_timer(ident_spai);
    report_times(ident_spai,"spai",0,A->comm);
  }

  free_globals(nbsteps);
  free_hash_table(ht);

  if (resplot_fptr) fclose(resplot_fptr);

  *spai_mat = M;
  return 0;

}