PageRenderTime 30ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/peer/src/peer.c

http://fieldtrip.googlecode.com/
C | 1509 lines | 1180 code | 158 blank | 171 comment | 320 complexity | e623631fabbfa338e572a05197f61991 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, AGPL-1.0, BSD-3-Clause, LGPL-2.0, BSD-2-Clause, LGPL-3.0
  1. /*
  2. * Copyright (C) 2010, Robert Oostenveld
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/
  16. *
  17. */
  18. #include "mex.h"
  19. #include "matrix.h"
  20. #include <pthread.h>
  21. #include "peer.h"
  22. #include "extern.h"
  23. #include "platform_includes.h"
  24. mxArray *mxSerialize(const mxArray*);
  25. mxArray *mxDeserialize(const void*, size_t);
  26. #define JOB_FIELDNUMBER 4
  27. const char* job_fieldnames[JOB_FIELDNUMBER] = {"version", "jobid", "argsize", "optsize"};
  28. #define JOBLIST_FIELDNUMBER 9
  29. const char* joblist_fieldnames[JOBLIST_FIELDNUMBER] = {"version", "jobid", "argsize", "optsize", "hostid", "hostname", "user", "memreq", "timreq"};
  30. #define PEERINFO_FIELDNUMBER 16
  31. const char* peerinfo_fieldnames[PEERINFO_FIELDNUMBER] = {"hostid", "hostname", "user", "group", "socket", "port", "status", "timavail", "memavail", "cpuavail", "allowuser", "allowgroup", "allowhost", "refuseuser", "refusegroup", "refusehost"};
  32. #define PEERLIST_FIELDNUMBER 11
  33. const char* peerlist_fieldnames[PEERLIST_FIELDNUMBER] = {"hostid", "hostname", "user", "group", "socket", "port", "status", "timavail", "memavail", "cpuavail", "current"};
  34. #define CURRENT_FIELDNUMBER 8
  35. const char* current_fieldnames[CURRENT_FIELDNUMBER] = {"hostid", "jobid", "hostname", "user", "group", "timreq", "memreq", "cpureq"};
  36. int peerInitialized = 0;
  37. /* the thread IDs are needed for cancelation at cleanup */
  38. pthread_t udsserverThread;
  39. pthread_t tcpserverThread;
  40. pthread_t announceThread;
  41. pthread_t discoverThread;
  42. pthread_t expireThread;
  43. /* this is called the first time that the mex-file is loaded */
  44. void initFun(void) {
  45. /* check whether the host has been initialized already */
  46. if (!peerInitialized) {
  47. /* open the logging facility and set the default level */
  48. #if SYSLOG ==1
  49. openlog("peer.mex", LOG_PID, LOG_USER);
  50. setlogmask(LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) | LOG_MASK(LOG_CRIT));
  51. #endif
  52. mexPrintf("peer: init\n");
  53. peerinit(NULL);
  54. peerInitialized = 1;
  55. }
  56. return;
  57. }
  58. /* this function is called upon unloading of the mex-file */
  59. void exitFun(void) {
  60. mexPrintf("peer: exit\n");
  61. /* tell all threads to stop running */
  62. pthread_mutex_lock(&mutexstatus);
  63. if (udsserverStatus) {
  64. pthread_mutex_unlock(&mutexstatus);
  65. mexPrintf("peer: requesting cancelation of udsserver thread\n");
  66. pthread_cancel(udsserverThread);
  67. pthread_join(udsserverThread, NULL);
  68. }
  69. else {
  70. pthread_mutex_unlock(&mutexstatus);
  71. }
  72. pthread_mutex_lock(&mutexstatus);
  73. if (tcpserverStatus) {
  74. pthread_mutex_unlock(&mutexstatus);
  75. mexPrintf("peer: requesting cancelation of tcpserver thread\n");
  76. pthread_cancel(tcpserverThread);
  77. pthread_join(tcpserverThread, NULL);
  78. }
  79. else {
  80. pthread_mutex_unlock(&mutexstatus);
  81. }
  82. pthread_mutex_lock(&mutexstatus);
  83. if (announceStatus) {
  84. pthread_mutex_unlock(&mutexstatus);
  85. mexPrintf("peer: requesting cancelation of announce thread\n");
  86. pthread_cancel(announceThread);
  87. pthread_join(announceThread, NULL);
  88. }
  89. else {
  90. pthread_mutex_unlock(&mutexstatus);
  91. }
  92. pthread_mutex_lock(&mutexstatus);
  93. if (discoverStatus) {
  94. pthread_mutex_unlock(&mutexstatus);
  95. mexPrintf("peer: requesting cancelation of discover thread\n");
  96. pthread_cancel(discoverThread);
  97. pthread_join(discoverThread, NULL);
  98. }
  99. else {
  100. pthread_mutex_unlock(&mutexstatus);
  101. }
  102. pthread_mutex_lock(&mutexstatus);
  103. if (expireStatus) {
  104. pthread_mutex_unlock(&mutexstatus);
  105. mexPrintf("peer: requesting cancelation of expire thread\n");
  106. pthread_cancel(expireThread);
  107. pthread_join(expireThread, NULL);
  108. }
  109. else {
  110. pthread_mutex_unlock(&mutexstatus);
  111. }
  112. /* free the shared dynamical memory */
  113. peerexit(NULL);
  114. peerInitialized = 0;
  115. /* switch off the logging facility */
  116. #if SYSLOG == 1
  117. closelog();
  118. #endif
  119. return;
  120. }
  121. void mexFunction (int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) {
  122. char command[STRLEN];
  123. char argument[STRLEN];
  124. char *ptr;
  125. int i, j, n, rc, t, found, handshake, success, count, server, status;
  126. UINT32_T peerid, jobid;
  127. UINT64_T memreq, cpureq, timreq;
  128. jobdef_t *def;
  129. joblist_t *job, *nextjob;
  130. peerlist_t *peer;
  131. userlist_t *allowuser, *refuseuser;
  132. grouplist_t *allowgroup, *refusegroup;
  133. hostlist_t *allowhost, *refusehost;
  134. mxArray *arg, *opt, *key, *val, *current;
  135. initFun();
  136. mexAtExit(exitFun);
  137. /* the first argument is always the command string */
  138. if (nrhs<1)
  139. mexErrMsgTxt ("invalid number of input arguments");
  140. if (!mxIsChar(prhs[0]))
  141. mexErrMsgTxt ("invalid input argument #1");
  142. if (mxGetString(prhs[0], command, STRLEN-1))
  143. mexErrMsgTxt ("invalid input argument #1");
  144. /* convert to lower case */
  145. ptr = command;
  146. while (*ptr) {
  147. *ptr = tolower(*ptr);
  148. ptr++;
  149. }
  150. ptr = argument;
  151. while (*ptr) {
  152. *ptr = tolower(*ptr);
  153. ptr++;
  154. }
  155. /****************************************************************************/
  156. if (strcmp(command, "announce")==0) {
  157. /* the input arguments should be "tcpserver <start|stop|status>" */
  158. if (nrhs<2)
  159. mexErrMsgTxt ("invalid number of input arguments");
  160. if (!mxIsChar(prhs[1]))
  161. mexErrMsgTxt ("invalid input argument #2");
  162. if (mxGetString(prhs[1], argument, STRLEN-1))
  163. mexErrMsgTxt ("invalid input argument #2");
  164. if (strcmp(argument, "start")==0) {
  165. if (announceStatus) {
  166. mexWarnMsgTxt("thread is already running");
  167. return;
  168. }
  169. mexPrintf("peer: spawning announce thread\n");
  170. rc = pthread_create(&announceThread, NULL, announce, (void *)NULL);
  171. if (rc)
  172. mexErrMsgTxt("problem with return code from pthread_create()");
  173. else {
  174. /* wait until the thread has properly started */
  175. pthread_mutex_lock(&mutexstatus);
  176. if (!announceStatus)
  177. pthread_cond_wait(&condstatus, &mutexstatus);
  178. pthread_mutex_unlock(&mutexstatus);
  179. }
  180. }
  181. else if (strcmp(argument, "stop")==0) {
  182. if (!announceStatus) {
  183. mexWarnMsgTxt("thread is not running");
  184. return;
  185. }
  186. mexPrintf("peer: requesting cancelation of announce thread\n");
  187. rc = pthread_cancel(announceThread);
  188. if (rc)
  189. mexErrMsgTxt("problem with return code from pthread_cancel()");
  190. }
  191. else if (strcmp(argument, "status")==0) {
  192. plhs[0] = mxCreateDoubleScalar(announceStatus);
  193. }
  194. else
  195. mexErrMsgTxt ("invalid input argument #2");
  196. return;
  197. }
  198. /****************************************************************************/
  199. else if (strcmp(command, "discover")==0) {
  200. /* the input arguments should be "discover <start|stop|status>" */
  201. if (nrhs<2)
  202. mexErrMsgTxt ("invalid number of input arguments");
  203. if (!mxIsChar(prhs[1]))
  204. mexErrMsgTxt ("invalid input argument #2");
  205. if (mxGetString(prhs[1], argument, STRLEN-1))
  206. mexErrMsgTxt ("invalid input argument #2");
  207. if (strcmp(argument, "start")==0) {
  208. if (discoverStatus) {
  209. mexWarnMsgTxt("thread is already running");
  210. return;
  211. }
  212. mexPrintf("peer: spawning discover thread\n");
  213. rc = pthread_create(&discoverThread, NULL, discover, (void *)NULL);
  214. if (rc)
  215. mexErrMsgTxt("problem with return code from pthread_create()");
  216. else {
  217. /* wait until the thread has properly started */
  218. pthread_mutex_lock(&mutexstatus);
  219. if (!discoverStatus)
  220. pthread_cond_wait(&condstatus, &mutexstatus);
  221. pthread_mutex_unlock(&mutexstatus);
  222. }
  223. }
  224. else if (strcmp(argument, "stop")==0) {
  225. if (!discoverStatus) {
  226. mexWarnMsgTxt("thread is not running");
  227. return;
  228. }
  229. mexPrintf("peer: requesting cancelation of discover thread\n");
  230. rc = pthread_cancel(discoverThread);
  231. if (rc)
  232. mexErrMsgTxt("problem with return code from pthread_cancel()");
  233. }
  234. else if (strcmp(argument, "status")==0) {
  235. plhs[0] = mxCreateDoubleScalar(discoverStatus);
  236. }
  237. else
  238. mexErrMsgTxt ("invalid input argument #2");
  239. return;
  240. }
  241. /****************************************************************************/
  242. else if (strcmp(command, "expire")==0) {
  243. /* the input arguments should be "expire <start|stop|status>" */
  244. if (nrhs<2)
  245. mexErrMsgTxt ("invalid number of input arguments");
  246. if (!mxIsChar(prhs[1]))
  247. mexErrMsgTxt ("invalid input argument #2");
  248. if (mxGetString(prhs[1], argument, STRLEN-1))
  249. mexErrMsgTxt ("invalid input argument #2");
  250. if (strcmp(argument, "start")==0) {
  251. if (expireStatus) {
  252. mexWarnMsgTxt("thread is already running");
  253. return;
  254. }
  255. mexPrintf("peer: spawning expire thread\n");
  256. rc = pthread_create(&expireThread, NULL, expire, (void *)NULL);
  257. if (rc)
  258. mexErrMsgTxt("problem with return code from pthread_create()");
  259. else {
  260. /* wait until the thread has properly started */
  261. pthread_mutex_lock(&mutexstatus);
  262. if (!expireStatus)
  263. pthread_cond_wait(&condstatus, &mutexstatus);
  264. pthread_mutex_unlock(&mutexstatus);
  265. }
  266. }
  267. else if (strcmp(argument, "stop")==0) {
  268. if (!expireStatus) {
  269. mexWarnMsgTxt("thread is not running");
  270. return;
  271. }
  272. mexPrintf("peer: requesting cancelation of expire thread\n");
  273. rc = pthread_cancel(expireThread);
  274. if (rc)
  275. mexErrMsgTxt("problem with return code from pthread_cancel()");
  276. }
  277. else if (strcmp(argument, "status")==0) {
  278. plhs[0] = mxCreateDoubleScalar(expireStatus);
  279. }
  280. else
  281. mexErrMsgTxt ("invalid input argument #2");
  282. return;
  283. }
  284. /****************************************************************************/
  285. else if (strcmp(command, "udsserver")==0) {
  286. /* the input arguments should be "udsserver <start|stop|status>" */
  287. if (nrhs<2)
  288. mexErrMsgTxt ("invalid number of input arguments");
  289. if (!mxIsChar(prhs[1]))
  290. mexErrMsgTxt ("invalid input argument #2");
  291. if (mxGetString(prhs[1], argument, STRLEN-1))
  292. mexErrMsgTxt ("invalid input argument #2");
  293. if (strcmp(argument, "start")==0) {
  294. if (udsserverStatus) {
  295. mexWarnMsgTxt("thread is already running");
  296. return;
  297. }
  298. mexPrintf("peer: spawning udsserver thread\n");
  299. rc = pthread_create(&udsserverThread, NULL, udsserver, (void *)NULL);
  300. if (rc)
  301. mexErrMsgTxt("problem with return code from pthread_create()");
  302. else {
  303. /* wait until the thread has properly started */
  304. pthread_mutex_lock(&mutexstatus);
  305. if (!udsserverStatus)
  306. pthread_cond_wait(&condstatus, &mutexstatus);
  307. pthread_mutex_unlock(&mutexstatus);
  308. /* inform the other peers of the updated unix domain socket */
  309. announce_once();
  310. }
  311. }
  312. else if (strcmp(argument, "stop")==0) {
  313. if (!udsserverStatus) {
  314. mexWarnMsgTxt("thread is not running");
  315. return;
  316. }
  317. mexPrintf("peer: requesting cancelation of udsserver thread\n");
  318. rc = pthread_cancel(udsserverThread);
  319. if (rc)
  320. mexErrMsgTxt("problem with return code from pthread_cancel()");
  321. else
  322. /* inform the other peers of the updated unix domain socket */
  323. announce_once();
  324. }
  325. else if (strcmp(argument, "status")==0) {
  326. plhs[0] = mxCreateDoubleScalar(udsserverStatus);
  327. }
  328. else
  329. mexErrMsgTxt ("invalid input argument #2");
  330. return;
  331. }
  332. /****************************************************************************/
  333. if (strcmp(command, "tcpserver")==0) {
  334. /* the input arguments should be "tcpserver <start|stop|status>" */
  335. if (nrhs<2)
  336. mexErrMsgTxt ("invalid number of input arguments");
  337. if (!mxIsChar(prhs[1]))
  338. mexErrMsgTxt ("invalid input argument #2");
  339. if (mxGetString(prhs[1], argument, STRLEN-1))
  340. mexErrMsgTxt ("invalid input argument #2");
  341. if (strcmp(argument, "start")==0) {
  342. if (tcpserverStatus) {
  343. mexWarnMsgTxt("thread is already running");
  344. return;
  345. }
  346. mexPrintf("peer: spawning tcpserver thread\n");
  347. rc = pthread_create(&tcpserverThread, NULL, tcpserver, (void *)NULL);
  348. if (rc)
  349. mexErrMsgTxt("problem with return code from pthread_create()");
  350. else {
  351. /* wait until the thread has properly started */
  352. pthread_mutex_lock(&mutexstatus);
  353. if (!tcpserverStatus)
  354. pthread_cond_wait(&condstatus, &mutexstatus);
  355. pthread_mutex_unlock(&mutexstatus);
  356. /* inform the other peers of the tcp server status */
  357. announce_once();
  358. }
  359. }
  360. else if (strcmp(argument, "stop")==0) {
  361. if (!tcpserverStatus) {
  362. mexWarnMsgTxt("thread is not running");
  363. return;
  364. }
  365. mexPrintf("peer: requesting cancelation of tcpserver thread\n");
  366. rc = pthread_cancel(tcpserverThread);
  367. if (rc)
  368. mexErrMsgTxt("problem with return code from pthread_cancel()");
  369. else
  370. /* inform the other peers of the updated tcp server status */
  371. announce_once();
  372. }
  373. else if (strcmp(argument, "status")==0) {
  374. plhs[0] = mxCreateDoubleScalar(tcpserverStatus);
  375. }
  376. else
  377. mexErrMsgTxt ("invalid input argument #2");
  378. return;
  379. }
  380. /****************************************************************************/
  381. else if (strcmp(command, "peerlist")==0) {
  382. /* it can be followed by an optional input argument "peerlist <status>" */
  383. if (nrhs>1) {
  384. /* only return the list for the desired status */
  385. if (!mxIsNumeric(prhs[1]))
  386. mexErrMsgTxt ("invalid input argument #2");
  387. else
  388. status = (UINT32_T)mxGetScalar(prhs[1]);
  389. }
  390. else {
  391. /* this is to be interpreted as "any status" */
  392. status = -1;
  393. }
  394. /* count the number of peers */
  395. i = 0;
  396. pthread_mutex_lock(&mutexpeerlist);
  397. peer = peerlist;
  398. while(peer) {
  399. i += (status==-1 ? 1 : (peer->host->status==status));
  400. peer = peer->next ;
  401. }
  402. plhs[0] = mxCreateStructMatrix(i, 1, PEERLIST_FIELDNUMBER, peerlist_fieldnames);
  403. i = 0;
  404. peer = peerlist;
  405. while(peer) {
  406. if (status!=-1 && peer->host->status!=status) {
  407. peer = peer->next;
  408. continue;
  409. }
  410. j = 0;
  411. mxSetFieldByNumber(plhs[0], i, j++, mxCreateDoubleScalar((UINT32_T)(peer->host->id)));
  412. mxSetFieldByNumber(plhs[0], i, j++, mxCreateString(peer->host->name));
  413. mxSetFieldByNumber(plhs[0], i, j++, mxCreateString(peer->host->user));
  414. mxSetFieldByNumber(plhs[0], i, j++, mxCreateString(peer->host->group));
  415. mxSetFieldByNumber(plhs[0], i, j++, mxCreateString(peer->host->socket));
  416. mxSetFieldByNumber(plhs[0], i, j++, mxCreateDoubleScalar((UINT32_T)(peer->host->port)));
  417. mxSetFieldByNumber(plhs[0], i, j++, mxCreateDoubleScalar((UINT32_T)(peer->host->status)));
  418. mxSetFieldByNumber(plhs[0], i, j++, mxCreateDoubleScalar((UINT64_T)(peer->host->timavail)));
  419. mxSetFieldByNumber(plhs[0], i, j++, mxCreateDoubleScalar((UINT64_T)(peer->host->memavail)));
  420. mxSetFieldByNumber(plhs[0], i, j++, mxCreateDoubleScalar((UINT64_T)(peer->host->cpuavail)));
  421. current = mxCreateStructMatrix(1, 1, CURRENT_FIELDNUMBER, current_fieldnames);
  422. mxSetFieldByNumber(current, 0, 0, mxCreateDoubleScalar(peer->host->current.hostid));
  423. mxSetFieldByNumber(current, 0, 1, mxCreateDoubleScalar(peer->host->current.jobid));
  424. mxSetFieldByNumber(current, 0, 2, mxCreateString(peer->host->current.name));
  425. mxSetFieldByNumber(current, 0, 3, mxCreateString(peer->host->current.user));
  426. mxSetFieldByNumber(current, 0, 4, mxCreateString(peer->host->current.group));
  427. mxSetFieldByNumber(current, 0, 5, mxCreateDoubleScalar(peer->host->current.timreq));
  428. mxSetFieldByNumber(current, 0, 6, mxCreateDoubleScalar(peer->host->current.memreq));
  429. mxSetFieldByNumber(current, 0, 7, mxCreateDoubleScalar(peer->host->current.cpureq));
  430. mxSetFieldByNumber(plhs[0], i, j++, current);
  431. i++;
  432. peer = peer->next ;
  433. }
  434. pthread_mutex_unlock(&mutexpeerlist);
  435. return;
  436. }
  437. /****************************************************************************/
  438. else if (strcmp(command, "joblist")==0) {
  439. /* count the number of jobs */
  440. i = 0;
  441. pthread_mutex_lock(&mutexjoblist);
  442. job = joblist;
  443. while(job) {
  444. i++;
  445. job = job->next ;
  446. }
  447. plhs[0] = mxCreateStructMatrix(i, 1, JOBLIST_FIELDNUMBER, joblist_fieldnames);
  448. i = 0;
  449. job = joblist;
  450. while(job) {
  451. mxSetFieldByNumber(plhs[0], i, 0, mxCreateDoubleScalar((UINT32_T)(job->job->version)));
  452. mxSetFieldByNumber(plhs[0], i, 1, mxCreateDoubleScalar((UINT32_T)(job->job->id)));
  453. mxSetFieldByNumber(plhs[0], i, 2, mxCreateDoubleScalar((UINT32_T)(job->job->argsize)));
  454. mxSetFieldByNumber(plhs[0], i, 3, mxCreateDoubleScalar((UINT32_T)(job->job->optsize)));
  455. mxSetFieldByNumber(plhs[0], i, 4, mxCreateDoubleScalar((UINT32_T)(job->host->id)));
  456. mxSetFieldByNumber(plhs[0], i, 5, mxCreateString(job->host->name));
  457. mxSetFieldByNumber(plhs[0], i, 6, mxCreateString(job->host->user));
  458. mxSetFieldByNumber(plhs[0], i, 7, mxCreateDoubleScalar((UINT64_T)(job->job->memreq)));
  459. mxSetFieldByNumber(plhs[0], i, 8, mxCreateDoubleScalar((UINT64_T)(job->job->timreq)));
  460. job = job->next;
  461. i++;
  462. }
  463. pthread_mutex_unlock(&mutexjoblist);
  464. return;
  465. }
  466. /****************************************************************************/
  467. else if (strcmp(command, "status")==0) {
  468. /* the input arguments should be "status <number>" */
  469. if (nrhs<2) {
  470. mexErrMsgTxt ("invalid number of input arguments");
  471. }
  472. else {
  473. if (!mxIsNumeric(prhs[1]))
  474. mexErrMsgTxt ("invalid input argument #2");
  475. if (!mxIsScalar(prhs[1]))
  476. mexErrMsgTxt ("invalid input argument #2");
  477. pthread_mutex_lock(&mutexhost);
  478. host->status = (UINT32_T)mxGetScalar(prhs[1]);
  479. pthread_mutex_unlock(&mutexhost);
  480. /* inform the other peers of the updated status */
  481. announce_once();
  482. }
  483. }
  484. /****************************************************************************/
  485. else if (strcmp(command, "info")==0) {
  486. /* the input arguments should be "info" */
  487. /* display all possible information on screen */
  488. pthread_mutex_lock(&mutexstatus);
  489. mexPrintf("tcpserverStatus = %d\n", tcpserverStatus);
  490. mexPrintf("udsserverStatus = %d\n", udsserverStatus);
  491. mexPrintf("announceStatus = %d\n", announceStatus);
  492. mexPrintf("discoverStatus = %d\n", discoverStatus);
  493. mexPrintf("expireStatus = %d\n", expireStatus);
  494. pthread_mutex_unlock(&mutexstatus);
  495. pthread_mutex_lock(&mutexhost);
  496. mexPrintf("host.id = %u\n", host->id);
  497. mexPrintf("host.name = %s\n", host->name);
  498. mexPrintf("host.port = %u\n", host->port);
  499. mexPrintf("host.user = %s\n", host->user);
  500. mexPrintf("host.group = %s\n", host->group);
  501. mexPrintf("host.status = %u\n", host->status);
  502. mexPrintf("host.timavail = %llu\n", host->timavail);
  503. mexPrintf("host.memavail = %llu\n", host->memavail);
  504. mexPrintf("host.cpuavail = %llu\n", host->cpuavail);
  505. pthread_mutex_unlock(&mutexhost);
  506. pthread_mutex_lock(&mutexsmartmem);
  507. mexPrintf("smartmem.enabled = %d\n", smartmem.enabled);
  508. pthread_mutex_unlock(&mutexsmartmem);
  509. pthread_mutex_lock(&mutexsmartcpu);
  510. mexPrintf("smartcpu.enabled = %d\n", smartcpu.enabled);
  511. pthread_mutex_unlock(&mutexsmartcpu);
  512. pthread_mutex_lock(&mutexsmartshare);
  513. mexPrintf("smartshare.enabled = %d\n", smartshare.enabled);
  514. pthread_mutex_unlock(&mutexsmartshare);
  515. pthread_mutex_lock(&mutexallowuserlist);
  516. allowuser = allowuserlist;
  517. while (allowuser) {
  518. mexPrintf("allowuser = %s\n", allowuser->name);
  519. allowuser = allowuser->next;
  520. }
  521. pthread_mutex_unlock(&mutexallowuserlist);
  522. pthread_mutex_lock(&mutexallowgrouplist);
  523. allowgroup = allowgrouplist;
  524. while (allowgroup) {
  525. mexPrintf("allowgroup = %s\n", allowgroup->name);
  526. allowgroup = allowgroup->next;
  527. }
  528. pthread_mutex_unlock(&mutexallowgrouplist);
  529. pthread_mutex_lock(&mutexallowhostlist);
  530. allowhost = allowhostlist;
  531. while (allowhost) {
  532. mexPrintf("allowhost = %s\n", allowhost->name);
  533. allowhost = allowhost->next;
  534. }
  535. pthread_mutex_unlock(&mutexallowhostlist);
  536. pthread_mutex_lock(&mutexrefuseuserlist);
  537. refuseuser = refuseuserlist;
  538. while (refuseuser) {
  539. mexPrintf("refuseuser = %s\n", refuseuser->name);
  540. refuseuser = refuseuser->next;
  541. }
  542. pthread_mutex_unlock(&mutexrefuseuserlist);
  543. pthread_mutex_lock(&mutexrefusegrouplist);
  544. refusegroup = refusegrouplist;
  545. while (refusegroup) {
  546. mexPrintf("refusegroup = %s\n", refusegroup->name);
  547. refusegroup = refusegroup->next;
  548. }
  549. pthread_mutex_unlock(&mutexrefusegrouplist);
  550. pthread_mutex_lock(&mutexrefusehostlist);
  551. refusehost = refusehostlist;
  552. while (refusehost) {
  553. mexPrintf("refusehost = %s\n", refusehost->name);
  554. refusehost = refusehost->next;
  555. }
  556. pthread_mutex_unlock(&mutexrefusehostlist);
  557. i = 0;
  558. pthread_mutex_lock(&mutexpeerlist);
  559. peer = peerlist;
  560. while(peer) {
  561. mexPrintf("peerlist[%d] = \n", i);
  562. mexPrintf(" host.id = %u\n", peer->host->id);
  563. mexPrintf(" host.name = %s\n", peer->host->name);
  564. mexPrintf(" host.port = %u\n", peer->host->port);
  565. mexPrintf(" host.user = %s\n", peer->host->user);
  566. mexPrintf(" host.group = %s\n", peer->host->group);
  567. mexPrintf(" host.status = %u\n", peer->host->status);
  568. mexPrintf(" host.timavail = %llu\n", peer->host->timavail);
  569. mexPrintf(" host.memavail = %llu\n", peer->host->memavail);
  570. mexPrintf(" host.cpuavail = %llu\n", peer->host->cpuavail);
  571. mexPrintf(" ipaddr = %s\n", peer->ipaddr);
  572. mexPrintf(" time = %s", ctime(&(peer->time)));
  573. peer = peer->next ;
  574. i++;
  575. }
  576. pthread_mutex_unlock(&mutexpeerlist);
  577. i = 0;
  578. pthread_mutex_lock(&mutexjoblist);
  579. job = joblist;
  580. while(job) {
  581. mexPrintf("joblist[%d] = \n", i);
  582. mexPrintf(" job.version = %u\n", job->job->version);
  583. mexPrintf(" job.id = %u\n", job->job->id);
  584. mexPrintf(" job.memreq = %llu\n", job->job->memreq);
  585. mexPrintf(" job.cpureq = %llu\n", job->job->cpureq);
  586. mexPrintf(" job.timreq = %llu\n", job->job->timreq);
  587. mexPrintf(" job.argsize = %u\n", job->job->argsize);
  588. mexPrintf(" job.optsize = %u\n", job->job->optsize);
  589. mexPrintf(" job.host.id = %u\n", job->host->id);
  590. job = job->next ;
  591. i++;
  592. }
  593. pthread_mutex_unlock(&mutexjoblist);
  594. return;
  595. }
  596. /****************************************************************************/
  597. else if (strcmp(command, "smartmem")==0) {
  598. /* the input arguments should be "smartmem <0|1> */
  599. if (nrhs<2) {
  600. mexErrMsgTxt ("invalid number of input arguments");
  601. }
  602. else {
  603. if (!mxIsNumeric(prhs[1]))
  604. mexErrMsgTxt ("invalid input argument #2");
  605. if (!mxIsScalar(prhs[1]))
  606. mexErrMsgTxt ("invalid input argument #2");
  607. pthread_mutex_lock(&mutexsmartmem);
  608. smartmem.enabled = mxGetScalar(prhs[1]);
  609. pthread_mutex_unlock(&mutexsmartmem);
  610. }
  611. }
  612. /****************************************************************************/
  613. else if (strcmp(command, "smartcpu")==0) {
  614. /* the input arguments should be "smartcpu <0|1> */
  615. if (nrhs<2) {
  616. mexErrMsgTxt ("invalid number of input arguments");
  617. }
  618. else {
  619. if (!mxIsNumeric(prhs[1]))
  620. mexErrMsgTxt ("invalid input argument #2");
  621. if (!mxIsScalar(prhs[1]))
  622. mexErrMsgTxt ("invalid input argument #2");
  623. pthread_mutex_lock(&mutexsmartcpu);
  624. smartcpu.enabled = mxGetScalar(prhs[1]);
  625. pthread_mutex_unlock(&mutexsmartcpu);
  626. }
  627. }
  628. /****************************************************************************/
  629. else if (strcmp(command, "smartshare")==0) {
  630. /* the input arguments should be "smartshare <0|1> */
  631. if (nrhs<2) {
  632. mexErrMsgTxt ("invalid number of input arguments");
  633. }
  634. else {
  635. if (!mxIsNumeric(prhs[1]))
  636. mexErrMsgTxt ("invalid input argument #2");
  637. if (!mxIsScalar(prhs[1]))
  638. mexErrMsgTxt ("invalid input argument #2");
  639. pthread_mutex_lock(&mutexsmartshare);
  640. smartshare.enabled = mxGetScalar(prhs[1]);
  641. pthread_mutex_unlock(&mutexsmartshare);
  642. }
  643. }
  644. /****************************************************************************/
  645. else if (strcmp(command, "memavail")==0) {
  646. /* the input arguments should be "memavail <number>" */
  647. if (nrhs<2) {
  648. mexErrMsgTxt ("invalid number of input arguments");
  649. }
  650. else {
  651. if (!mxIsNumeric(prhs[1]))
  652. mexErrMsgTxt ("invalid input argument #2");
  653. if (!mxIsScalar(prhs[1]))
  654. mexErrMsgTxt ("invalid input argument #2");
  655. pthread_mutex_lock(&mutexhost);
  656. host->memavail = (UINT64_T)(mxGetScalar(prhs[1])+0.5);
  657. pthread_mutex_unlock(&mutexhost);
  658. }
  659. }
  660. /****************************************************************************/
  661. else if (strcmp(command, "cpuavail")==0) {
  662. /* the input arguments should be "cpuavail <number>" */
  663. if (nrhs<2) {
  664. mexErrMsgTxt ("invalid number of input arguments");
  665. }
  666. else {
  667. if (!mxIsNumeric(prhs[1]))
  668. mexErrMsgTxt ("invalid input argument #2");
  669. if (!mxIsScalar(prhs[1]))
  670. mexErrMsgTxt ("invalid input argument #2");
  671. pthread_mutex_lock(&mutexhost);
  672. host->cpuavail = (UINT64_T)(mxGetScalar(prhs[1])+0.5);
  673. pthread_mutex_unlock(&mutexhost);
  674. }
  675. }
  676. /****************************************************************************/
  677. else if (strcmp(command, "timavail")==0) {
  678. /* the input arguments should be "timavail <number>" */
  679. if (nrhs<2) {
  680. mexErrMsgTxt ("invalid number of input arguments");
  681. }
  682. else {
  683. if (!mxIsNumeric(prhs[1]))
  684. mexErrMsgTxt ("invalid input argument #2");
  685. if (!mxIsScalar(prhs[1]))
  686. mexErrMsgTxt ("invalid input argument #2");
  687. pthread_mutex_lock(&mutexhost);
  688. host->timavail = (UINT64_T)(mxGetScalar(prhs[1])+0.5);
  689. pthread_mutex_unlock(&mutexhost);
  690. }
  691. }
  692. /****************************************************************************/
  693. else if (strcmp(command, "tcpport")==0) {
  694. /* the input arguments should be "tcpport <number>" */
  695. if (nrhs<2)
  696. mexErrMsgTxt ("invalid number of input arguments");
  697. if (!mxIsNumeric(prhs[1]))
  698. mexErrMsgTxt ("invalid input argument #2");
  699. if (!mxIsScalar(prhs[1]))
  700. mexErrMsgTxt ("invalid input argument #2");
  701. if (tcpserverStatus)
  702. mexErrMsgTxt ("cannot change the port while the tcpserver is running");
  703. pthread_mutex_lock(&mutexhost);
  704. host->port = (UINT32_T)mxGetScalar(prhs[1]);
  705. pthread_mutex_unlock(&mutexhost);
  706. }
  707. /****************************************************************************/
  708. else if (strcmp(command, "group")==0) {
  709. /* the input arguments should be "group <string>" */
  710. if (nrhs<2)
  711. mexErrMsgTxt ("invalid number of input arguments");
  712. pthread_mutex_lock(&mutexhost);
  713. if (mxIsEmpty(prhs[1])) {
  714. /* set the default group name */
  715. strncpy(host->group, DEFAULT_GROUP, STRLEN);
  716. }
  717. else {
  718. if (!mxIsChar(prhs[1]))
  719. /* FIXME this causes a deadlock */
  720. mexErrMsgTxt ("invalid input argument #2");
  721. if (mxGetString(prhs[1], host->group, STRLEN))
  722. /* FIXME this causes a deadlock */
  723. mexErrMsgTxt("FIXME: unexpected error");
  724. }
  725. pthread_mutex_unlock(&mutexhost);
  726. }
  727. /****************************************************************************/
  728. else if (strcmp(command, "hostname")==0) {
  729. /* the input arguments should be "group <string>" */
  730. if (nrhs<2)
  731. mexErrMsgTxt ("invalid number of input arguments");
  732. pthread_mutex_lock(&mutexhost);
  733. if (mxIsEmpty(prhs[1])) {
  734. /* set the default, i.e. the hostname of this computer */
  735. if (gethostname(host->name, STRLEN)) {
  736. pthread_mutex_unlock(&mutexhost);
  737. mexErrMsgTxt("could not get hostname");
  738. }
  739. }
  740. else {
  741. /* use the hostname specified by the user, e.g. localhost */
  742. if (!mxIsChar(prhs[1])) {
  743. pthread_mutex_unlock(&mutexhost);
  744. mexErrMsgTxt ("invalid input argument #2 for hostname");
  745. }
  746. if (mxGetString(prhs[1], host->name, STRLEN)) {
  747. pthread_mutex_unlock(&mutexhost);
  748. mexErrMsgTxt("could not copy string for hostname");
  749. }
  750. }
  751. /* the hostname was correctly updated */
  752. pthread_mutex_unlock(&mutexhost);
  753. }
  754. /****************************************************************************/
  755. else if (strcmp(command, "allowuser")==0) {
  756. /* the input arguments should be "allowuser {<string>, <string>, ...}" */
  757. if (nrhs<2)
  758. mexErrMsgTxt ("invalid number of input arguments");
  759. if (!mxIsCell(prhs[1]))
  760. mexErrMsgTxt ("invalid input argument #2");
  761. /* check that all elements of the cell array are strings */
  762. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  763. arg = mxGetCell(prhs[1], i);
  764. if (!mxIsChar(arg))
  765. mexErrMsgTxt ("invalid input argument #2, the cell-array should contain strings");
  766. }
  767. /* erase the existing list */
  768. clear_allowuserlist();
  769. /* add all elements to the list */
  770. pthread_mutex_lock(&mutexallowuserlist);
  771. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  772. arg = mxGetCell(prhs[1], i);
  773. allowuser = (userlist_t *)malloc(sizeof(userlist_t));
  774. allowuser->name = malloc(mxGetNumberOfElements(arg)+1);
  775. allowuser->next = allowuserlist;
  776. if(mxGetString(arg, allowuser->name, mxGetNumberOfElements(arg)+1)!=0)
  777. mexErrMsgTxt("FIXME: unexpected error, memory leak");
  778. allowuserlist = allowuser;
  779. }
  780. pthread_mutex_unlock(&mutexallowuserlist);
  781. /* erase the list of known peers, the updated filtering will be done upon discovery */
  782. clear_peerlist();
  783. }
  784. /****************************************************************************/
  785. else if (strcmp(command, "allowgroup")==0) {
  786. /* the input arguments should be "allowgroup {<string>, <string>, ...}" */
  787. if (nrhs<2)
  788. mexErrMsgTxt ("invalid number of input arguments");
  789. if (!mxIsCell(prhs[1]))
  790. mexErrMsgTxt ("invalid input argument #2");
  791. /* check that all elements of the cell array are strings */
  792. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  793. arg = mxGetCell(prhs[1], i);
  794. if (!mxIsChar(arg))
  795. mexErrMsgTxt ("invalid input argument #2, the cell-array should contain strings");
  796. }
  797. /* erase the existing list */
  798. clear_allowgrouplist();
  799. /* add all elements to the list */
  800. pthread_mutex_lock(&mutexallowgrouplist);
  801. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  802. arg = mxGetCell(prhs[1], i);
  803. allowgroup = (grouplist_t *)malloc(sizeof(grouplist_t));
  804. allowgroup->name = malloc(mxGetNumberOfElements(arg)+1);
  805. allowgroup->next = allowgrouplist;
  806. if(mxGetString(arg, allowgroup->name, mxGetNumberOfElements(arg)+1)!=0)
  807. mexErrMsgTxt("FIXME: unexpected error, memory leak");
  808. allowgrouplist = allowgroup;
  809. }
  810. pthread_mutex_unlock(&mutexallowgrouplist);
  811. /* flush the list of known peers, the updated filtering will be done upon discovery */
  812. clear_peerlist();
  813. }
  814. /****************************************************************************/
  815. else if (strcmp(command, "allowhost")==0) {
  816. /* the input arguments should be "allowhost {<string>, <string>, ...}" */
  817. if (nrhs<2)
  818. mexErrMsgTxt ("invalid number of input arguments");
  819. if (!mxIsCell(prhs[1]))
  820. mexErrMsgTxt ("invalid input argument #2");
  821. /* check that all elements of the cell array are strings */
  822. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  823. arg = mxGetCell(prhs[1], i);
  824. if (!mxIsChar(arg))
  825. mexErrMsgTxt ("invalid input argument #2, the cell-array should contain strings");
  826. }
  827. /* erase the existing list */
  828. clear_allowhostlist();
  829. /* add all elements to the list */
  830. pthread_mutex_lock(&mutexallowhostlist);
  831. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  832. arg = mxGetCell(prhs[1], i);
  833. allowhost = (hostlist_t *)malloc(sizeof(hostlist_t));
  834. allowhost->name = malloc(mxGetNumberOfElements(arg)+1);
  835. allowhost->next = allowhostlist;
  836. if(mxGetString(arg, allowhost->name, mxGetNumberOfElements(arg)+1)!=0)
  837. mexErrMsgTxt("FIXME: unexpected error, memory leak");
  838. allowhostlist = allowhost;
  839. }
  840. pthread_mutex_unlock(&mutexallowhostlist);
  841. /* flush the list of known peers, the updated filtering will be done upon discovery */
  842. clear_peerlist();
  843. }
  844. /****************************************************************************/
  845. else if (strcmp(command, "refuseuser")==0) {
  846. /* the input arguments should be "refuseuser {<string>, <string>, ...}" */
  847. if (nrhs<2)
  848. mexErrMsgTxt ("invalid number of input arguments");
  849. if (!mxIsCell(prhs[1]))
  850. mexErrMsgTxt ("invalid input argument #2");
  851. /* check that all elements of the cell array are strings */
  852. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  853. arg = mxGetCell(prhs[1], i);
  854. if (!mxIsChar(arg))
  855. mexErrMsgTxt ("invalid input argument #2, the cell-array should contain strings");
  856. }
  857. /* erase the existing list */
  858. clear_refuseuserlist();
  859. /* add all elements to the list */
  860. pthread_mutex_lock(&mutexrefuseuserlist);
  861. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  862. arg = mxGetCell(prhs[1], i);
  863. refuseuser = (userlist_t *)malloc(sizeof(userlist_t));
  864. refuseuser->name = malloc(mxGetNumberOfElements(arg)+1);
  865. refuseuser->next = refuseuserlist;
  866. if(mxGetString(arg, refuseuser->name, mxGetNumberOfElements(arg)+1)!=0)
  867. mexErrMsgTxt("FIXME: unexpected error, memory leak");
  868. refuseuserlist = refuseuser;
  869. }
  870. pthread_mutex_unlock(&mutexrefuseuserlist);
  871. /* erase the list of known peers, the updated filtering will be done upon discovery */
  872. clear_peerlist();
  873. }
  874. /****************************************************************************/
  875. else if (strcmp(command, "refusegroup")==0) {
  876. /* the input arguments should be "refusegroup {<string>, <string>, ...}" */
  877. if (nrhs<2)
  878. mexErrMsgTxt ("invalid number of input arguments");
  879. if (!mxIsCell(prhs[1]))
  880. mexErrMsgTxt ("invalid input argument #2");
  881. /* check that all elements of the cell array are strings */
  882. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  883. arg = mxGetCell(prhs[1], i);
  884. if (!mxIsChar(arg))
  885. mexErrMsgTxt ("invalid input argument #2, the cell-array should contain strings");
  886. }
  887. /* erase the existing list */
  888. clear_refusegrouplist();
  889. /* add all elements to the list */
  890. pthread_mutex_lock(&mutexrefusegrouplist);
  891. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  892. arg = mxGetCell(prhs[1], i);
  893. refusegroup = (grouplist_t *)malloc(sizeof(grouplist_t));
  894. refusegroup->name = malloc(mxGetNumberOfElements(arg)+1);
  895. refusegroup->next = refusegrouplist;
  896. if(mxGetString(arg, refusegroup->name, mxGetNumberOfElements(arg)+1)!=0)
  897. mexErrMsgTxt("FIXME: unexpected error, memory leak");
  898. refusegrouplist = refusegroup;
  899. }
  900. pthread_mutex_unlock(&mutexrefusegrouplist);
  901. /* flush the list of known peers, the updated filtering will be done upon discovery */
  902. clear_peerlist();
  903. }
  904. /****************************************************************************/
  905. else if (strcmp(command, "refusehost")==0) {
  906. /* the input arguments should be "refusehost {<string>, <string>, ...}" */
  907. if (nrhs<2)
  908. mexErrMsgTxt ("invalid number of input arguments");
  909. if (!mxIsCell(prhs[1]))
  910. mexErrMsgTxt ("invalid input argument #2");
  911. /* check that all elements of the cell array are strings */
  912. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  913. arg = mxGetCell(prhs[1], i);
  914. if (!mxIsChar(arg))
  915. mexErrMsgTxt ("invalid input argument #2, the cell-array should contain strings");
  916. }
  917. /* erase the existing list */
  918. clear_refusehostlist();
  919. /* add all elements to the list */
  920. pthread_mutex_lock(&mutexrefusehostlist);
  921. for (i=0; i<mxGetNumberOfElements(prhs[1]); i++) {
  922. arg = mxGetCell(prhs[1], i);
  923. refusehost = (hostlist_t *)malloc(sizeof(hostlist_t));
  924. refusehost->name = malloc(mxGetNumberOfElements(arg)+1);
  925. refusehost->next = refusehostlist;
  926. if(mxGetString(arg, refusehost->name, mxGetNumberOfElements(arg)+1)!=0)
  927. mexErrMsgTxt("FIXME: unexpected error, memory leak");
  928. refusehostlist = refusehost;
  929. }
  930. pthread_mutex_unlock(&mutexrefusehostlist);
  931. /* flush the list of known peers, the updated filtering will be done upon discovery */
  932. clear_peerlist();
  933. }
  934. /****************************************************************************/
  935. else if (strcmp(command, "put")==0) {
  936. int hasuds, hastcp;
  937. /* the input arguments should be "put <peerid> <arg> <opt> ... " */
  938. /* where additional options should be specified as key-value pairs */
  939. if (nrhs<2)
  940. mexErrMsgTxt("invalid argument #2");
  941. if (!mxIsNumeric(prhs[1]))
  942. mexErrMsgTxt ("invalid input argument #2");
  943. peerid = (UINT32_T)mxGetScalar(prhs[1]);
  944. if (nrhs<3)
  945. mexErrMsgTxt("invalid argument #3");
  946. if (nrhs<4)
  947. mexErrMsgTxt("invalid argument #4");
  948. jobid = rand(); /* assign a random jobid by default */
  949. memreq = 0; /* default assumption */
  950. cpureq = 0; /* default assumption */
  951. timreq = 0; /* default assumption */
  952. i = 4;
  953. while ((i+1)<nrhs) {
  954. key = (mxArray *)prhs[i++];
  955. val = (mxArray *)prhs[i++];
  956. if (!mxIsChar(key))
  957. mexErrMsgTxt ("optional arguments should come in key-value pairs");
  958. if (mxGetString(key, argument, STRLEN-1))
  959. mexErrMsgTxt ("optional arguments should come in key-value pairs");
  960. /* use the optional parameter value, beware of the typecasting to 32 and 64 bit integers */
  961. if (strcmp(argument, "jobid")==0)
  962. jobid = (UINT32_T)mxGetScalar(val);
  963. else if (strcmp(argument, "memreq")==0)
  964. memreq = (UINT64_T)(mxGetScalar(val)+0.5);
  965. else if (strcmp(argument, "cpureq")==0)
  966. cpureq = (UINT64_T)(mxGetScalar(val)+0.5);
  967. else if (strcmp(argument, "timreq")==0)
  968. timreq = (UINT64_T)(mxGetScalar(val)+0.5);
  969. }
  970. found = 0;
  971. pthread_mutex_lock(&mutexpeerlist);
  972. peer = peerlist;
  973. while(peer) {
  974. if (peer->host->id==peerid) {
  975. found = 1;
  976. break;
  977. }
  978. peer = peer->next ;
  979. }
  980. if (!found) {
  981. pthread_mutex_unlock(&mutexpeerlist);
  982. mexErrMsgTxt("failed to locate specified peer\n");
  983. }
  984. arg = (mxArray *) mxSerialize(prhs[2]);
  985. if (!arg) {
  986. mexErrMsgTxt("could not serialize job arguments");
  987. }
  988. opt = (mxArray *) mxSerialize(prhs[3]);
  989. if (!opt) {
  990. mxDestroyArray(arg);
  991. arg = NULL;
  992. mexErrMsgTxt("could not serialize job options");
  993. }
  994. def = (jobdef_t *)malloc(sizeof(jobdef_t));
  995. if (!def) {
  996. mxDestroyArray(arg);
  997. arg = NULL;
  998. mxDestroyArray(opt);
  999. opt = NULL;
  1000. mexErrMsgTxt("could not allocate memory");
  1001. }
  1002. pthread_mutex_lock(&mutexhost);
  1003. hasuds = (strlen(peer->host->socket)>0 && strcmp(peer->host->name, host->name)==0);
  1004. hastcp = (peer->host->port>0);
  1005. pthread_mutex_unlock(&mutexhost);
  1006. if (hasuds) {
  1007. /* open the UDS socket */
  1008. if ((server = open_uds_connection(peer->host->socket)) < 0) {
  1009. pthread_mutex_unlock(&mutexpeerlist);
  1010. mexErrMsgTxt("failed to create socket\n");
  1011. }
  1012. }
  1013. else if (hastcp) {
  1014. /* open the TCP socket */
  1015. if ((server = open_tcp_connection(peer->ipaddr, peer->host->port)) < 0) {
  1016. pthread_mutex_unlock(&mutexpeerlist);
  1017. mexErrMsgTxt("failed to create socket\n");
  1018. }
  1019. }
  1020. else {
  1021. pthread_mutex_unlock(&mutexpeerlist);
  1022. mexErrMsgTxt("failed to create socket\n");
  1023. }
  1024. /* the connection was opened without error */
  1025. pthread_mutex_unlock(&mutexpeerlist);
  1026. if ((n = bufread(server, &handshake, sizeof(int))) != sizeof(int)) {
  1027. close_connection(server);
  1028. mexErrMsgTxt("tcpsocket: could not write handshake");
  1029. }
  1030. if (!handshake) {
  1031. close_connection(server);
  1032. mexErrMsgTxt("failed to negociate connection");
  1033. }
  1034. /* the message that will be written consists of
  1035. message->host
  1036. message->job
  1037. message->arg
  1038. message->opt
  1039. */
  1040. def->version = VERSION;
  1041. def->id = jobid;
  1042. def->memreq = memreq;
  1043. def->cpureq = cpureq;
  1044. def->timreq = timreq;
  1045. def->argsize = mxGetNumberOfElements(arg);
  1046. def->optsize = mxGetNumberOfElements(opt);
  1047. /* write the message (hostdef, jobdef, arg, opt) with handshakes in between */
  1048. /* the slave may close the connection between the message segments in case the job is refused */
  1049. success = 1;
  1050. pthread_mutex_lock(&mutexhost);
  1051. if (success)
  1052. success = (bufwrite(server, host, sizeof(hostdef_t)) == sizeof(hostdef_t));
  1053. pthread_mutex_unlock(&mutexhost);
  1054. if ((n = bufread(server, &handshake, sizeof(int))) != sizeof(int)) {
  1055. close_connection(server);
  1056. mexErrMsgTxt("could not write handshake");
  1057. }
  1058. if (!handshake) {
  1059. close_connection(server);
  1060. mexErrMsgTxt("failed to write hostdef");
  1061. }
  1062. if (success)
  1063. success = (bufwrite(server, def, sizeof(jobdef_t)) == sizeof(jobdef_t));
  1064. if ((n = bufread(server, &handshake, sizeof(int))) != sizeof(int)) {
  1065. close_connection(server);
  1066. mexErrMsgTxt("could not write handshake");
  1067. }
  1068. if (!handshake) {
  1069. close_connection(server);
  1070. mexErrMsgTxt("failed to write jobdef");
  1071. }
  1072. if (success)
  1073. success = (bufwrite(server, (void *)mxGetData(arg), def->argsize) == def->argsize);
  1074. if ((n = bufread(server, &handshake, sizeof(int))) != sizeof(int)) {
  1075. close_connection(server);
  1076. mexErrMsgTxt("could not write handshake");
  1077. }
  1078. if (!handshake) {
  1079. close_connection(server);
  1080. mexErrMsgTxt("failed to write arg");
  1081. }
  1082. if (success)
  1083. success = (bufwrite(server, (void *)mxGetData(opt), def->optsize) == def->optsize);
  1084. if ((n = bufread(server, &handshake, sizeof(int))) != sizeof(int)) {
  1085. close_connection(server);
  1086. mexErrMsgTxt("could not write handshake");
  1087. }
  1088. if (!handshake) {
  1089. close_connection(server);
  1090. mexErrMsgTxt("failed to write opt");
  1091. }
  1092. close_connection(server);
  1093. mxDestroyArray(arg);
  1094. arg = NULL;
  1095. mxDestroyArray(opt);
  1096. opt = NULL;
  1097. if (success) {
  1098. /* return the job details */
  1099. plhs[0] = mxCreateStructMatrix(1, 1, JOB_FIELDNUMBER, job_fieldnames);
  1100. mxSetFieldByNumber(plhs[0], 0, 0, mxCreateDoubleScalar((UINT32_T)(def->version)));
  1101. mxSetFieldByNumber(plhs[0], 0, 1, mxCreateDoubleScalar((UINT32_T)(def->id)));
  1102. mxSetFieldByNumber(plhs[0], 0, 2, mxCreateDoubleScalar((UINT32_T)(def->argsize)));
  1103. mxSetFieldByNumber(plhs[0], 0, 3, mxCreateDoubleScalar((UINT32_T)(def->optsize)));
  1104. FREE(def);
  1105. }
  1106. else {
  1107. FREE(def);
  1108. mexErrMsgTxt ("failed to put job arguments");
  1109. }
  1110. return;
  1111. }
  1112. /****************************************************************************/
  1113. else if (strcmp(command, "get")==0) {
  1114. /* the input arguments should be "get <jobid>" */
  1115. if (nrhs<2)
  1116. mexErrMsgTxt ("invalid number of input arguments");
  1117. if (!mxIsNumeric(prhs[1]))
  1118. mexErrMsgTxt ("invalid input argument #2");
  1119. if (!mxIsScalar(prhs[1]))
  1120. mexErrMsgTxt ("invalid input argument #2");
  1121. jobid = (UINT32_T)mxGetScalar(prhs[1]);
  1122. found = 0;
  1123. pthread_mutex_lock(&mutexjoblist);
  1124. job = joblist;
  1125. while(job) {
  1126. found = (job->job->id==jobid);
  1127. if (found) {
  1128. plhs[0] = (mxArray *)mxDeserialize(job->arg, job->job->argsize);
  1129. plhs[1] = (mxArray *)mxDeserialize(job->opt, job->job->optsize);
  1130. break;
  1131. }
  1132. job = job->next ;
  1133. }
  1134. if (!found) {
  1135. pthread_mutex_unlock(&mutexjoblist);
  1136. mexErrMsgTxt("failed to locate specified job\n");
  1137. }
  1138. pthread_mutex_unlock(&mutexjoblist);
  1139. return;
  1140. }
  1141. /****************************************************************************/
  1142. else if (strcmp(command, "clear")==0) {
  1143. /* the input arguments should be "clear <jobid>" */
  1144. if (nrhs<2)
  1145. mexErrMsgTxt ("invalid number of input arguments");
  1146. if (!mxIsNumeric(prhs[1]))
  1147. mexErrMsgTxt ("invalid input argument #2");
  1148. if (!mxIsScalar(prhs[1]))
  1149. mexErrMsgTxt ("invalid input argument #2");
  1150. jobid = (UINT32_T)mxGetScalar(prhs[1]);
  1151. found = 0;
  1152. pthread_mutex_lock(&mutexjoblist);
  1153. /* test the first item on the list */
  1154. if (joblist)
  1155. {
  1156. if (joblist->job->id==jobid) {
  1157. found = 1;
  1158. /* delete the first item in the list */
  1159. nextjob = joblist->next;
  1160. FREE(joblist->job);
  1161. FREE(joblist->host);
  1162. FREE(joblist->arg);
  1163. FREE(joblist->opt);
  1164. FREE(joblist);
  1165. joblist = nextjob;
  1166. }
  1167. }
  1168. /* traverse the list */
  1169. job = joblist;
  1170. while(job) {
  1171. /* test the next item on the list, remember the current one */
  1172. nextjob = job->next;
  1173. if (nextjob) {
  1174. if (nextjob->job->id==jobid) {
  1175. found = 1;
  1176. /* skip the next item in the list */
  1177. job->next = nextjob->next;
  1178. /* delete the next item in the list */
  1179. FREE(nextjob->job);
  1180. FREE(nextjob->host);
  1181. FREE(nextjob->arg);
  1182. FREE(nextjob->opt);
  1183. FREE(nextjob);
  1184. break;
  1185. }
  1186. }
  1187. job = job->next;
  1188. }
  1189. pthread_mutex_unlock(&mutexjoblist);
  1190. if (!found) {
  1191. mexWarnMsgTxt("failed to locate specified job\n");
  1192. }
  1193. return;
  1194. }
  1195. /****************************************************************************/
  1196. else if (strcmp(command, "peerinfo")==0) {
  1197. pthread_mutex_lock(&mutexhost);
  1198. plhs[0] = mxCreateStructMatrix(1, 1, PEERINFO_FIELDNUMBER, peerinfo_fieldnames);
  1199. j = 0;
  1200. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateDoubleScalar((UINT32_T)(host->id)));
  1201. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateString(host->name));
  1202. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateString(host->user));
  1203. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateString(host->group));
  1204. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateString(host->socket));
  1205. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateDoubleScalar((UINT32_T)(host->port)));
  1206. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateDoubleScalar((UINT32_T)(host->status)));
  1207. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateDoubleScalar((UINT64_T)(host->timavail)));
  1208. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateDoubleScalar((UINT64_T)(host->memavail)));
  1209. mxSetFieldByNumber(plhs[0], 0, j++, mxCreateDoubleScalar((UINT64_T)(host->cpuavail)));
  1210. pthread_mutex_unlock(&mutexhost);
  1211. /* create a cell-array for allowuser */
  1212. i = 0;
  1213. pthread_mutex_lock(&mutexallowuserlist);
  1214. allowuser = allowuserlist;
  1215. while (allowuser) {
  1216. /* count the number of items */
  1217. i++;
  1218. allowuser = allowuser->next;
  1219. }
  1220. if (i==0)
  1221. val= mxCreateCellMatrix(0, 0);
  1222. else
  1223. val= mxCreateCellMatrix(1, i);
  1224. /* loop over the list to assign the items to a cell-array */
  1225. allowuser = allowuserlist;
  1226. while (allowuser) {
  1227. /* start assigning at the back, to keep them in the original order */
  1228. mxSetCell(val, --i, mxCreateString(allowuser->name));
  1229. allowuser = allowuser->next;
  1230. }
  1231. mxSetFieldByNumber(plhs[0], 0, j++, val);
  1232. pthread_mutex_unlock(&mutexallowuserlist);
  1233. /* create a cell-array for allowgroup */
  1234. i = 0;
  1235. pthread_mutex_lock(&mutexallowgrouplist);
  1236. allowgroup = allowgrouplist;
  1237. while (allowgroup) {
  1238. /* count the number of items */
  1239. i++;
  1240. allowgroup = allowgroup->next;
  1241. }
  1242. if (i==0)
  1243. val= mxCreateCellMatrix(0, 0);
  1244. else
  1245. val= mxCreateCellMatrix(1, i);
  1246. /* loop over the list to assign the items to a cell-array */
  1247. allowgroup = allowgrouplist;
  1248. while (allowgroup) {
  1249. /* start assigning at the back, to keep them in the original order */
  1250. mxSetCell(val, --i, mxCreateString(allowgroup->name));
  1251. allowgroup = allowgroup->next;
  1252. }
  1253. mxSetFieldByNumber(plhs[0], 0, j++, val);
  1254. pthread_mutex_unlock(&mutexallowgrouplist);
  1255. /* create a cell-array for allowhost */
  1256. i = 0;
  1257. pthread_mutex_lock(&mutexallowhostlist);
  1258. allowhost = allowhostlist;
  1259. while (allowhost) {
  1260. /* count the number of items */
  1261. i++;
  1262. allowhost = allowhost->next;
  1263. }
  1264. if (i==0)
  1265. val= mxCreateCellMatrix(0, 0);
  1266. else
  1267. val= mxCreateCellMatrix(1, i);
  1268. /* loop over the list to assign the items to a cell-array */
  1269. allowhost = allowhostlist;
  1270. while (allowhost) {
  1271. /* start assigning at the back, to keep them in the original order */
  1272. mxSetCell(val, --i, mxCreateString(allowhost->name));
  1273. allowhost = allowhost->next;
  1274. }
  1275. mxSetFieldByNumber(plhs[0], 0, j++, val);
  1276. pthread_mutex_unlock(&mutexallowhostlist);
  1277. /* create a cell-array for refuseuser */
  1278. i = 0;
  1279. pthread_mutex_lock(&mutexrefuseuserlist);
  1280. refuseuser = refuseuserlist;
  1281. while (refuseuser) {
  1282. /* count the number of items */
  1283. i++;
  1284. refuseuser = refuseuser->next;
  1285. }
  1286. if (i==0)
  1287. val= mxCreateCellMatrix(0, 0);
  1288. else
  1289. val= mxCreateCellMatrix(1, i);
  1290. /* loop over the list to assign the items to a cell-array */
  1291. refuseuser = refuseuserlist;
  1292. while (refuseuser) {
  1293. /* start assigning at the back, to keep them in the original order */
  1294. mxSetCell(val, --i, mxCreateString(refuseuser->name));
  1295. refuseuser = refuseuser->next;
  1296. }
  1297. mxSetFieldByNumber(plhs[0], 0, j++, val);
  1298. pthread_mutex_unlock(&mutexrefuseuserlist);
  1299. /* create a cell-array for refusegroup */
  1300. i = 0;
  1301. pthread_mutex_lock(&mutexrefusegrouplist);
  1302. refusegroup = refusegrouplist;
  1303. while (refusegroup) {
  1304. /* count the number of items */
  1305. i++;
  1306. refusegroup = refusegroup->next;
  1307. }
  1308. if (i==0)
  1309. val= mxCreateCellMatrix(0, 0);
  1310. else
  1311. val= mxCreateCellMatrix(1, i);
  1312. /* loop over the list to assign the items to a cell-array */
  1313. refusegroup = refusegrouplist;
  1314. while (refusegroup) {
  1315. /* start assigning at the back, to keep them in the original order */
  1316. mxSetCell(val, --i, mxCreateString(refusegroup->name));
  1317. refusegroup = refusegroup->next;
  1318. }
  1319. mxSetFieldByNumber(plhs[0], 0, j++, val);
  1320. pthread_mutex_unlock(&mutexrefusegrouplist);
  1321. /* create a cell-array for refusehost */
  1322. i = 0;
  1323. pthread_mutex_lock(&mutexrefusehostlist);
  1324. refusehost = refusehostlist;
  1325. while (refusehost) {
  1326. /* count the number of items */
  1327. i++;
  1328. refusehost = refusehost->next;
  1329. }
  1330. if (i==0)
  1331. val= mxCreateCellMatrix(0, 0);
  1332. else
  1333. val= mxCreateCellMatrix(1, i);
  1334. /* loop over the list to assign the items to a cell-array */
  1335. refusehost = refusehostlist;
  1336. while (refusehost) {
  1337. /* start assigning at the back, to keep them in the original order */
  1338. mxSetCell(val, --i, mxCreateString(refusehost->name));
  1339. refusehost = refusehost->next;
  1340. }
  1341. mxSetFieldByNumber(plhs[0], 0, j++, val);
  1342. pthread_mutex_unlock(&mutexrefusehostlist);
  1343. return;
  1344. }
  1345. /****************************************************************************/
  1346. else {
  1347. mexErrMsgTxt ("unknown command for peer");
  1348. return;
  1349. }
  1350. return;
  1351. }