mbed_poll.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /* mbed Microcontroller Library
  2. * Copyright (c) 2017 ARM Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "mbed_poll.h"
  17. #include "FileHandle.h"
  18. #if MBED_CONF_RTOS_PRESENT
  19. #include "rtos/Kernel.h"
  20. #include "rtos/Thread.h"
  21. using namespace rtos;
  22. #else
  23. #include "Timer.h"
  24. #include "LowPowerTimer.h"
  25. #endif
  26. namespace mbed {
  27. // timeout -1 forever, or milliseconds
  28. int poll(pollfh fhs[], unsigned nfhs, int timeout)
  29. {
  30. /**
  31. * TODO Proper wake-up mechanism.
  32. * In order to correctly detect availability of read/write a FileHandle, we needed
  33. * a select or poll mechanisms. We opted for poll as POSIX defines in
  34. * http://pubs.opengroup.org/onlinepubs/009695399/functions/poll.html Currently,
  35. * mbed::poll() just spins and scans filehandles looking for any events we are
  36. * interested in. In future, his spinning behaviour will be replaced with
  37. * condition variables.
  38. */
  39. #if MBED_CONF_RTOS_PRESENT
  40. uint64_t start_time = 0;
  41. if (timeout > 0) {
  42. start_time = Kernel::get_ms_count();
  43. }
  44. #define TIME_ELAPSED() int64_t(Kernel::get_ms_count() - start_time)
  45. #else
  46. #if MBED_CONF_PLATFORM_POLL_USE_LOWPOWER_TIMER
  47. LowPowerTimer timer;
  48. #else
  49. Timer timer;
  50. #endif
  51. if (timeout > 0) {
  52. timer.start();
  53. }
  54. #define TIME_ELAPSED() timer.read_ms()
  55. #endif // MBED_CONF_RTOS_PRESENT
  56. int count = 0;
  57. for (;;) {
  58. /* Scan the file handles */
  59. for (unsigned n = 0; n < nfhs; n++) {
  60. FileHandle *fh = fhs[n].fh;
  61. short mask = fhs[n].events | POLLERR | POLLHUP | POLLNVAL;
  62. if (fh) {
  63. fhs[n].revents = fh->poll(mask) & mask;
  64. } else {
  65. fhs[n].revents = POLLNVAL;
  66. }
  67. if (fhs[n].revents) {
  68. count++;
  69. }
  70. }
  71. if (count) {
  72. break;
  73. }
  74. /* Nothing selected - this is where timeout handling would be needed */
  75. if (timeout == 0 || (timeout > 0 && TIME_ELAPSED() > timeout)) {
  76. break;
  77. }
  78. #ifdef MBED_CONF_RTOS_PRESENT
  79. // TODO - proper blocking
  80. // wait for condition variable, wait queue whatever here
  81. rtos::Thread::wait(1);
  82. #endif
  83. }
  84. return count;
  85. }
  86. } // namespace mbed