      SUBROUTINE MXMN_MF (PARRAY,KLEN,PMAX,PMIN)
C
C*******************************************************************
C*
C*    NAME      : MXMN
C*
C*    FUNCTION  : RETURN MAXIMUM AND MINIMUM VALUES FROM AN ARRAY
C*                OF FLOATING POINT NUMBERS.
C*
C*    INPUT     : PARRAY - ARRAY OF NUMBERS
C*                KLEN   - LAST WORD OF THIS ARRAY
C*
C*    OUTPUT    : PMAX - MAXIMUM VALUE
C*                PMIN - MINIMUM VALUE
C*
C*
C*     JOHN HENNESSY, ECMWF, 22 APRIL 1985
C*
C*    Modified by Jean CLOCHARD, French DMN, January 1990.
C*    R. El Khatib 2004-10-12 MAXVAL,MINVAL
C*    F. Vana + NEC Apr-2009: OpenMP
C*
C*******************************************************************
C
      USE OML_MOD , ONLY : OML_MY_THREAD , OML_GET_NUM_THREADS
C
#include "precision.h"
C
      INTEGER KLEN
      REAL (KIND=JPDBLR) PMAX, PMIN
      REAL (KIND=JPDBLR) PARRAY (KLEN)
      INTEGER START, END, BLOCKS, MY_THREAD, THREADS
      REAL (KIND=JPDBLR) PMAX_LOCAL, PMIN_LOCAL
C
      PMAX = -HUGE(PARRAY)
      PMIN = HUGE(PARRAY)
!$OMP PARALLEL
!$OMP&PRIVATE(START,END,BLOCKS,MY_THREAD,THREADS,PMAX_LOCAL,PMIN_LOCAL)
      MY_THREAD = OML_MY_THREAD() - 1
      THREADS = OML_GET_NUM_THREADS()
      BLOCKS = (KLEN + THREADS) / THREADS
      START = MY_THREAD * BLOCKS + 1
      END = MIN(START+BLOCKS-1,KLEN)
      PMAX_LOCAL = MAXVAL(PARRAY(START:END))
      PMIN_LOCAL = MINVAL(PARRAY(START:END))
!$OMP CRITICAL
      PMAX = MAX(PMAX,PMAX_LOCAL)
      PMIN = MIN(PMIN,PMIN_LOCAL)
!$OMP END CRITICAL
!$OMP END PARALLEL

      RETURN
C
      END
