/*

Copyright (C) 2020 Olaf Till <i7tiol@t-online.de>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; If not, see <http://www.gnu.org/licenses/>.

*/

// PKG_ADD: autoload ("parcellfun_set_nproc", "__parcellfun_interface__.oct");
// PKG_DEL: autoload ("parcellfun_set_nproc", "__parcellfun_interface__.oct", "remove");


#include "parallel-gnutls.h"

namespace octave_parallel
{

  control &get_scheduler (void)
  {
    // FIXME: Should the executable be configurable?

    std::string empty_string;

    static octave_parallel::scheduler_watch sched_watch (empty_string);

    return sched_watch.get_good_sched ();
  }
}

DEFUN_DLD (parcellfun_set_nproc, args, nargout,
           "-*- texinfo -*-\n\
@deftypefn {Loadable Function} {@var{nproc} =} parcellfun_set_nproc (@var{nproc_arg})\n\
Set current number of background processes for parcellfun.\n\
\n\
The number of used background processes is determined by the first argument\n\
to @code{parcellfun}. If necessary, @code{parcellfun} will spawn new\n\
background processes, but it will never remove any of them, even if it\n\
does not use all of them.\n\
@code{parcellfun_set_nproc} can be used to set the number of currently spawned\n\
processes to @var{nproc_arg}. This may be used to remove all background\n\
processes between calls to @code{parcellfun} by specifying an @var{nproc_arg}\n\
of zero.\n\
\n\
The real number of spawned processes will be limited to the available\n\
processor cores and is returned.\n\
\n\
@seealso{parcellfun}\n\
@end deftypefn")
{
  std::string fname ("parcellfun_set_nproc");

  octave_value retval;

  if (args.length () != 1
      || ! args(0).OV_ISREAL ()
      || ! args(0).is_scalar_type ())
    {
      print_usage ();

      return retval;
    }

  octave_parallel::control &sched = octave_parallel::get_scheduler ();

  if (sched.set_nproc (args(0).int_value ())
      || ! sched.good ())
    {
      error ("%s: could not set number of processes", fname.c_str ());
    }
  else
    {
      retval = octave_value (sched.get_nproc ());
    }

  return retval;
}
