py_thread.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "hooks_py.h"
  2. #include "simulator.h"
  3. #include "thread_manager.h"
  4. #include "thread.h"
  5. #include "scheduler.h"
  6. static PyObject *
  7. getNthreads(PyObject *self, PyObject *args)
  8. {
  9. return PyInt_FromLong(Sim()->getThreadManager()->getNumThreads());
  10. }
  11. static PyObject *
  12. getThreadAppid(PyObject *self, PyObject *args)
  13. {
  14. unsigned long thread_id = INVALID_THREAD_ID;
  15. if (!PyArg_ParseTuple(args, "l", &thread_id))
  16. return NULL;
  17. if (thread_id >= Sim()->getThreadManager()->getNumThreads())
  18. {
  19. PyErr_SetString(PyExc_ValueError, "Invalid thread id");
  20. return NULL;
  21. }
  22. Thread *thread = Sim()->getThreadManager()->getThreadFromID(thread_id);
  23. if (!thread)
  24. {
  25. PyErr_SetString(PyExc_ValueError, "Invalid thread id");
  26. return NULL;
  27. }
  28. return PyInt_FromLong(thread->getAppId());
  29. }
  30. static PyObject *
  31. getThreadName(PyObject *self, PyObject *args)
  32. {
  33. unsigned long thread_id = INVALID_THREAD_ID;
  34. if (!PyArg_ParseTuple(args, "l", &thread_id))
  35. return NULL;
  36. if (thread_id >= Sim()->getThreadManager()->getNumThreads())
  37. {
  38. PyErr_SetString(PyExc_ValueError, "Invalid thread id");
  39. return NULL;
  40. }
  41. Thread *thread = Sim()->getThreadManager()->getThreadFromID(thread_id);
  42. if (!thread)
  43. {
  44. PyErr_SetString(PyExc_ValueError, "Invalid thread id");
  45. return NULL;
  46. }
  47. return Py_BuildValue("s", thread->getName().c_str());
  48. }
  49. static PyObject *
  50. getThreadAffinity(PyObject *self, PyObject *args)
  51. {
  52. unsigned long thread_id = INVALID_THREAD_ID;
  53. if (!PyArg_ParseTuple(args, "l", &thread_id))
  54. return NULL;
  55. if (thread_id >= Sim()->getThreadManager()->getNumThreads())
  56. {
  57. PyErr_SetString(PyExc_ValueError, "Invalid thread id");
  58. return NULL;
  59. }
  60. cpu_set_t mask;
  61. bool success = Sim()->getThreadManager()->getScheduler()->threadGetAffinity(thread_id, sizeof(cpu_set_t), &mask);
  62. if (!success)
  63. {
  64. PyErr_SetString(PyExc_ValueError, "threadGetAffinity() failed");
  65. return NULL;
  66. }
  67. PyObject *res = PyTuple_New(Sim()->getConfig()->getApplicationCores());
  68. for(unsigned int cpu = 0; cpu < Sim()->getConfig()->getApplicationCores(); ++cpu)
  69. {
  70. PyObject *_res = CPU_ISSET(cpu, &mask) ? Py_True : Py_False;
  71. Py_INCREF(_res);
  72. PyTuple_SET_ITEM(res, cpu, _res);
  73. }
  74. return res;
  75. }
  76. static PyObject *
  77. setThreadAffinity(PyObject *self, PyObject *args)
  78. {
  79. unsigned long thread_id = INVALID_THREAD_ID;
  80. PyObject *py_mask;
  81. if (!PyArg_ParseTuple(args, "lO", &thread_id, &py_mask))
  82. return NULL;
  83. if (thread_id >= Sim()->getThreadManager()->getNumThreads())
  84. {
  85. PyErr_SetString(PyExc_ValueError, "Invalid thread id");
  86. return NULL;
  87. }
  88. if (!PySequence_Check(py_mask))
  89. {
  90. PyErr_SetString(PyExc_ValueError, "Second argument must be iteratable");
  91. return NULL;
  92. }
  93. if (PySequence_Size(py_mask) > (Py_ssize_t)Sim()->getConfig()->getApplicationCores())
  94. {
  95. PyErr_SetString(PyExc_ValueError, "Core mask is longer than number of available cores");
  96. return NULL;
  97. }
  98. cpu_set_t mask;
  99. CPU_ZERO(&mask);
  100. for(unsigned int cpu = 0; cpu < (unsigned int)PySequence_Size(py_mask) && cpu < 8*sizeof(cpu_set_t); ++cpu)
  101. {
  102. PyObject *item = PySequence_ITEM(py_mask, cpu);
  103. if (PyObject_IsTrue(item))
  104. CPU_SET(cpu, &mask);
  105. Py_DECREF(item);
  106. }
  107. bool result = Sim()->getThreadManager()->getScheduler()->threadSetAffinity(INVALID_THREAD_ID, thread_id, sizeof(cpu_set_t), &mask);
  108. if (result)
  109. Py_RETURN_TRUE;
  110. else
  111. Py_RETURN_FALSE;
  112. }
  113. static PyMethodDef PyThreadMethods[] = {
  114. { "get_nthreads", getNthreads, METH_VARARGS, "Get number of threads" },
  115. { "get_thread_appid", getThreadAppid, METH_VARARGS, "Get application ID for a thread" },
  116. { "get_thread_name", getThreadName, METH_VARARGS, "Get thread name" },
  117. { "get_thread_affinity", getThreadAffinity, METH_VARARGS, "Get thread affinity" },
  118. { "set_thread_affinity", setThreadAffinity, METH_VARARGS, "Set thread affinity" },
  119. { NULL, NULL, 0, NULL } /* Sentinel */
  120. };
  121. void HooksPy::PyThread::setup(void)
  122. {
  123. Py_InitModule("sim_thread", PyThreadMethods);
  124. }