6 Commits

Author SHA1 Message Date
e8d4d6596e cafe-1.16.1 2022-08-04 10:19:32 +02:00
2170202fc9 version 1.15.0; added ca, epics4 version methods 2022-03-11 16:32:51 +01:00
9a18453b41 reset status in getCache following put with nowtaccess error 2021-10-14 19:37:59 +02:00
f97beb8edf 2020b LD_PRELOAD 2021-06-15 16:19:04 +02:00
32ed13125d cafe-1.13.0 2021-03-22 12:41:12 +01:00
90d82bec7a cafe-1.12.5 release 2021-03-16 09:35:10 +01:00
15 changed files with 2220 additions and 1375 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
*~
*.bak
*.*-
RHEL7-x86_64
SL6-x86_64
windows-x64
felix-cache

233
.matlab7rc.sh-original Executable file
View File

@@ -0,0 +1,233 @@
#
# usage: .matlab7rc.sh
#
# abstract: This Bourne Shell script is sourced by the matlab script
# to obtain certain site/user dependent information
# as explained below. The first occurrence of this file
# in the directory list:
#
# . (current)
# $HOME (home)
# matlab/bin (default location)
#
# is used. Most of the time this file in the default location
# need not be modified at all and nothing needs to be done.
# However, if MATLAB does not work properly with the default
# values then this file may need to be modified and different
# values inserted.
#
# Currently, the following variables appear in the code below.
#
# ARCH (machine architecture)
# DISPLAY (DISPLAY variable for X Window System)
# LDPATH_PREFIX (path(s) that appear at the start of
# LD_LIBRARY_PATH)
# LDPATH_SUFFIX (path(s) that appear at the end of
# LD_LIBRARY_PATH)
# LD_LIBRARY_PATH (load library path - the name
# LD_LIBRARY_PATH is platform dependent)
# MATLAB (MATLAB root directory)
# MATLABPATH (MATLAB search path)
# SHELL (which shell to use for ! and unix
# command in MATLAB)
# TOOLBOX (toolbox path)
#
# NOTE: Run matlab -n to get the values used to run MATLAB.
# MATLAB is NOT executed.
#
# Additional variables are used in the MATLAB script, but
# to affect their behavior from this file requires an
# understanding first of how they are determined in the
# MATLAB script and then making code modifications to this
# file.
#
# The strategy behind the use of this file is to keep
# the site wide changes in the matlab/bin/.matlab7rc.sh version
# and have the individual user start with a copy in their
# $HOME directory and modify it for their special circumstances.
#
# IMPORTANT: Please understand that The MathWorks cannot
# anticipate every possible installation. If
# your situation does not fit into the current
# model of using this .matlab7rc.sh file then
# we would like to hear from you. Please
# contact The MathWorks Technical Support.
#
# note(s): 1. The default values are
#
# ARCH (machine architecture)
#
# This is the machine architecture determined by
# the arch utility script.
#
# DISPLAY (DISPLAY variable for X Window System)
#
# This is set to "$DISPLAY" where DISPLAY is
# taken from the environment.
#
# LDPATH_PREFIX (path(s) that appear at the
# start of LD_LIBRARY_PATH)
#
# Enclose in single quotes to defer evaluation
# to the MATLAB script.
#
# LDPATH_SUFFIX (path(s) that appear at the
# end of LD_LIBRARY_PATH)
#
# Enclose in single quotes to defer evaluation
# to the MATLAB script.
#
# LD_LIBRARY_PATH (load library path - the name
# LD_LIBRARY_PATH is platform
# dependent)
#
# TABLE:
#
# platform variable name
# -------- -------------
# glnxa64 LD_LIBRARY_PATH
# maci64 DYLD_LIBRARY_PATH
#
# NOTE: The final load library path determined
# in the MATLAB startup script is composed
# of:
#
# ------------------------------------------------------------
# LDPATH_PREFIX:<matlab_additions>:LD_LIBRARY_PATH:\
# <system_additions>:LDPATH_SUFFIX
# ------------------------------------------------------------
#
# This means to add paths between:
# 1. <matlab_additions> and LD_LIBRARY_PATH
# put them in front of LD_LIBRARY_PATH
# 2. LD_LIBRARY_PATH and <system_additions>
# put them at the end of LD_LIBRARY_PATH
#
# MATLAB (MATLAB root directory)
#
# MATLABPATH (MATLAB search path)
#
# This is set to "$MATLABPATH" where MATLABPATH is
# taken from the environment.
#
# SHELL (which shell to use for ! or
# unix command in MATLAB)
#
# This is set to "$SHELL" where SHELL is taken from
# the environment. If SHELL is empty or not defined
# then MATLAB uses /bin/sh internally.
#
# TOOLBOX (toolbox path)
#
# This is set to "$TOOLBOX" where TOOLBOX is
# taken from the environment.
#
# Copyright 1986-2016 The MathWorks, Inc.
#----------------------------------------------------------------------------
#
# Determine the arch.
#
# -------------------------------------------------------------
#
MATLAB_UTIL_DIR=
#
# -------------------------------------------------------------
#
if [ ! "$MATLAB_UTIL_DIR" ]; then
MATLAB_UTIL_DIR=$MATLAB_UTIL_DIRdefault
fi
#
MATLAB="$MATLABdefault"
#
. "$MATLAB_UTIL_DIR/arch.sh"
if [ "$ARCH" = "unknown" ]; then
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
echo ''
echo ' Sorry! We could not determine the machine architecture for your'
echo ' host. Please contact:'
echo ''
echo ' MathWorks Technical Support'
echo ''
echo ' for further assistance.'
echo ''
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
trap ""
exit 1
fi
#
# IMPORTANT! Modify ONLY if you don't like the defaults after running
# MATLAB.
#
case "$ARCH" in
glnx*)
#----------------------------------------------------------------------------
AUTOMOUNT_MAP=''
DISPLAY="$DISPLAY"
ARCH="$ARCH"
TOOLBOX="$TOOLBOX"
MATLABPATH="$MATLABPATH"
SHELL="$SHELL"
LDPATH_PREFIX=''
#
# To always use the OpenGL libraries shipped with MATLAB uncomment the next
# line.
#
# LDPATH_PREFIX='$MATLAB/sys/opengl/lib/$ARCH'
#
LDPATH_SUFFIX=''
#
if [ "$LD_LIBRARY_PATH" != "" ]; then
LD_LIBRARY_PATH=$LD_LIBRARY_PATH
else
LD_LIBRARY_PATH=
fi
#----------------------------------------------------------------------------
;;
mac*)
AUTOMOUNT_MAP=''
DISPLAY="$DISPLAY"
ARCH="$ARCH"
TOOLBOX="$TOOLBOX"
MATLABPATH="$MATLABPATH"
SHELL="$SHELL"
LDPATH_PREFIX=''
#
# To always use the OpenGL libraries shipped with MATLAB uncomment the next
# line.
#
# LDPATH_PREFIX='$MATLAB/sys/opengl/lib/$ARCH'
#
LDPATH_SUFFIX=''
#
if [ "$DYLD_LIBRARY_PATH" != "" ]; then
DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH
else
DYLD_LIBRARY_PATH=
fi
#----------------------------------------------------------------------------
;;
*)
#----------------------------------------------------------------------------
AUTOMOUNT_MAP=''
DISPLAY="$DISPLAY"
ARCH="$ARCH"
TOOLBOX="$TOOLBOX"
MATLABPATH="$MATLABPATH"
SHELL="$SHELL"
LDPATH_PREFIX=''
#
# To always use the OpenGL libraries shipped with MATLAB uncomment the next
# line.
#
# LDPATH_PREFIX='$MATLAB/sys/opengl/lib/$ARCH'
#
LDPATH_SUFFIX=''
#
if [ "$LD_LIBRARY_PATH" != "" ]; then
LD_LIBRARY_PATH=$LD_LIBRARY_PATH
else
LD_LIBRARY_PATH=
fi
#----------------------------------------------------------------------------
;;
esac

Binary file not shown.

BIN
RHEL7-x86_64/2018a/mocha.mexa64 Executable file

Binary file not shown.

53
bug2020b.txt Normal file
View File

@@ -0,0 +1,53 @@
Dear Jan,
Thank you for the feedback and your suggestion to use LD_PRELOAD to load the library before we then actually LD_PRELOAD the partial glibc 2.18 implementation. Then your library should still be able to load with pure glibc 2.17 as available on your system, in which this glibc bug does not exist. I had not thought of this. I have now added this approach to our knowledge base.
Thanks again and best regards,
Martijn
--------------- Original Message ---------------
From: Martijn Aben [support@mathworks.nl]
Sent: 6/3/2021 11:56 AM
To: jan.chrin@psi.ch
Subject: Re: mex file hangs in 2020b on Linux [ ref:_00Di0Ha1u._5003q1PWEEz:ref ]
Dear Jan Chrin,
I am writing in reference to your Technical Support Case 04900956 regarding 'mex file hangs in 2020b on Linux'.
I suspect that what is going on here is that this third-party library is using pthread_join() when loaded (i.e. it might call it its entry point or the constructor of a static class instance). Using pthread_join() at library load, will lead to deadlocks in glibc versions 2.18 2.22:
https://bugzilla.redhat.com/show_bug.cgi?id=1223055
Now it looks like you are on a Red Hat 7 (based) system. RHEL 7 by default includes glibc 2.17 and so in general, outside MATLAB, you would not run into this issue with that third-party library which you work with. As a matter of fact, even inside MATLAB you will not run into any issues related to this as long as you work with a MATLAB release before R2020b; those releases will simply work with your system's glibc 2.17.
Starting with MATLAB R2020b however, MATLAB is no longer compatible with glibc 2.17, we now require 2.18 at a minimum. To still allow MATLAB to run on RHEL 7 systems, which we did still want to support, we therefore have included a partial glibc 2.18 implementation with MATLAB R20208b which is loaded on top of the glibc 2.17 of your system (if needed, if you are on a system with newer glibc we will simply only use the newer system glibc). This glibc 2.18 implementation which we add, then also actually introduces that glibc 2.18 bug.
There is no direct/straightforward solution or workaround for this issue, you have to either:
1. Avoid the usage of pthread_join() during library load. Perhaps move the initialization code which normally occurs statically/automatically at library load to a function which can/must be be called after the library has loaded. You may be able to make this change by yourself or you might need to work with the developer of the third-party library to see whether they can/are willing to make this change. The issue is not necessarily MATLAB specific; it could occur with any application trying to work with their library on a Linux distribution with glibc versions 2.18 2.22, so it could really be worth making that change. Or,
2. Work with MATLAB releases prior to R2020b, or
3. Since upgrading glibc in an existing Linux distribution is not really an option, switch to version 8 of your Red Hat (based) Linux distribution, which includes glibc 2.28 which we can work with directly and which should not suffer from that glibc bug which exists in versions 2.18 2.22. Or switch to an entirely different Linux distribution/version altogether which includes glibc > 2.22.
Please preserve the Reference ID in further correspondence on this query. This allows our systems to automatically associate your reply to the appropriate Case.
If you have a new technical support question, please submit a new request here:
http://www.mathworks.com/support/servicerequests/create.html
Sincerely,
Martijn Aben
MathWorks Technical Support Department
Self-Service: http://www.mathworks.com/support
File Exchange and MATLAB Answers: http://www.mathworks.com/matlabcentral/
The MathWorks BV
Dr. Holtroplaan 5B
5652 XR Eindhoven
The Netherlands
Chamber of Commerce Eindhoven: 29046452

268
cafe-matlab.sh Executable file
View File

@@ -0,0 +1,268 @@
#! /bin/bash
# User to set the default MATLAB version here
# This default is ONLY activated
# (1) in the absence of the relevant input argument, and
# (2) if matlab is not already pre-loaded on your system
MATLAB_DEFAULT=2017b
# cafe-matlab.sh script to enable use of the mocha mex-file
# The script executes the command: module load cafe-matlab/<matlab-version>
# which will pre-pend the $MATLABPATH environment variable with the location
# of the matching mocha mex-file
# Jan Chrin, 5 April 2017
#
# Usage: cafe-matlab.sh -v <matlab version> -d <default matlab version> -s <true/false>
# where the input key value pairs are **optional**
# Examples of usage:
# (1) Use mocha with MATLAB version 2017b but do not start matlab [-s false is default]
# cafe-matlab.sh -v 2017b
# (2) Use mocha with MATLAB version 2017b and start matlab
# cafe-matlab.sh -v 2017b -s true
# (3) Use mocha with MATLAB version given by MATLAB_DEFAULT in script
# cafe-matlab.sh -v default -s true
# cafe-matlab.sh --usedefault [equivalent -v default -s true]
# (4) Use mocha with preloaded matlab (else if none, then that given by -d option else MATLAB_DEFAULT )
# cafe-matlab.sh -d 2017b
# cafe-matlab.sh --preloaded [equivalent to -v preloaded -s true]
# If no instruction to the matlab version is given by the user then the procedure is:
# (1) If MATLAB is already loaded ($MATLAB has automatically been set),
# then the location of the corresponding mex-file will be pre-pended to $MATLABPATH
# (2) if MATLAB is **not** already loaded, then the script will use a default MATLAB
# version, as given by the -d option else that given by $MATLAB_DEFAULT in the above.
# and the location of the corresponding mex-file will be pre-pended to $MATLABPATH
PRINT_INFO=false
# Reset (required)
MATLAB_START=false
MATLAB_REQUESTED=
MATLAB_V=$MATLAB_VERSION
#For MATLAB version 2015a and earlier
if [ ! $MATLAB_VERSION ]
then
if [ ${MATLAB} ]
then
MATLAB_EXT=${MATLAB##*/}
#use IFS to split string into arrays with . being the delimeter
IFS='.' read -ra NAMES <<< $MATLAB_EXT
MATLAB_V=${NAMES[0]}
#echo $MATLAB_EXT
fi
fi
# Loop round input arguments
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
-v|-V|--version|--Version)
c=$2
MATLAB_REQUESTED=${c##*/}
if [ $PRINT_INFO = true ]
then
echo MATLAB VERSION REQUESTED = "${MATLAB_REQUESTED}"
fi
shift
;;
-s|-S|--start|--Start)
MATLAB_START="$2"
if [ $PRINT_INFO = true ]
then
echo MATLAB START = "${MATLAB_START}"
fi
shift
;;
-d|-D|--default|--Default)
MATLAB_DEFAULT="$2"
if [ $PRINT_INFO = true ]
then
echo MATLAB DEFAULT = "${MATLAB_DEFAULT}"
fi
shift
;;
--preloaded)
MATLAB_REQUESTED="preloaded"
MATLAB_START=false
if [ $PRINT_INFO = true ]
then
echo MATLAB VERSION REQUESTED = "${MATLAB_REQUESTED}"
echo MATLAB START = "${MATLAB_START}"
fi
;;
--usedefault)
MATLAB_REQUESTED="default"
MATLAB_START=false
if [ $PRINT_INFO = true ]
then
echo MATLAB VERSION REQUESTED = "${MATLAB_REQUESTED}"
echo MATLAB START = "${MATLAB_START}"
fi
;;
-h|-H|--help|--Help)
echo '*********************************************************'
echo Usage: cafe-matlab.sh
echo '-v <matlabVersion> If omitted, uses pre-loaded matlab version, else default version'
echo '-d <matlabVersion> Override default version to be used if matlab module not already loaded'
echo '-s <true/false> Whether or not to start matlab; default is false.'
echo ' Option is valid for matlab versions 2020a and earlier '
echo '--show Shows matlab version currently loaded and the script default version'
echo '*********************************************************'
echo 'e.g. cafe-matlab.sh -v 2019a -s false % use matlab/2019a'
echo 'e.g. cafe-matlab.sh -d 2019a -s false % Use pre-loaded matlab module else matlab/2019a'
echo 'e.g. cafe-matlab.sh % Use pre-loaded matlab module, else that given in script'
return 2> /dev/null || exit
;;
--show)
echo '*********************************************************'
if [ $MATLAB_V ]
then
echo MATLAB VERSION CURRENTLY LOADED IS ${MATLAB_V}
else
echo 'MATLAB MODULE NOT CURRENTLY LOADED'
fi
echo THE SCRIPT DEFAULT IS $MATLAB_DEFAULT BUT WILL ONLY BE ACTIVATED IF MATLAB
echo 'IS NOT ALREADY LOADED OR OTHERWISE SPECIFIED BY THE -v OPTION'
echo '$MATLAB_DEFAULT CAN BE OVERRIDDEN USING THE -d OPTION'
echo '*********************************************************'
return 2> /dev/null || exit
;;
*)
echo Unknown input key: "$key"
echo Usage: 'cafe-matlab -v <matlab version> -s <true/false>'
echo where '-s true' will start matlab - default is false
echo Executing script with default options
# unknown option
;;
esac
shift #
done
if [ $MATLAB_REQUESTED ]
then
if [ $MATLAB_REQUESTED == 'default' ]
then
MATLAB_REQUESTED=$MATLAB_DEFAULT
fi
if [ $MATLAB_REQUESTED == 'preloaded' ]
then
MATLAB_REQUESTED= #leave empty
fi
fi
#echo $MATLAB_V
#echo $MATLAB_REQUESTED
#echo $MATLAB_DEFAULT
module use Cafe
#if -v is given then load MATLAB_REQUESTED
#if -v not given or if -v preloaded, then load MATLAB_V
#else load MATLAB_DEFAULT
if [ $MATLAB_REQUESTED ]
then
if test -f "/opt/psi/Cafe/modulefiles/cafe-matlab/${MATLAB_REQUESTED}"
then
#unload removes $MATLAB_VERSION
module unload matlab
module unload cafe-matlab
module load cafe-matlab/${MATLAB_REQUESTED}
if [ $PRINT_INFO = true ]
then
echo "Using requested version: matlab/$MATLAB_REQUESTED"
fi
else
echo "Unknown requested version: matlab/$MATLAB_REQUESTED"
echo "'module avail cafe-matlab' gives the possibilities:"
module avail cafe-matlab
MATLAB_START=false
fi
elif [ $MATLAB_V ]
then
if test -f "/opt/psi/Cafe/modulefiles/cafe-matlab/${MATLAB_V}"
then
#unload removes $MATLAB_VERSION
module unload matlab
module unload cafe-matlab
module load cafe-matlab/${MATLAB_V}
if [ $PRINT_INFO = true ]
then
echo "Using matlab/$MATLAB_V"
fi
else
module unload matlab
module unload cafe-matlab
module load cafe-matlab/$MATLAB_DEFAULT
if [ $PRINT_INFO = true ]
then
echo "Using matlab/$MATLAB_DEFAULT"
fi
fi
else
if test -f "/opt/psi/Cafe/modulefiles/cafe-matlab/${MATLAB_DEFAULT}"
then
module unload matlab
module unload cafe-matlab
module load cafe-matlab/$MATLAB_DEFAULT
if [ $PRINT_INFO = true ]
then
echo "Using matlab/$MATLAB_DEFAULT"
fi
else
echo "The default requested version: matlab/$MATLAB_DEFAULT within cafe-matlab.sh is invalid!"
echo "'module avail cafe-matlab' gives the possibilities:"
module avail cafe-matlab
fi
fi
#safe versions
mvarray=("2015a" "2016a" "2016b" "2017a" "2017b" "2018a" "2019a" "2019b" "2020a")
if [[ ! " ${mvarray[*]} " =~ " ${MATLAB_REQUESTED} " ]]; then
#echo "Version is not in array"
#ld-preload for 2020b onwards on redhat7
if [[ -z "${LD_PRELOAD}" ]]; then
export LD_PRELOAD=$EPICS/base-7.0.6/lib/$EPICS_HOST_ARCH/libCom.so
else
LD_PRELOAD_TEMP=$LD_PRELOAD
export LD_PRELOAD=$EPICS/base-7.0.6/lib/$EPICS_HOST_ARCH/libCom.so:$LD_PRELOAD
fi
MATLAB_START=true
fi
if [ $MATLAB_START = true ]
then
matlab &
fi
## Or manually acticate cafe-matlab:
## module unload matlab
## module unload cafe-matlab
## module load cafe-matlab/2016b
## or module switch cafe-matlab/2016b cafe-matlab/2015a
if [[ ! " ${mvarray[*]} " =~ " ${MATLAB_REQUESTED} " ]]; then
if [[ -z "$LD_PRELOAD_TEMP" ]]; then
unset LD_PRELOAD
else
export LD_PRELOAD=$LD_PRELOAD_TEMP
unset LD_PRELOAD_TEMP
fi
module unload cafe-matlab
module unload matlab
fi

View File

@@ -1 +0,0 @@
exampleNew.m

1068
example.m Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
#include <cafe.h>
//include <hashConduit.h>
#include "macchinetta.h"
#include "containerMochaccino.h"
@@ -11,6 +12,7 @@ using namespace std;
const unsigned short METHOD_NAME_MAX_SIZE=80;
const unsigned short PVNAME_MAX_SIZE=80;
const unsigned short DBR_STRING_MAX_SIZE=40;
const unsigned short MONITOR_ACTION_MAX_SIZE=255;
const unsigned short ME_MESSAGE_MAX_SIZE=255;
@@ -182,7 +184,8 @@ enum mdtIndex {MOCHA_NATIVE=0, MOCHA_CHAR, MOCHA_UCHAR, MOCHA_SHORT, MOCHA_USH
enum mochaIndex {SHOW=1, OPEN, OPEN_ARRAY, OPEN_WAIT, GET_OPEN_WAIT_TIME,
OPEN_WAIT_WITH_TIME,OPEN_WAIT_TIME_TO_DEFAULT,
OPEN_NOWAIT, OPEN_NOW, OPEN_NOW_AND_WAIT, OPEN_GROUP,
CLOSE, CLOSE_ARRAY, CLOSE_GROUP, CA_POLL, MEX_UNLOCK, MOCHA_VERSION,
CLOSE, CLOSE_ARRAY, CLOSE_GROUP, CA_POLL, MEX_UNLOCK,
MOCHA_VERSION, EPICS_V_STRING, CA_V_STRING,
WITH_EXCEPTIONS, HAVE_EXCEPTIONS, SEND_NOW,
GET=100, GET_INT8, GET_INT16, GET_INT32, GET_INT64, GET_UINT8,
GET_UINT16, GET_UINT32, GET_UINT64, GET_FLOAT, GET_DOUBLE,
@@ -213,8 +216,8 @@ enum mochaIndex {SHOW=1, OPEN, OPEN_ARRAY, OPEN_WAIT, GET_OPEN_WAIT_TIME,
SET_NELEM, SET_NELEM_CACHE, SET_OFFSET,
GET_NELEM_CLIENT, GET_NELEM_NATIVE, GET_NELEM_REQUEST,
GET_NELEM, GET_NELEM_CACHE, GET_OFFSET,
MONITOR=400, MONITOR_STOP, MONITOR_FLUSH_EVENT,
GET_MONITOR_HANDLES, GET_MONITOR_HANDLES_AND_ACTIONS,
MONITOR=400, MONITOR_STOP, MONITOR_FLUSH_EVENT,
GET_MONITOR_HANDLES, GET_MONITOR_HANDLES_AND_ACTIONS, GET_NO_MONITORS,
IS_CONNECTED=500, ALL_CONNECTED,
PRINT_STATUS=600, PRINT_MONITORS, PRINT_HANDLE, PRINT_HANDLES,
PRINT_DISCONNECTED_HANDLES,GET_HANDLES,GET_HANDLE_STATES,
@@ -252,7 +255,8 @@ void msInsert()
ms.insert(mochaccino(CA_POLL, "capoll"));
ms.insert(mochaccino(MEX_UNLOCK, "mexunlock"));
ms.insert(mochaccino(MOCHA_VERSION, "version"));
ms.insert(mochaccino(EPICS_V_STRING, "epicsversion"));
ms.insert(mochaccino(CA_V_STRING, "caversion"));
ms.insert(mochaccino(WITH_EXCEPTIONS, "withexceptions"));
ms.insert(mochaccino(WITH_EXCEPTIONS, "setexceptions"));
ms.insert(mochaccino(HAVE_EXCEPTIONS, "haveexceptions"));
@@ -397,10 +401,12 @@ void msInsert()
ms.insert(mochaccino(GET_OFFSET, "getoffset"));
ms.insert(mochaccino(MONITOR, "monitorstart"));
ms.insert(mochaccino(MONITOR, "monitor"));
ms.insert(mochaccino(MONITOR_STOP, "monitorstop"));
ms.insert(mochaccino(MONITOR_FLUSH_EVENT, "monitorflushevent"));
ms.insert(mochaccino(GET_NO_MONITORS, "getnomonitors"));
ms.insert(mochaccino(GET_MONITOR_HANDLES, "getmonitorhandles"));
ms.insert(mochaccino(GET_MONITOR_HANDLES_AND_ACTIONS, "getmonitorhandlesandactions"));
@@ -456,6 +462,15 @@ void printStatus(int status )
}
void printStringInputError()
{
mexPrintf("Error in intepreting pv in input argument:\n");
mexPrintf("PV name does not have a char value \n");
mexPrintf("MATLAB mx library does not support string/mxSTRING_CLASS as input\n");
mexPrintf("Please use char/mxCHAR_CLASS as data type instead\n");
mexPrintf("i.e., use single quotes instead of double quotes in input argument!\n");
}
std::string prepareExceptionID(int status )
{
std::string exID="CAFE_";
@@ -771,6 +786,56 @@ unsigned int getNObjectsFromDataCell(const mxArray * thisCell)
}
char getEscapeSequence(char cNext, bool & recognizedFlag) {
char wfChar = cNext;
recognizedFlag = true;
switch (cNext) {
case '0':
wfChar = '\0';
break;
case '\'':
wfChar = '\'';
break;
case '"':
wfChar = '\"';
break;
case '?':
wfChar = '\?';
break;
case '\\':
wfChar = '\\';
break;
case 'a':
wfChar = '\a';
break;
case 'b':
wfChar = '\b';
break;
case 'f':
wfChar = '\f';
break;
case 'n':
wfChar = '\n';
break;
case 'r':
wfChar = '\r';
break;
case 't':
wfChar = '\t';
break;
case 'v':
wfChar = '\v';
break;
default:
// Unrecognized escape sequence; print slash
wfChar = '\\';
recognizedFlag = false;
break;
}
return wfChar;
}
/*
@@ -910,15 +975,93 @@ void cellToString(const mxArray * thisCell)
break;
case mxCHAR_CLASS:
ne=1;
dbr_string_t * strBuffer = new dbr_string_t[ne];
mxGetString(newCell, *strBuffer, sizeof(dbr_string_t)*ne);
for (mwIndex j=0; j< ne; ++j )
{
strcpy(inputStringCell[iWithinAllCells],strBuffer[j]);
unsigned int neLocal=1;
if (ne > (DBR_STRING_MAX_SIZE-1)) {
mexPrintf("Exceeded (with %d) max limit of %d chars. Ignoring this element of cell\n",
ne, (DBR_STRING_MAX_SIZE-1));
break;
}
dbr_string_t * strBuffer = new dbr_string_t[neLocal];
mxGetString(newCell, *strBuffer, sizeof(dbr_string_t)*neLocal);
//mexPrintf("ne %d\n", ne);
//mexPrintf("strBuffer %d\n", *strBuffer[0]);
//mexPrintf("strBuffer %c \n", *strBuffer[0]);
char c = strBuffer[0][0];
char cNext;
if (c == '\\' && ne > neLocal) {
cNext = strBuffer[0][1];
//mexPrintf("char cNext %c\n", cNext);
bool recognizedFlag = true;
char cNew = NS_MOCHA::getEscapeSequence(cNext, recognizedFlag);
//Must loop over all ne!
for (unsigned int i=0; i < ne; ++i) {
strBuffer[0][i] = cNew;
}
/* Must loop over all ne
switch (cNext) {
case '0':
strBuffer[0][0] = '\0';
break;
case '\'':
strBuffer[0][1] = '\'';
break;
case '"':
strBuffer[0][1] = '\"';
break;
case '?':
strBuffer[0][1] = '\?';
break;
case '\\':
strBuffer[0][1] = '\\';
break;
case 'a':
strBuffer[0][1] = '\a';
break;
case 'b':
strBuffer[0][1] = '\b';
break;
case 'f':
strBuffer[0][1] = '\f';
break;
case 'n':
//strBuffer[0][0] = '\n';
for (unsigned int i=0; i < ne; ++i) {
strBuffer[0][i] = '\n';
}
break;
case 'r':
strBuffer[0][1] = '\r';
break;
case 't':
//strBuffer[0][0] = '\t';
for (unsigned int i=0; i < ne; ++i) {
strBuffer[0][i] = '\t';
}
break;
case 'v':
strBuffer[0][1] = '\v';
break;
default:
// Unrecognized escape sequence; print slAH
strBuffer[0][1] = '\\';
break;
}
*/
}
for (mwIndex j=0; j< neLocal; ++j )
{
strcpy(inputStringCell[iWithinAllCells], strBuffer[j]);
++iWithinAllCells;
}
delete [] strBuffer;
break;
}
@@ -1188,6 +1331,7 @@ unsigned int checkForHandleNoOpen(const mxArray * inputValue)
if (mxIsNumeric(inputValue) )
{
_handle = (uint32_T) mxGetScalar(inputValue);
}
else if (mxIsChar(inputValue) )
@@ -1206,6 +1350,8 @@ unsigned int checkForHandleNoOpen(const mxArray * inputValue)
}
}
else if (mxIsCell(inputValue) )
{
@@ -1231,8 +1377,21 @@ unsigned int checkForHandleNoOpen(const mxArray * inputValue)
mexPrintf("PV=%s has not yet been opened by user!\n", pv );
}
}
else if (strcmp (mxGetClassName(newCell),"string") ==0 ) {
printStringInputError();
return _handle;;
}
}
else if (strcmp (mxGetClassName(inputValue),"string") ==0 ) {
printStringInputError();
return _handle;;
}
else
{
mexPrintf("Error in checkForHandleNoOpen:\n");
@@ -1248,6 +1407,8 @@ unsigned int checkForHandle(const mxArray * inputValue)
{
unsigned int _handle=0;
if (mxIsNumeric(inputValue) )
{
@@ -1297,7 +1458,20 @@ unsigned int checkForHandle(const mxArray * inputValue)
_handle=open(pv);
}
}
else if (strcmp (mxGetClassName(newCell),"string") ==0 ) {
printStringInputError();
return _handle;;
}
}
else if (strcmp (mxGetClassName(inputValue),"string") ==0 ) {
printStringInputError();
return _handle;;
}
else
{
mexPrintf("Error in checkForHandle:\n");
@@ -1305,9 +1479,11 @@ unsigned int checkForHandle(const mxArray * inputValue)
mexPrintf("or PV name does not have a char value \n");
return _handle;
}
if (_handle==0)
if (_handle<1)
{
mexPrintf("Handle in input argument not given! \n");
mexPrintf("Handle should be a positive integer. \n");
mexPrintf("Alternatively enter the pv name in single quotes\n");
}
return _handle;
}

View File

@@ -12,7 +12,6 @@
//#include <Python.h>
//#endif
extern void _main();
using namespace NS_MOCHA;
@@ -43,33 +42,23 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
mexPrintf("Please use the method name (MATLAB char) as input to the first argument. \n");
mexPrintf("The command: mocha \'show\' will display the methods available. \n");
mexPrintf("1st input argument Class Name: %s\n", mxGetClassName(prhs[0]));
mexPrintf("1st input argument Class ID: %d\n", mxGetClassID(prhs[0]));
mexPrintf("1st input argument to mocha must be of type char/mxCHAR_CLASS\n");
//mexPrintf("1st input argument given has Class Name: %s\n", mxGetClassName(prhs[0]));
//mexPrintf("1st input argument given has Class ID: %d\n", mxGetClassID(prhs[0]));
//mexPrintf("1st input argument to mocha must be of type char/mxCHAR_CLASS\n");
return;
}
}
/*
if (strcmp (mxGetClassName(prhs[0]),"string") ==0 ) {
mxChar * mess2 = static_cast<mxChar*>(mxGetData(prhs[0]));
mData = (mxArray *) mess2;
messLength = METHOD_NAME_MAX_SIZE+1;
if ( mxGetString(mData, mess, messLength) == 1) {
mexPrintf ("mxGetString has failed; input is not of mxChar type\n");
}
mexPrintf ("mocha does not support string/mxSTRING_CLASS as input\n");
mexPrintf ("Please use char/mxCHAR_CLASS as data type for input\n");
mexPrintf ("MATLAB mx library does not support string/mxSTRING_CLASS as input\n");
mexPrintf ("Please use char/mxCHAR_CLASS as data type instead\n");
mexPrintf("i.e., use single quotes instead of double quotes in input argument!\n");
return;
}
else {
*/
}
//message
//Trick to handle mocha(402) input from monitor Action
@@ -77,14 +66,32 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
messLength = METHOD_NAME_MAX_SIZE+1;
if (mxIsChar(prhs[0]) )
{
mData = (mxArray *) prhs[0];
mData = (mxArray *) prhs[0];
mxGetString(mData, mess, messLength);
}
else if (!strcmp(mxGetClassName(prhs[0]), "string") )
{
mexPrintf("1st input argument given has Class Name: %s\n", mxGetClassName(prhs[0]));
mexPrintf("1st input argument given has Class ID: %d\n", mxGetClassID(prhs[0]));
mexPrintf("1st input argument to mocha must be of type char/mxCHAR_CLASS\n");
mexPrintf("Please use single quotes instead of double quotes in input argument!\n");
return;
}
else if (mochaIndex ==MONITOR_FLUSH_EVENT)
{
strcpy(mess,"monitorflushevent");
}
else
{
mexPrintf("1st input argument given has Class Name: %s\n", mxGetClassName(prhs[0]));
mexPrintf("1st input argument given has Class ID: %d\n", mxGetClassID(prhs[0]));
mexPrintf("1st input argument to mocha must be of type char/mxCHAR_CLASS\n");
return;
}
char messOriginal[METHOD_NAME_MAX_SIZE+1];
strcpy(messOriginal,mess);
@@ -167,6 +174,7 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
//mexPrintf("message %s\n", mess);
//mexPrintf("message %s\n", messString.c_str());
it_name = name_index.find(mess);
@@ -325,14 +333,12 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
case SET:
if (nrhs<3)
{
mexPrintf("Invalid Number of argument %d. Input: 'set', handle/pv, data \n", nrhs);
return;
}
if (mxIsChar(prhs[1]))
{
nh=1;
@@ -421,9 +427,7 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
}
else
{
nh=mxGetNumberOfElements (prhs[1]);
}
///mexPrintf("nh=%d, nargin=%d\n", nh, nrhs);
@@ -488,8 +492,16 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
mexPrintf("mocha mex file is active\n");
break;
case EPICS_V_STRING:
plhs[0]=mxCreateString((char *) (cafe._epics_version()).c_str());
break;
case CA_V_STRING:
plhs[0]=mxCreateString((char *) (cafe._ca_version()).c_str());
break;
case MOCHA_VERSION:
plhs[0]=mxCreateString((char *) "mocha-1.8.0 : 14 December 2018");
plhs[0]=mxCreateString((char *) "mocha-1.16.1 : 3 August 2022");
break;
case SHOW:
@@ -514,23 +526,18 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
case SET_PUT_PREPARE:
{
if (nrhs<2)
{
mexPrintf("Invalid Number of argument(s) %d. Input: setPutPrepare, handle(s) or handleArray \n", nrhs);
return;
}
size_t numberOfHandles=0;
for (size_t j=1; j<nrhs; ++j)
{
numberOfHandles=mxGetNumberOfElements (prhs[j]);
neWithinAllCells=0; // filled by checkHandleArray
//What is dataType?
@@ -1044,8 +1051,9 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
xData = (mxArray *) prhs[1];
pvLength = PVNAME_MAX_SIZE+1;
mxGetString(xData, pv, pvLength);
handle=NS_MOCHA::open(pv);
//return handle
//plhs[0] = mxCreateDoubleScalar(handle);
@@ -1351,7 +1359,6 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
(du[j].getPVName(),pvgroup.getGroupHandle());
//Match INPUT to CAFE DATATYPE
if (mdtIndexOriginal==MOCHA_NATIVE)
{
@@ -2599,19 +2606,14 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
case GET:
{
if (nrhs<2)
{
mexPrintf("Invalid Number of argument %d. Input: message, handle/pv \n", nrhs);
return;
}
handle=checkForHandle(prhs[1]);
if(handle==0)
{
mexPrintf("Handle does not exist!\n");
@@ -2640,11 +2642,8 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
if (mdtIndex==MOCHA_NATIVE)
{
status=cafe.getHandleHelper().getDataTypeRequest(handle, rdt);
if (status!=ICAFE_NORMAL)
{
mexPrintf("Error for handle input= %d \n", (uint32_T) mxGetScalar(prhs[1]) );
@@ -2657,14 +2656,11 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
CAFE_DATATYPE cdt = (CAFE_DATATYPE) rdt;
mdtIndex=getMdtIndexFromCafeDataType(cdt);
if (cafe.getHandleHelper().isEnum(handle))
{
mdtIndex=MOCHA_STRING;
}
}
@@ -2672,7 +2668,6 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
nelem = cafe.getHandleHelper().getNelemClient(handle); //Change Request to Client
if (cafe.getHandleHelper().getOffset(handle) > 0 )
{
@@ -2697,12 +2692,10 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
//mexPrintf("get Cache: nelem = %d \n", nelem);
if ( (cafe.getHandleHelper().getOffsetLast(handle) > 0) ||
(cafe.getHandleHelper().getNelemToRetrieveFromCache(handle) > cafe.getHandleHelper().getNelemRequest(handle)))
{
//if (nelem > cafe.getHandleHelper().getNelemRequest(handle) ) {
nelemPrevious=cafe.getHandleHelper().getNelemToRetrieveFromCache(handle);
nelem = min( (unsigned int) nelem, cafe.getHandleHelper().getNelemRequest(handle)-cafe.getHandleHelper().getOffsetLast(handle));
@@ -2716,6 +2709,14 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
}
//special case for wf with dbr_char_t
ChannelRegalia channelInfo;
status=cafe.getChannelInfo(handle, channelInfo);
unsigned int WFWithString = 0;
if (channelInfo.getClassNameAsString().compare("waveform") ==0) {
WFWithString = 1;
}
switch (mdtIndex)
{
case MOCHA_DOUBLE:
@@ -2786,57 +2787,91 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
break;
case MOCHA_UCHAR:
plhs[0] = mxCreateNumericMatrix(1,nelem,mxUINT8_CLASS, mxREAL);
ucharArray = (uint8_T *) mxGetData (plhs[0]);
if(cacheFlag)
{
status=cafe.getCache(handle,ucharArray);
}
else
{
status=cafe.get(handle,ucharArray);
}
//special case for wf with dbr_char_t
/*
if (WFWithString == 1) {
string wfStr;
if (cacheFlag)
{
status=cafe.getWFAsStringCache(handle,wfStr);
}
else
{
status=cafe.getWFAsString(handle,wfStr);
}
plhs[0] = mxCreateString( wfStr.c_str() );
}
else {
*/
plhs[0] = mxCreateNumericMatrix(1,nelem,mxUINT8_CLASS, mxREAL);
ucharArray = (uint8_T *) mxGetData (plhs[0]);
if(cacheFlag)
{
status=cafe.getCache(handle,ucharArray);
}
else
{
status=cafe.get(handle,ucharArray);
}
//}
break;
case MOCHA_STRING:
{
dbr_string_t * stringArrayc = new dbr_string_t[nelem];
if(cacheFlag)
{
status=cafe.getCache(handle,stringArrayc);
}
else
{
status=cafe.get(handle,stringArrayc);
}
if (WFWithString ==1) {
//char *test[40];
//test[0]="test";
//test[1]="again";
//mxChar *pr;
//char *ptr_to_seed_data;
//int c;
string wfStr;
if (status==ICAFE_NORMAL)
{
if (nelem==1)
if (cacheFlag)
{
plhs[0]=mxCreateString( stringArrayc[0] );
status=cafe.getWFAsStringCache(handle,wfStr);
}
else
{
plhs[0] = mxCreateCellMatrix(1,nelem);
for (mwSignedIndex i=0; i <nelem; ++i)
{
mxSetCell (plhs[0], i, mxCreateString( stringArrayc[i] ));
}
status=cafe.getWFAsString(handle,wfStr);
}
}
delete [] stringArrayc;
plhs[0] = mxCreateString( wfStr.c_str() );
}
else {
dbr_string_t * stringArrayc = new dbr_string_t[nelem];
if(cacheFlag)
{
status=cafe.getCache(handle,stringArrayc);
}
else
{
status=cafe.get(handle,stringArrayc);
}
if (status==ICAFE_NORMAL)
{
if (nelem==1)
{
plhs[0]=mxCreateString( stringArrayc[0] );
}
else
{
plhs[0] = mxCreateCellMatrix(1,nelem);
for (mwSignedIndex i=0; i <nelem; ++i)
{
mxSetCell (plhs[0], i, mxCreateString( stringArrayc[i] ));
}
}
}
delete [] stringArrayc;
}
break;
}
// Non DBR_TYPES
@@ -2997,11 +3032,11 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
if (cacheFlag)
{
status=cafe.getWFAsString(handle,wfStr);
status=cafe.getWFAsStringCache(handle,wfStr);
}
else
{
status=cafe.getWFAsStringCache(handle,wfStr);
status=cafe.getWFAsString(handle,wfStr);
}
//plhs[0] = mxCreateCellMatrix(1,2);
@@ -4236,7 +4271,7 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
size_t ne = mxGetNumberOfElements ( prhs[2]);
if(ne==0)
if (ne==0)
{
mexPrintf("Empty Data Array in Input \n");
return;
@@ -4246,21 +4281,34 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
neWithinAllCells=0;
iWithinAllCells=0;
mxClassID mxid =mxGetClassID( prhs[2]);
mxClassID mxid =mxGetClassID(prhs[2]);
//This line is important for a string as the Number of Elements
//is interpreted as the number of characters!!!
//Hence for ne to be 1
//Unless we have the special case of wf and DBR_CHAR
//So let us first check if this is a waveform
unsigned short isWFWithString=0;
if (mxid==mxCHAR_CLASS)
{
ne=1;
ChannelRegalia channelInfo;
status=cafe.getChannelInfo(handle, channelInfo);
//mexPrintf(channelInfo.getClassNameAsString().c_str());
if (channelInfo.getClassNameAsString().compare("waveform") !=0) {
ne=1;
}
else {
isWFWithString = 1;
}
}
nelem = cafe.getHandleHelper().getNelemClient(handle);
//handle does not exist
if(nelem==0)
if (nelem==0)
{
//status
plhs[0] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL);
@@ -4275,11 +4323,12 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
return;
}
if(nelem!=ne)
if (nelem!=ne)
{
cafe.getHandleHelper().setNelem(handle,ne);
}
mxArray *fout;
switch(mxid)
{
@@ -4360,11 +4409,13 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
scanCell(prhs[2]);
//Is it a waveform??
//If neWithinAllCells =1 and wf and class is mx_char
inputStringCell = new dbr_string_t[neWithinAllCells];
cellToString(prhs[2]);
if(neWithinAllCells!=ne)
{
cafe.getHandleHelper().setNelem(handle,neWithinAllCells);
@@ -4377,17 +4428,132 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
}
// Single String
case mxCHAR_CLASS:
dbr_string_t inputString;;
mxGetString(prhs[2], inputString, sizeof(dbr_string_t));
status=cafe.set(handle, inputString);
char *buf;
size_t buflen;
buflen = mxGetN(prhs[2]) + 1;
/*
buf = (char *) mxMalloc(buflen);
break;
long mexStatus;
mexStatus = mxGetString(prhs[2], buf, (mwSize) buflen+10);
if (mexStatus != 0) {
mexWarnMsgIdAndTxt( "MATLAB:mxmalloc:mxGetString",
"Failed to copy input string into allocated memory.");
status = ECAFE_BADSTR;
}
*/
buf=mxArrayToString(prhs[2]);
if (isWFWithString == 1) {
//std::string tempStr = inputString;
dbr_char_t * wfChar = new dbr_char_t [buflen+1];
//dbr_char_t * setStrValues = (dbr_char_t *) mxMalloc(buflen+40); // new dbr_char_t [buflen];
std::string wfStr = buf;
unsigned short iCount = 0;
for (std::string::size_type i=0; i < wfStr.size(); ++i) {
char c = wfStr[i];
char cNext;
if (c == '\\' && i < (wfStr.size()-1)) {
cNext = wfStr[i+1];
bool recognizedFlag = true;
wfChar[iCount] = NS_MOCHA::getEscapeSequence(cNext, recognizedFlag);
//mexPrintf ("wf %d", wfChar[iCount]);
/*
switch (cNext) {
case '0':
wfChar[iCount] = '\0';
break;
case '\'':
wfChar[iCount] = '\'';
break;
case '"':
wfChar[iCount] = '\"';
break;
case '?':
wfChar[iCount] = '\?';
break;
case '\\':
wfChar[iCount] = '\\';
break;
case 'a':
wfChar[iCount] = '\a';
break;
case 'b':
wfChar[iCount] = '\b';
break;
case 'f':
wfChar[iCount] = '\f';
break;
case 'n':
wfChar[iCount] = '\n';
break;
case 'r':
wfChar[iCount] = '\r';
break;
case 't':
mexPrintf ("wf %c", wfChar[iCount]);
wfChar[iCount] = '\t';
mexPrintf ("wf %c", wfChar[iCount]);
break;
case 'v':
wfChar[iCount] = '\v';
break;
default:
// Unrecognized escape sequence; print slash and subsequent letter
wfChar[iCount] = '\\';
--i;
break;
}
*/
//if (wfChar[iCount] != '\\') {
if (recognizedFlag) {
++i;
// mexPrintf ("wfplus i %d %d", wfChar[iCount], i);
}
}
else {
wfChar[iCount] = c;
}
++iCount;
//setStrValues[i] = buf[i];
}
cafe.getHandleHelper().setNelem(handle, iCount);
//std::string tb = buf;
//strcpy( (char*)(setStrValues), (const char*) buf); //"Hello \nWorld\0" );
//setStrValues =(dbr_char_t *) tb.c_str(); //"Hello\tWorld\nA\0"; //(dbr_char_t *) buf; //
status = cafe.set(handle, wfChar); // ) (dbr_char_t *) buf);
delete [] wfChar;
// mxFree(setStrValues);
}
else {
status=cafe.set(handle, buf);
}
mxFree(buf);
break;
default:
mexPrintf("mxClassID=%s (enum %d) is not supported; set not instigated!\n",
mxGetClassName(prhs[2]), mxid);
mexPrintf("mxClassID=%s (enum %d) is supported; i.e., use single instead of double quotes!\n",
"char", mxCHAR_CLASS);
break;
status = ECAFE_INVALID_SWITCH_CASE;
break;
}
if(nelem!=ne) cafe.getHandleHelper().setNelem(handle,nelem); //back to old value
//status
@@ -4408,9 +4574,6 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
}
case SET_AND_GET:
{
if (nrhs<3)
@@ -5361,6 +5524,39 @@ void macchinettaFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prh
break;
}
case GET_NO_MONITORS:
{
if (nrhs<2)
{
mexPrintf("Invalid Number of argument %d. Input: 'getNoMonitors', handle/pv \n", nrhs);
return;
}
else if (nrhs>2)
{
mexPrintf("Ignoring arguments after the 2nd from the %d entered. Input: 'getNoMonitors', handle/pv \n", nrhs);
}
handle=checkForHandle(prhs[1]);
if(handle==0)
{
return;
}
unsigned int nm;
nm=cafe.getHandleHelper().getNmonitor(handle);
//number of monitors for this handle
plhs[0] = mxCreateNumericMatrix(1,1,mxUINT32_CLASS,mxREAL);
ulongArray = (uint32_T *) mxGetData(plhs[0]);
ulongArray[0]=nm;
break;
}
case PRINT_MONITORS:
{

135
makefile
View File

@@ -1,135 +0,0 @@
#
# Jan Chrin
# New Version: June 2016
#
# makefile to build mocha mex file
# printenv | grep MATLAB to reveal your MATLAB Directory
#
# e.g. on sf-lc we have
# MATLAB=/afs/psi.ch/sys/linux/opt/matlab/2015a.x86_64
#
# local executables are built in ./${EPICS_HOST_ARCH}/$(MVER)
# where the MATLAB version is grepped from $(MATLAB)
MATLAB_ROOT=${MATLAB}
MATLAB_VERSION=$(notdir $(MATLAB_ROOT))
##### CHANGE AS APPROPRIATE #################
#Mocha Version to install
MOCHA_VERSION=mocha-noqt-1.8.0-gcc-6.3.0
#CAFE version to link to
CAFE_VERSION=cafe-noqt-1.8.0-gcc-6.3.0
EPICS_BASE=${EPICS}/base
#CAFE project base
CAFE_BASE=/opt/gfa/cafe
CAFE_MOCHA_BASE=${CAFE_BASE}/mocha
CAFE_CPP_BASE=$(CAFE_BASE)/cpp/$(CAFE_VERSION)
BOOST_BASE=${CAFE_BASE}/boost/boost_1_61_0/include
INSTALL_MOCHA_LIBDIR= $(CAFE_MOCHA_BASE)/$(MOCHA_VERSION)/lib/$(MATLAB_VERSION)
#############################################
#First deteremine if we are on a 32/64 bit machine
#as mex file extensions are named differently
pattern64=x86_64
pattern32=i386
PWD=$(shell pwd)
#hardware platform
HW=$(shell uname -i)
ifeq ($(pattern64),$(findstring $(pattern64), $(HW)))
MEXE=mexa64
MATLAB_LIB = $(MATLAB_ROOT)/bin/glnxa64
else
ifeq ($(pattern32),$(findstring $(pattern32), $(HW)))
MEXE=mexglx
MATLAB_LIB = $(MATLAB_ROOT)/bin/glnxa86
endif
endif
INSTALL_PATH?=$(INSTALL_MOCHA_LIBDIR)
OBJ_DIR= ${EPICS_HOST_ARCH}/$(MATLAB_VERSION)
INCLUDEPATH_MOCHA += -I$(MATLAB_ROOT)/extern/include \
-I$(CAFE_CPP_BASE)/include -I./ \
-I$(EPICS_BASE)/include -I$(EPICS_BASE)/include/os/Linux
INCLUDEPATH_MACHINETTA += $(INCLUDEPATH_MOCHA) -I$(BOOST_BASE) -I$(BOOST_BASE)/boost
LIB_DIR += \
-L$(EPICS_BASE)/lib/${EPICS_HOST_ARCH} \
-Wl,-rpath,$(EPICS_BASE)/lib/${EPICS_HOST_ARCH} \
-L$(MATLAB_LIB) -Wl,-rpath,$(MATLAB_LIB)
#-lboost_system -lboost_thread-mt
LIBS += -ldl -lca -lCom -lmx -lmex -lmat
LIB_INSTALL = $(LIB_DIR) -L$(INSTALL_PATH) -Wl,-rpath,$(INSTALL_PATH)
LIB_LOCAL = $(LIB_DIR)
CPP_OBJS=../cpp/src/libs/cafe/$(CAFE_VERSION_M)
#CAFE_OBJS_DIR = $(CPP_OBJS)/cafe.o $(CPP_OBJS)/cafeCache.o $(CPP_OBJS)/cafeGroup.o $(CPP_OBJS)/cafeVectors.o \
# $(CPP_OBJS)/cafeXML.o $(CPP_OBJS)/callbackHandlerCreate.o $(CPP_OBJS)/callbackHandlerMonitor.o \
# $(CPP_OBJS)/conduitGroup.o $(CPP_OBJS)/conduit.o \
# $(CPP_OBJS)/connectCallbacks.o $(CPP_OBJS)/connectGroup.o \
# $(CPP_OBJS)/connect.o $(CPP_OBJS)/exceptionsHelper.o $(CPP_OBJS)/granules.o $(CPP_OBJS)/handleHelper.o \
# $(CPP_OBJS)/helper.o \
# $(CPP_OBJS)/loadCollectionXMLParser.o $(CPP_OBJS)/loadGroupXMLParser.o $(CPP_OBJS)/methodCallbacks.o \
# $(CPP_OBJS)/policyHelper.o \
# $(CPP_OBJS)/restorePVGroupXMLParser.o $(CPP_OBJS)/transpose.o
CAFE_OBJS_DIR = $(CAFE_BASE)/cpp/$(CAFE_VERSION)/lib/libcafe.a
# MATLAB Versions 2014 onwards, use
# LDFLAGS='$(LIB_LOCAL) $(LIBS) instead of $(LIB_LOCAL) $(LIBS)
# LDFLAGS='$(LIB_LOCAL) $(LIBS) instead of $(LIB_INSTALL) $(LIBS)
$(OBJ_DIR)/mocha.$(MEXE): mocha.cpp $(OBJ_DIR)/macchinettaSwitch.o
mex -largeArrayDims CXXFLAGS='-v -largeArrayDims -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread' \
mocha.cpp $(OBJ_DIR)/macchinettaSwitch.o $(CAFE_OBJS_DIR) -outdir $(OBJ_DIR) -output mocha.$(MEXE) \
$(INCLUDEPATH_MOCHA) \
LDFLAGS='$(LIB_LOCAL) $(LIBS)'
#$(OBJ_DIR)/libmacchinetta.so: $(OBJ_DIR)/macchinettaSwitch.o
# g++ -shared -Wl,-soname,libmacchinetta.so \
# $(OBJ_DIR)/macchinettaSwitch.o -o $(OBJ_DIR)/libmacchinetta.so
$(OBJ_DIR)/macchinettaSwitch.o: macchinettaSwitch.cpp macchinettaHelper.h \
macchinetta.h containerMochaccino.h
mex CXXFLAGS='-v -largeArrayDims -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread' \
-c macchinettaSwitch.cpp $(INCLUDEPATH_MACHINETTA) -outdir $(OBJ_DIR)
install: $(OBJ_DIR)/mocha.$(MEXE)
mkdir -p $(INSTALL_PATH)
mex CXXFLAGS='-v -largeArrayDims -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread' \
mocha.cpp $(OBJ_DIR)/macchinettaSwitch.o $(CAFE_OBJS_DIR) -outdir $(INSTALL_PATH) -output mocha.$(MEXE) \
$(INCLUDEPATH_MOCHA) \
LDFLAGS='$(LIB_INSTALL) $(LIBS)'
cp example.m $(INSTALL_PATH)
cp scripts/monitorAction.m $(INSTALL_PATH)
cp scripts/pvtable.m $(INSTALL_PATH)
cp scripts/test.xml $(INSTALL_PATH)
install_lib: $(OBJ_DIR)/libmacchinetta.so
mkdir -p $(INSTALL_PATH)
cp $(OBJ_DIR)/libmacchinetta.so $(INSTALL_PATH)
clean:
rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.so $(OBJ_DIR)/*.$(MEXE)

1
makefile Symbolic link
View File

@@ -0,0 +1 @@
makefile_rel_1.13-gcc-6.3.0

View File

@@ -1,70 +0,0 @@
MATLAB_ROOT=C:\'Program Files'\MATLAB\R2016b_x64
MEXE=mexw64
#c:\local\boost_1_62_0\
INCLUDES = -IC:\CAFE\CAFE\cpp\include -IC:\CAFE\CAFE\cpp -IC:\local\boost_1_62_0 \
-IC:\local\boost_1_62_0\boost -IC:\epics\base-3.14.12.5\include -IC:\epics\base-3.14.12.5\include\os\WIN32 \
-I"C:\Program Files\MATLAB\R2016b_x64\extern\include" \
-Ic:\Qt\qt-4.8.6-x64-msvc2010\include -Ic:\Qt\qt-4.8.6-x64-msvc2010\include\QtCore -Ic:\Qt\qt-4.8.6-msvc2010\include\QtXml
CXX=cl
CXXFLAGS = /W4 /EHsc
OUTPUT_OPTION = /o $@
LIB_LOCAL = C:\epics\base-3.14.12.5\lib\windows-x64\Com.lib C:\epics\base-3.14.12.5\lib\windows-x64\ca.lib \
C:\CAFE\CAFE\cpp\cafe.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_thread-vc100-mt-1_62.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_system-vc100-mt-1_62.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_chrono-vc100-mt-1_62.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_date_time-vc100-mt-1_62.lib \
C:\Qt\Qt-4.8.6-msvc2010\lib\QtCore4.lib C:\Qt\tq-4.8.6-msvc2010\lib\QtXml4.lib
#"C:\Program Files\MATLAB\R2016b_x64\extern\lib\win64\microsoft\libmat.lib" \
#"C:\Program Files\MATLAB\R2016b_x64\extern\lib\win64\microsoft\libmex.lib" \
#"C:\Program Files\MATLAB\R2016b_x64\extern\lib\win64\microsoft\libmx.lib"
LIB_CAFE=C:\CAFE\CAFE\cpp\cafe.lib
LIB_BOOST =C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_date_time-vc100-mt-1_62.lib
LIB_BOOST2=C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_date_time-vc100-mt-s-1_62.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_thread-vc100-mt-s-1_62.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_system-vc100-mt-s-1_62.lib \
C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_chrono-vc100-mt-s-1_62.lib
#LIB_BOOST2=C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_thread-vc100-mt-s-1_62.lib \
#C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_system-vc100-mt-s-1_62.lib \
#C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_date_time-vc100-mt-s-1_62.lib \
#C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_chrono-vc100-mt-s-1_62.lib
#LIB_BOOST=C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_thread-vc100-mt-1_62.lib \
#C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_system-vc100-mt-1_62.lib \
#C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_date_time-vc100-mt-1_62.lib \
#C:\local\boost_1_62_0\lib64-msvc-10.0\libboost_chrono-vc100-mt-1_62.lib
LIB_QT=C:\Qt\Qt-4.8.6-x64-msvc2010\lib\QtCore4.lib C:\Qt\qt-4.8.6-x64-msvc2010\lib\QtXml4.lib
LIB_EPICS=C:\epics\base-3.14.12.5\lib\windows-x64\Com.lib C:\epics\base-3.14.12.5\lib\windows-x64\ca.lib
OBJ_DIR=windows-x64
CAFE_OBJS = C:\CAFE\CAFE\cpp\src\cafeCache.obj C:\CAFE\CAFE\cpp\src\cafeGroup.obj C:\CAFE\CAFE\cpp\src\cafe.obj C:\CAFE\CAFE\cpp\src\cafeVectors.obj \
C:\CAFE\CAFE\cpp\src\cafeXML.obj C:\CAFE\CAFE\cpp\src\callbackHandlerCreate.obj C:\CAFE\CAFE\cpp\src\callbackHandlerMonitor.obj \
C:\CAFE\CAFE\cpp\src\conduitGroup.obj C:\CAFE\CAFE\cpp\src\conduit.obj \
C:\CAFE\CAFE\cpp\src\connectCallbacks.obj C:\CAFE\CAFE\cpp\src\connectGroup.obj \
C:\CAFE\CAFE\cpp\src\connect.obj C:\CAFE\CAFE\cpp\src\exceptionsHelper.obj C:\CAFE\CAFE\cpp\src\granules.obj C:\CAFE\CAFE\cpp\src\handleHelper.obj \
C:\CAFE\CAFE\cpp\src\helper.obj \
C:\CAFE\CAFE\cpp\src\loadCollectionXMLParser.obj C:\CAFE\CAFE\cpp\src\loadGroupXMLParser.obj C:\CAFE\CAFE\cpp\src\methodCallbacks.obj \
C:\CAFE\CAFE\cpp\src\policyHelper.obj \
C:\CAFE\CAFE\cpp\src\restorePVGroupXMLParser.obj C:\CAFE\CAFE\cpp\src\transpose.obj
#\NODEFAULTLIB
$(OBJ_DIR)\mocha.$(MEXE): mocha.cpp $(OBJ_DIR)\macchinettaSwitch.obj
"C:\Program Files\MATLAB\R2016b_x64\bin\win64\mex" -v COMPFLAGS="$(COMPFLAGS) -Wall" mocha.cpp $(OBJ_DIR)/macchinettaSwitch.obj -DDB_TEXT_GLBLSOURCE -DMSCC -DWIN32 -DWIN64 -largeArrayDims $(INCLUDES) $(LIB_EPICS) $(LIB_CAFE) $(LIB_BOOST) $(LIB_BOOST2) $(LIB_QT) \
-outdir $(OBJ_DIR) -output mocha.$(MEXE)
$(OBJ_DIR)\macchinettaSwitch.obj: macchinettaSwitch.cpp macchinettaHelper.h \
macchinetta.h containerMochaccino.h
"C:\Program Files\MATLAB\R2016b_x64\bin\win64\mex" -largeArrayDims \
-c macchinettaSwitch.cpp $(INCLUDES) -outdir $(OBJ_DIR)
clean:
rm -f $(OBJ_DIR)/*.obj $(OBJ_DIR)/*.$(MEXE)

99
msg.txt Normal file
View File

@@ -0,0 +1,99 @@
Re: cafe-matlab version 2020b and onwards.
Important information to cafe-matlab users.
Dear Colleagues,
Starting with MATLAB 2020b, the mocha mex-file
will only work if matlab is executed from the
following bash script:
source /opt/psi/Cafe/cafe-matlab.sh -v 2020b
This script by necessity momentarily adds the
EPICS libCom.so library to the LD_PRELOAD environment
variable before starting matlab. The library is
immediately removed from LD_PRELOAD once matlab is
executed. The setting of LD_PRELOAD was previously
handled from within the IT load module step but has
now been withdraw from this procedure and delegated
to the above script to prevent conflict with other
epics client applications running on the user's console
that would unwittingly pick up this lingering environment
variable.
An explanation as to why this is required is given below.
For those invoking the above script in their .bashrc
in order to load the cafe-matlab module for later use;
the script can continue to be used for this purpose for
matlab versions 2020a and earlier only:
source /opt/psi/Cafe/cafe-matlab.sh -v 2020a
The above script can also be used to both load the
cafe-matlab module and start matlab, e.g, on the
command line, for all matlab versions (old and new)
as follows:
source /opt/psi/Cafe/cafe-matlab.sh -v 2020a -s True
The -s flag controls whether or not to start matlab
and only plays a role only for matlab 2020a or earlier.
The default value is False (and thus matlab is started
explicitly by the user). For matlab 2020b onwards
the flag is always set to True. To learn of all script
options, see:
/opt/psi/Cafe/cafe-matlab.sh -h
FYI, the mocha mex-file for MATLAB version 2020a and
onwards uses the latest epics 7 client release:
mocha('epicsversion')
Please let me know if I can assist with anything.
Yours,
Jan
http://cafe.psi.ch/mocha.html
What's going on?
================
With input from a reply from Mathworks Technical Support.
MATLAB 2020b and subsequent versions require glibc
version 2.18 or greater. Red Hat 7 (RHEL7), however,
is based on the glib 2.17 release.
To allow MATLAB 2020b to run on RHEL7, MATLAB includes
a partial glib 2.18 implementation that is pre-loaded
atop of RHEL7's glibc 2.17. Unfortunately, there is
a documented bug in glib versions 2.18 - 2.22 that
results in a deadlock in libraries using pthread_join
when loaded. Since EPICS libCom library relies on this
method, any epics client mex-file will hang and freeze
matlab. The problem can be circumvented by specifically
pre-loading the EPICS libCom library before the partial
glibc 2.18 preload. In this way, libCom is loaded with
glibc 2.17 (which does not have this glibc bug.)
To PyCafe users.
Dear Colleagues,
FYI, updated PyCafe extensions for python 3.5, 3.7, and 3.8
have been provided using the latest epics7 client library.
If it is of interest to stay "au courant", please add the
following to your PYTHONPATH:
/opt/gfa/cafe/python/pycafe/cafe-1.15.0/lib/RHEL7-x86_64
The epics version can be retrieved with the following cafe method:
cafe.epics_version_string()
Please let me if you would like more information or help with anything.
Yours,
Jan
http://cafe.psi.ch/cython.html

3
out Normal file
View File

@@ -0,0 +1,3 @@
mex CXXFLAGS='-v -largeArrayDims -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread -std=c++1z' \
-c macchinettaSwitch.cpp -I/opt/psi/Programming/matlab/2021b/extern/include -I/opt/gfa/cafe/cpp/cafe-1.15.0-gcc-7.3.0/include -I./ -I/usr/local/epics/base-7.0.6/include -I/usr/local/epics/base-7.0.6/include/os/Linux -I/usr/local/epics/base-7.0.6/include/compiler/gcc -I/opt/gfa/cafe/boost/boost_1_61_0/include -I/opt/gfa/cafe/boost/boost_1_61_0/include/boost -outdir RHEL7-x86_64/2021b
Building with 'g++'.

View File

@@ -23,16 +23,20 @@ dstruct = mocha('getPVCache', hpv);
t=struct2table(dstruct);
for n=1:length(hpv)
s1(n).handle=hpv(n);
s1(n).handle=hpv(n);
s1(n).pv=pvn(n);
s1(n).cs=state(n);
s1(n).nmon=mocha('getNoMonitors', hpv(n));
end
t1=struct2table(s1);
if (string(class(t.val)) == string('char'))
t.val=string(t.val);
end
pvt=table(t1.handle,t1.pv,t.val, t.status, t1.cs);
pvt.Properties.VariableNames={'h','pv', 'val', 'stat','c'};
pvt=table(t1.handle,t1.pv, t.val, t.status, t1.cs, t1.nmon);
pvt.Properties.VariableNames={'h','pv', 'val', 'stat','c', 'm'};
%tNew.Properties.VariableNames{'Var1'}= 'handle';
%tNew.Properties.VariableNames{'Var2'}= 'pv';
%tNew.Properties.VariableNames{'Var3'}= 'val';