1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
/*
PsychToolbox3/Source/Common/MachPriorityMex/MachPriorityMex.c
PLATFORMS:
OS X only.
AUTHORS:
Allen Ingling awi Allen.Ingling@nyu.edu
Mario Kleiner mk
HISTORY:
8/08/02 awi wrote it.
10/29/04 awi fixed the spelling of "MachGetPriorityMex" in help lines.
2/17/05 mk Added proper error handling/reporting.
4/6/05 awi Merged Mario Kleiner's error handling improvements into Psychtoolbox.org master.
DESCRIPTION
MachSetPriorityMex is a simplified variant of MachPriority which strips out the Psychtoolbox mex/mx abstraction layer and separates
Get from Set. See also MachGetPriorityMex
Legal calls to MachSetPriorityMex:
priority=MachSetPriorityMex(['THREAD_STANDARD_POLICY'] );
priority=MachSetPriorityMex(['THREAD_STANDARD_POLICY'], 'default');
priority=MachSetPriorityMex(['THREAD_TIME_CONSTRAINT_POLICY', 'period','computation', 'constraint', 'preemptible');
priority=MachSetPriorityMex(['THREAD_TIME_CONSTRAINT_POLICY', 'default');
priority=MachSetPriorityMex(['THREAD_PRECEDENCE_POLICY', 'importance');
priority=MachSetPriorityMex(['THREAD_PRECEDENCE_POLICY', 'default');
NOTES:
See MachGetPrioritMex.c notes section.
IMPORTANT:
We seem to be missing some free statements below.
*/
#include "MachPriorityMex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
bool isError;
thread_policy_flavor_t flavorConstant;
int kernError;
task_t threadID;
thread_policy_t threadPolicy;
mach_msg_type_number_t policyCount, policyCountFilled;
boolean_t isDefault;
char commandString[COMMAND_STRING_LENGTH];
threadID= mach_thread_self();
kernError=0;
//get the policy flavor constant specified by the user and the getDefault argument
if(nrhs<1)
mexErrMsgTxt("MachGetPriorityMex requires at least one argument. See help MachGetPriorityMex.");
if(!mxIsChar(prhs[0]))
mexErrMsgTxt("First input argument is not a string. See help MachGetPriorityMex.");
mxGetString(prhs[0], commandString, COMMAND_STRING_LENGTH);
isError=GetFlavorConstantFromFlavorString(commandString, mxGetM(prhs[0]) * mxGetN(prhs[0]), &flavorConstant); //case sensitive.
if(isError)
mexErrMsgTxt("Unrecognized command. See help MachGetPriorityMex.");
//branch according to the first argument
switch(flavorConstant){
case THREAD_STANDARD_POLICY:
if(nrhs>2)
mexErrMsgTxt("Extra argument(s) detected. See help MachGetPriorityMex.");
if(nrhs==2){
if(!mxIsChar(prhs[1]))
mexErrMsgTxt("Expecting string in second argument. See help MachGetPriorityMex.");
mxGetString(prhs[1], commandString, COMMAND_STRING_LENGTH);
commandString[COMMAND_STRING_LENGTH-1]= '\0'; //guarantee strcmp an end of string character
if(strcmp(commandString, "default"))
mexErrMsgTxt("Unrecognized second argument. See help MachGetPriorityMex.");
}
threadPolicy=(thread_policy_t)malloc(sizeof(thread_standard_policy_data_t));
policyCount=THREAD_STANDARD_POLICY_COUNT;
policyCountFilled=policyCount;
isDefault=TRUE;
kernError=thread_policy_get(threadID, THREAD_STANDARD_POLICY, threadPolicy, &policyCountFilled, &isDefault);
if (kernError==0) kernError=thread_policy_set(threadID, THREAD_STANDARD_POLICY, threadPolicy, policyCountFilled);
break;
case THREAD_TIME_CONSTRAINT_POLICY:
if(nrhs==1)
mexErrMsgTxt("Missing argument detected. See help MachGetPriorityMex.");
else if(nrhs==2){
if(!mxIsChar(prhs[1]))
mexErrMsgTxt("Expecting string in second argument. See help MachGetPriorityMex.");
mxGetString(prhs[1], commandString, COMMAND_STRING_LENGTH);
commandString[COMMAND_STRING_LENGTH-1]= '\0'; //guarantee strcmp an end of string character
if(strcmp(commandString, "default"))
mexErrMsgTxt("Unrecognized second argument. See help MachGetPriorityMex.");
threadPolicy=(thread_policy_t)malloc(sizeof(thread_time_constraint_policy_data_t));
policyCount=THREAD_TIME_CONSTRAINT_POLICY_COUNT;
policyCountFilled=policyCount;
isDefault=TRUE;
kernError=thread_policy_get(threadID, THREAD_TIME_CONSTRAINT_POLICY, threadPolicy, &policyCountFilled, &isDefault);
if (kernError==0) kernError=thread_policy_set(threadID, THREAD_TIME_CONSTRAINT_POLICY, threadPolicy, policyCountFilled);
free((void*)threadPolicy);
break;
}else if(nrhs != 5)
mexErrMsgTxt("Incorrect number of arguments. See help MachGetPriorityMex.");
else{
if(! (mxIsDouble(prhs[1]) && mxGetM(prhs[1]) * mxGetN(prhs[1]) == 1))
mexErrMsgTxt("Expected double in second argument. See help MachSetPriorityMex.");
if(! (mxIsDouble(prhs[2]) && mxGetM(prhs[2]) * mxGetN(prhs[2]) == 1))
mexErrMsgTxt("Expected double in third argument. See help MachSetPriorityMex.");
if(! (mxIsDouble(prhs[3]) && mxGetM(prhs[3]) * mxGetN(prhs[3]) == 1))
mexErrMsgTxt("Expected double in fourth argument. See help MachGetPriorityMex.");
if(!((mxIsDouble(prhs[4]) || mxIsLogical(prhs[4])) && (mxGetM(prhs[4]) * mxGetN(prhs[4]) == 1)))
mexErrMsgTxt("Expected double or logical in fifth argument. See help MachSetPriorityMex.");
threadPolicy=(thread_policy_t)malloc(sizeof(thread_time_constraint_policy_data_t));
((thread_time_constraint_policy_t)threadPolicy)->period=(uint32_t)mxGetPr(prhs[1])[0];
((thread_time_constraint_policy_t)threadPolicy)->computation=(uint32_t)mxGetPr(prhs[2])[0];
((thread_time_constraint_policy_t)threadPolicy)->constraint=(uint32_t)mxGetPr(prhs[3])[0];
((thread_time_constraint_policy_t)threadPolicy)->preemptible= (boolean_t)(mxIsDouble(prhs[4]) ? mxGetPr(prhs[4])[0] : mxGetLogicals(prhs[4])[0]);
policyCount=THREAD_TIME_CONSTRAINT_POLICY_COUNT;
policyCountFilled=policyCount;
kernError=thread_policy_set(threadID, THREAD_TIME_CONSTRAINT_POLICY, threadPolicy, policyCountFilled);
free((void*)threadPolicy);
break;
}
case THREAD_PRECEDENCE_POLICY:
if(nrhs>2)
mexErrMsgTxt("Extra argument(s) detected. See help MachGetPriorityMex.");
if(nrhs<2)
mexErrMsgTxt("Missing argument detected. See help MachGetPriorityMex.");
if(mxIsChar(prhs[1])){ //set the default
mxGetString(prhs[1], commandString, COMMAND_STRING_LENGTH);
commandString[COMMAND_STRING_LENGTH-1]= '\0'; //guarantee strcmp an end of string character
if(strcmp(commandString, "default"))
mexErrMsgTxt("Unrecognized second argument. See help MachGetPriorityMex.");
threadPolicy=(thread_policy_t)malloc(sizeof(thread_precedence_policy_data_t));
policyCount=THREAD_PRECEDENCE_POLICY_COUNT;
policyCountFilled=policyCount;
isDefault=TRUE;
kernError=thread_policy_get(threadID, THREAD_PRECEDENCE_POLICY, threadPolicy, &policyCountFilled, &isDefault);
if (kernError==0) kernError=thread_policy_set(threadID, THREAD_PRECEDENCE_POLICY, threadPolicy, policyCountFilled);
free((void*)threadPolicy);
break;
}else if(mxIsDouble(prhs[1]) && mxGetM(prhs[1]) * mxGetN(prhs[1]) == 1){ //set a specified value
threadPolicy=(thread_policy_t)malloc(sizeof(thread_precedence_policy_data_t));
((thread_precedence_policy_t)threadPolicy)->importance=(integer_t)mxGetPr(prhs[1])[0];
policyCount=THREAD_PRECEDENCE_POLICY_COUNT;
policyCountFilled=policyCount;
kernError=thread_policy_set(threadID, THREAD_PRECEDENCE_POLICY, threadPolicy, policyCountFilled);
}
}
// Check for and report errors in thread_policy_set:
if (kernError!=0) {
mexErrMsgTxt("ERROR: Failed to set requested thread scheduling policy! thread_policy_set() failed!");
}
}
|