?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL_Interpreter: Multiprocessing Options Commands' ??
MODULE clm$set_disp_multipro_opts_cmds;

{ PURPOSE:
{   This module contains the processors for the set_multiprocessing_options command and the
{   display_multiprocessing_options command.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
*copyc clp$build_standard_title
*copyc clp$close_display
*copyc clp$convert_integer_to_string
*copyc clp$evaluate_parameters
*copyc clp$new_display_line
*copyc clp$open_display_reference
*copyc clp$put_display
*copyc clp$reset_for_next_display_page
*copyc jmp$get_multipro_options_r3
*copyc jmp$set_multiprocessing_r3
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
?? EJECT ??
*copyc clv$nil_display_control
?? OLDTITLE ??
?? NEWTITLE := 'clp$display_multipro_opt_cmd ', EJECT ??

{ PURPOSE:
{   The purpose of this command is to display the multiprocessing permissions imposed on a job.
{
{   DISPLAY_MULTIPROCESSING_OPTIONS, DISMO [ OUTPUT  =  <file reference> ]
{                                          [ STATUS  = <status variable> ]
{           output, o:  This parameter specifies the file to which the information
{                       is displayed.  Omission causes $OUTPUT to be used.
{           status :    see ERROR HANDLING.

  PROCEDURE [XDCL] clp$display_multipro_opt_cmd
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status );

{ PROCEDURE display_multiprocessing_options, display_multiprocessing_option, dismo (
{   output, o: file = $output
{   status )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 3] of clt$pdt_parameter_name,
      parameters: array [1 .. 2] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        default_value: string (7),
      recend,
      type2: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [91, 9, 17, 7, 38, 29, 89],
    clc$command, 3, 2, 0, 0, 0, 0, 2, ''], [
    ['O                              ',clc$abbreviation_entry, 1],
    ['OUTPUT                         ',clc$nominal_entry, 1],
    ['STATUS                         ',clc$nominal_entry, 2]],
    [
{ PARAMETER 1
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 7],
{ PARAMETER 2
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$file_type],
    '$output'],
{ PARAMETER 2
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$output = 1,
      p$status = 2;

    VAR
      pvt: array [1 .. 2] of clt$parameter_value;

*copy clv$display_variables
?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      clp$close_display (display_control, ignore_status);

    PROCEND abort_handler;
*copy clp$new_page_procedure
?? OLDTITLE ??
?? NEWTITLE := 'put_subtitle', EJECT ??

{ PURPOSE:
{   The display_multiprocessing_options command has no subtitles.  This is merely a dummy routine used to
{   keep the module consistant with those that do produce subtitles.

  PROCEDURE put_subtitle
    (VAR display_control: clt$display_control;
     VAR status: ost$status);

    status.normal := TRUE;

  PROCEND put_subtitle;
?? OLDTITLE, EJECT ??

    VAR
      data_string: string(35),
      display_control: clt$display_control,
      ignore_status: ost$status,
      multiprocessing_allowed: boolean,
      ring_attributes: amt$ring_attributes;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    jmp$get_multipro_options_r3 (multiprocessing_allowed, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF multiprocessing_allowed THEN
      data_string := ' Multiprocessing allowed';
    ELSE
      data_string := ' Multiprocessing not allowed';
    IFEND;

    display_control := clv$nil_display_control;
    #SPOIL (display_control);
    osp$establish_block_exit_hndlr (^abort_handler);

    ring_attributes.r1 := #RING (^ring_attributes);
    ring_attributes.r2 := #RING (^ring_attributes);
    ring_attributes.r3 := #RING (^ring_attributes);
    clp$open_display_reference (pvt [p$output].value^.file_value^, ^clp$new_page_procedure, fsc$list,
          ring_attributes, display_control, status);
    IF NOT status.normal THEN
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;
    clv$titles_built := FALSE;
    clv$command_name := 'display_multiprocessing_options';

    clp$put_display (display_control, data_string, clc$trim, status);
    IF status.normal THEN
      clp$close_display (display_control, status);
    ELSE
      clp$close_display (display_control, ignore_status);
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND clp$display_multipro_opt_cmd;
?? OLDTITLE ??
?? NEWTITLE := 'clp$set_multipro_opt_cmd', EJECT ??

{ PURPOSE:
{   The purpose of this command is to change multiprocessing permissions imposed on a job.  The multiprocess
{   option of this command can be used within a job to allow multiprocessing of its tasks.  This means that
{   different tasks from the same job may be executing simultaneously on multiple processors.  The default for
{   this option is OFF because most jobs will not benefit from being able to multiprocess, and there is a
{   small overhead involved in allowing it.
{
{   The CPU Reinstatement feature gives the capability to initialize (or reinitialize) a CPU and return it for
{   use in the active configuration without a system interrupt.  A result of this feature is that turning OFF
{   one CPU on a dual CPU mainframe is NOT equivalent to a single CPU mainframe.  On a dual CPU mainframe
{   certain system segments are made cache-bypass, whether or not both CPUs are ON, allowing for the turning
{   ON of a CPU at a time other then at system deadstart.  Special care should be taken if any programs
{   utilize the SET_MULTIPROCESSING_OPTIONS command with the MP parameter set to ON as it will encounter a
{   performance degradation if used on a dual CPU mainframe with one CPU turned OFF or DOWN.
{
{     SET_MULTIPROCESSING_OPTIONS    MULTIPROCESS = OFF | ON
{                                  [ PROCESSORS = ( P0,P1 ) ]
{                                  [ STATUS = <status variable> ]
{            MULTIPROCESS, MP, M  : This parameter specifies whether a job is to allow simultaneous
{                               processing of its tasks on multiple processors.
{            PROCESSORS, PROCESSOR, P : This parameter specifies the processors desired.
{            STATUS           : see ERROR HANDLING.

  PROCEDURE [XDCL] clp$set_multipro_opt_cmd
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE set_multiprocessing_options, set_multiprocessing_option, setmo (
{   multiprocess, mp, m: key on, off keyend = off
{   processors, processor, p: list of key p0, p1 keyend = $optional
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 7] of clt$pdt_parameter_name,
      parameters: array [1 .. 3] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 2] of clt$keyword_specification,
        default_value: string (3),
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$list_type_qualifier_v2,
        element_type_spec: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 2] of clt$keyword_specification,
        recend,
      recend,
      type3: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [91, 9, 17, 7, 23, 56, 370],
    clc$command, 7, 3, 0, 0, 0, 0, 3, ''], [
    ['M                              ',clc$abbreviation_entry, 1],
    ['MP                             ',clc$alias_entry, 1],
    ['MULTIPROCESS                   ',clc$nominal_entry, 1],
    ['P                              ',clc$abbreviation_entry, 2],
    ['PROCESSOR                      ',clc$alias_entry, 2],
    ['PROCESSORS                     ',clc$nominal_entry, 2],
    ['STATUS                         ',clc$nominal_entry, 3]],
    [
{ PARAMETER 1
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 81,
  clc$optional_default_parameter, 0, 3],
{ PARAMETER 2
    [6, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 97, clc$optional_parameter,
  0, 0],
{ PARAMETER 3
    [7, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$keyword_type], [2], [
    ['OFF                            ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['ON                             ', clc$nominal_entry, clc$normal_usage_entry, 1]]
    ,
    'off'],
{ PARAMETER 2
    [[1, 0, clc$list_type], [81, 1, clc$max_list_size, 0, FALSE, FALSE],
      [[1, 0, clc$keyword_type], [2], [
      ['P0                             ', clc$nominal_entry, clc$normal_usage_entry, 1],
      ['P1                             ', clc$nominal_entry, clc$normal_usage_entry, 2]]
      ]
    ],
{ PARAMETER 3
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$multiprocess = 1,
      p$processors = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    VAR
      list_p: ^clt$data_value,
      option_p: ^clt$data_value,
      processor_id_set: ost$processor_id_set;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Check the value of the PROCESSORS parameter.

    processor_id_set := $ost$processor_id_set[];
    IF pvt [p$processors].specified THEN
      list_p := pvt [p$processors].value;
      WHILE list_p <> NIL DO
        option_p := list_p^.element_value;
        list_p := list_p^.link;
        IF option_p^.keyword_value = 'P0' THEN
          processor_id_set := processor_id_set + $ost$processor_id_set[0];
        ELSEIF option_p^.keyword_value = 'P1' THEN
          processor_id_set := processor_id_set + $ost$processor_id_set[1];
        IFEND;
      WHILEND;
    IFEND;

    jmp$set_multiprocessing_r3 (pvt [p$multiprocess].value^.keyword_value, processor_id_set, status);

  PROCEND clp$set_multipro_opt_cmd;
?? OLDTITLE ??
MODEND clm$set_disp_multipro_opts_cmds
