sgx_graphene.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* Copyright (C) 2014 Stony Brook University
  2. This file is part of Graphene Library OS.
  3. Graphene Library OS is free software: you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public License
  5. as published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. Graphene Library OS is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #include <pal.h>
  14. #include <pal_error.h>
  15. #include <atomic.h>
  16. #include <linux/futex.h>
  17. #include <errno.h>
  18. #include "sgx_internal.h"
  19. #if 0 /* this code is useless for now */
  20. int _DkEventSet (PAL_HANDLE event, int wakeup)
  21. {
  22. int ret = 0;
  23. if (event->event.isnotification) {
  24. // Leave it signaled, wake all
  25. if (atomic_cmpxchg(&event->event.signaled, 0, 1) == 0) {
  26. int nwaiters = atomic_read(&event->event.nwaiters);
  27. if (nwaiters) {
  28. if (wakeup != -1 && nwaiters > wakeup)
  29. nwaiters = wakeup;
  30. ret = INLINE_SYSCALL(futex, 6, &event->event.signaled,
  31. FUTEX_WAKE, nwaiters, NULL, NULL, 0);
  32. if (IS_ERR(ret))
  33. atomic_set(&event->event.signaled, 0);
  34. }
  35. }
  36. } else {
  37. // Only one thread wakes up, leave unsignaled
  38. ret = INLINE_SYSCALL(futex, 6, &event->event.signaled, FUTEX_WAKE, 1,
  39. NULL, NULL, 0);
  40. }
  41. return IS_ERR(ret) ? -PAL_ERROR_TRYAGAIN : ret;
  42. }
  43. int _DkEventWait (PAL_HANDLE event)
  44. {
  45. int ret = 0;
  46. if (!event->event.isnotification || !atomic_read(&event->event.signaled)) {
  47. atomic_inc(&event->event.nwaiters);
  48. do {
  49. ret = INLINE_SYSCALL(futex, 6, &event->event.signaled, FUTEX_WAIT,
  50. 0, NULL, NULL, 0);
  51. if (IS_ERR(ret)) {
  52. if (ERRNO(ret) == EWOULDBLOCK) {
  53. ret = 0;
  54. } else {
  55. ret = -PAL_ERROR_DENIED;
  56. break;
  57. }
  58. }
  59. } while (event->event.isnotification &&
  60. !atomic_read(&event->event.signaled));
  61. atomic_dec(&event->event.nwaiters);
  62. }
  63. return ret;
  64. }
  65. #endif
  66. #define PRINTBUF_SIZE 256
  67. struct printbuf {
  68. int idx; // current buffer index
  69. int cnt; // total bytes printed so far
  70. char buf[PRINTBUF_SIZE];
  71. };
  72. static int
  73. fputch(void * f, int ch, struct printbuf * b)
  74. {
  75. __UNUSED(f);
  76. b->buf[b->idx++] = ch;
  77. if (b->idx == PRINTBUF_SIZE - 1) {
  78. INLINE_SYSCALL(write, 3, 2, b->buf, b->idx);
  79. b->idx = 0;
  80. }
  81. b->cnt++;
  82. return 0;
  83. }
  84. static int
  85. vprintf(const char * fmt, va_list ap)
  86. {
  87. struct printbuf b;
  88. b.idx = 0;
  89. b.cnt = 0;
  90. vfprintfmt((void *) &fputch, NULL, &b, fmt, ap);
  91. INLINE_SYSCALL(write, 3, 2, b.buf, b.idx);
  92. return b.cnt;
  93. }
  94. int
  95. pal_printf(const char * fmt, ...)
  96. {
  97. va_list ap;
  98. int cnt;
  99. va_start(ap, fmt);
  100. cnt = vprintf(fmt, ap);
  101. va_end(ap);
  102. return cnt;
  103. }