Matlab crashes runing Multi Thread s-function with openGL
2 views (last 30 days)
Show older comments
Hi! I try to write a simple s-function with openGL/freeglut. I compile it within Visual Studio ( how to do it ). When i run my s-function in Simulink it works only the first time. The second attempt of running the model results in Matlab crash, but the matlab process steel exist in a memory.
May be there is a mistake with memory or thread manipulation? I find out that Matlab crashes at glutInit function
Will be very glad if somebody can help me because i have found almost no information about s-function used with multithreading or openGL.
Here is the code:
#define S_FUNCTION_NAME my_sf
#define S_FUNCTION_LEVEL 2
#include <simstruc.h>
#include <freeglut.h>
#include <Math.h>
#include <windows.h>
#include <process.h>
#include <stdio.h>
struct data_st {
unsigned ThreadId;
HANDLE hThread, hEvent;
};
void display() {
glClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer with current clearing color
// Define shapes enclosed within a pair of glBegin and glEnd
glBegin(GL_QUADS); // Each set of 4 vertices form a quad
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex2f(-0.8f, 0.1f); // Define vertices in counter-clockwise (CCW) order
glVertex2f(-0.2f, 0.1f); // so that the normal (front-face) is facing you
glVertex2f(-0.2f, 0.7f);
glVertex2f(-0.8f, 0.7f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex2f(-0.7f, -0.6f);
glVertex2f(-0.1f, -0.6f);
glVertex2f(-0.1f, 0.0f);
glVertex2f(-0.7f, 0.0f);
glColor3f(0.2f, 0.2f, 0.2f); // Dark Gray
glVertex2f(-0.9f, -0.7f);
glColor3f(1.0f, 1.0f, 1.0f); // White
glVertex2f(-0.5f, -0.7f);
glColor3f(0.2f, 0.2f, 0.2f); // Dark Gray
glVertex2f(-0.5f, -0.3f);
glColor3f(1.0f, 1.0f, 1.0f); // White
glVertex2f(-0.9f, -0.3f);
glEnd();
glBegin(GL_TRIANGLES); // Each set of 3 vertices form a triangle
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex2f(0.1f, -0.6f);
glVertex2f(0.7f, -0.6f);
glVertex2f(0.4f, -0.1f);
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex2f(0.3f, -0.4f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex2f(0.9f, -0.4f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex2f(0.6f, -0.9f);
glEnd();
glBegin(GL_POLYGON); // These vertices form a closed polygon
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex2f(0.4f, 0.2f);
glVertex2f(0.6f, 0.2f);
glVertex2f(0.7f, 0.4f);
glVertex2f(0.6f, 0.6f);
glVertex2f(0.4f, 0.6f);
glVertex2f(0.3f, 0.4f);
glEnd();
glFlush(); // Render now
}
void do_nothing(void) {
return;
}
unsigned __stdcall plot(struct data_st* data) {
char *argv[1];
int argc = 1;
argv[0] = strdup("Myappname");
glutInit(&argc, argv); // Initialize GLUT
glutCreateWindow("Vertex, Primitive & Color"); // Create window with the given title
glutInitWindowSize(320, 320); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutDisplayFunc(do_nothing); // Register callback handler for window re-paint event
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
while (WaitForSingleObject(data->hEvent, 0) != WAIT_OBJECT_0) {
display();
glutMainLoopEvent();
}
//glutDestroyWindow( glutGetWindow() );
return(0);
}
/* Function: mdlInitializeSizes ===============================================
* Abstract:
* Setup sizes of the various vectors.
*/
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 0);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return; /* Parameter mismatch will be reported by Simulink */
}
if (!ssSetNumInputPorts(S, 1)) return;
ssSetInputPortWidth(S, 0, 1);
ssSetInputPortDirectFeedThrough(S, 0, 1);
if (!ssSetNumOutputPorts(S,1)) return;
ssSetOutputPortWidth(S, 0, 1);
ssSetNumSampleTimes(S, 1);
/* specify the sim state compliance to be same as a built-in block */
ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);
ssSetNumDWork(S, 1);
ssSetDWorkWidth(S, 0, 1);
ssSetDWorkDataType(S, 0, SS_POINTER);
ssSetOptions(S,
SS_OPTION_WORKS_WITH_CODE_REUSE |
SS_OPTION_EXCEPTION_FREE_CODE |
SS_OPTION_USE_TLC_WITH_ACCELERATOR);
}
#define MDL_START
void mdlStart(SimStruct *S)
{
void **Ptrs = (void**)ssGetDWork(S, 0);
struct data_st* data;
data = (void*)malloc(sizeof(struct data_st));
Ptrs[0] = data;
data -> hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
data -> hThread = (HANDLE)_beginthreadex(NULL, 0, plot, data, 0, &(data->ThreadId));
if (data->hThread == 0)
return;
}
/* Function: mdlInitializeSampleTimes =========================================
* Abstract:
* Specifiy that we inherit our sample time from the driving block.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
ssSetModelReferenceSampleTimeDefaultInheritance(S);
}
/* Function: mdlOutputs =======================================================
* Abstract:
* y = 2*u
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
real_T *y = ssGetOutputPortRealSignal(S,0);
*y = 2.0 *(*uPtrs[0]);
}
/* Function: mdlTerminate =====================================================
* Abstract:
* No termination needed, but we are required to have this routine.
*/
static void mdlTerminate(SimStruct *S)
{
void **Ptrs = (void**)ssGetDWork(S, 0);
struct data_st* data;
data = Ptrs[0];
SetEvent(data->hEvent); // init event for thread stop
WaitForSingleObject(data->hThread, INFINITE); // wait thread to be finised
CloseHandle(data->hEvent);
CloseHandle(data->hThread);
free(data);
}
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
0 Comments
Accepted Answer
More Answers (0)
See Also
Categories
Find more on Simulink Coder in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!