ntsync.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Various unit tests for the "ntsync" synchronization primitive driver.
  4. *
  5. * Copyright (C) 2021-2022 Elizabeth Figura <zfigura@codeweavers.com>
  6. */
  7. #define _GNU_SOURCE
  8. #include <sys/ioctl.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include <time.h>
  12. #include <pthread.h>
  13. #include <linux/ntsync.h>
  14. #include "kselftest_harness.h"
  15. static int read_sem_state(int sem, __u32 *count, __u32 *max)
  16. {
  17. struct ntsync_sem_args args;
  18. int ret;
  19. memset(&args, 0xcc, sizeof(args));
  20. ret = ioctl(sem, NTSYNC_IOC_SEM_READ, &args);
  21. *count = args.count;
  22. *max = args.max;
  23. return ret;
  24. }
  25. #define check_sem_state(sem, count, max) \
  26. ({ \
  27. __u32 __count, __max; \
  28. int ret = read_sem_state((sem), &__count, &__max); \
  29. EXPECT_EQ(0, ret); \
  30. EXPECT_EQ((count), __count); \
  31. EXPECT_EQ((max), __max); \
  32. })
  33. static int release_sem(int sem, __u32 *count)
  34. {
  35. return ioctl(sem, NTSYNC_IOC_SEM_RELEASE, count);
  36. }
  37. static int read_mutex_state(int mutex, __u32 *count, __u32 *owner)
  38. {
  39. struct ntsync_mutex_args args;
  40. int ret;
  41. memset(&args, 0xcc, sizeof(args));
  42. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &args);
  43. *count = args.count;
  44. *owner = args.owner;
  45. return ret;
  46. }
  47. #define check_mutex_state(mutex, count, owner) \
  48. ({ \
  49. __u32 __count, __owner; \
  50. int ret = read_mutex_state((mutex), &__count, &__owner); \
  51. EXPECT_EQ(0, ret); \
  52. EXPECT_EQ((count), __count); \
  53. EXPECT_EQ((owner), __owner); \
  54. })
  55. static int unlock_mutex(int mutex, __u32 owner, __u32 *count)
  56. {
  57. struct ntsync_mutex_args args;
  58. int ret;
  59. args.owner = owner;
  60. args.count = 0xdeadbeef;
  61. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_UNLOCK, &args);
  62. *count = args.count;
  63. return ret;
  64. }
  65. static int read_event_state(int event, __u32 *signaled, __u32 *manual)
  66. {
  67. struct ntsync_event_args args;
  68. int ret;
  69. memset(&args, 0xcc, sizeof(args));
  70. ret = ioctl(event, NTSYNC_IOC_EVENT_READ, &args);
  71. *signaled = args.signaled;
  72. *manual = args.manual;
  73. return ret;
  74. }
  75. #define check_event_state(event, signaled, manual) \
  76. ({ \
  77. __u32 __signaled, __manual; \
  78. int ret = read_event_state((event), &__signaled, &__manual); \
  79. EXPECT_EQ(0, ret); \
  80. EXPECT_EQ((signaled), __signaled); \
  81. EXPECT_EQ((manual), __manual); \
  82. })
  83. static int wait_objs(int fd, unsigned long request, __u32 count,
  84. const int *objs, __u32 owner, int alert, __u32 *index)
  85. {
  86. struct ntsync_wait_args args = {0};
  87. struct timespec timeout;
  88. int ret;
  89. clock_gettime(CLOCK_MONOTONIC, &timeout);
  90. args.timeout = timeout.tv_sec * 1000000000 + timeout.tv_nsec;
  91. args.count = count;
  92. args.objs = (uintptr_t)objs;
  93. args.owner = owner;
  94. args.index = 0xdeadbeef;
  95. args.alert = alert;
  96. ret = ioctl(fd, request, &args);
  97. *index = args.index;
  98. return ret;
  99. }
  100. static int wait_any(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index)
  101. {
  102. return wait_objs(fd, NTSYNC_IOC_WAIT_ANY, count, objs, owner, 0, index);
  103. }
  104. static int wait_all(int fd, __u32 count, const int *objs, __u32 owner, __u32 *index)
  105. {
  106. return wait_objs(fd, NTSYNC_IOC_WAIT_ALL, count, objs, owner, 0, index);
  107. }
  108. static int wait_any_alert(int fd, __u32 count, const int *objs,
  109. __u32 owner, int alert, __u32 *index)
  110. {
  111. return wait_objs(fd, NTSYNC_IOC_WAIT_ANY,
  112. count, objs, owner, alert, index);
  113. }
  114. static int wait_all_alert(int fd, __u32 count, const int *objs,
  115. __u32 owner, int alert, __u32 *index)
  116. {
  117. return wait_objs(fd, NTSYNC_IOC_WAIT_ALL,
  118. count, objs, owner, alert, index);
  119. }
  120. TEST(semaphore_state)
  121. {
  122. struct ntsync_sem_args sem_args;
  123. struct timespec timeout;
  124. __u32 count, index;
  125. int fd, ret, sem;
  126. clock_gettime(CLOCK_MONOTONIC, &timeout);
  127. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  128. ASSERT_LE(0, fd);
  129. sem_args.count = 3;
  130. sem_args.max = 2;
  131. sem = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  132. EXPECT_EQ(-1, sem);
  133. EXPECT_EQ(EINVAL, errno);
  134. sem_args.count = 2;
  135. sem_args.max = 2;
  136. sem = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  137. EXPECT_LE(0, sem);
  138. check_sem_state(sem, 2, 2);
  139. count = 0;
  140. ret = release_sem(sem, &count);
  141. EXPECT_EQ(0, ret);
  142. EXPECT_EQ(2, count);
  143. check_sem_state(sem, 2, 2);
  144. count = 1;
  145. ret = release_sem(sem, &count);
  146. EXPECT_EQ(-1, ret);
  147. EXPECT_EQ(EOVERFLOW, errno);
  148. check_sem_state(sem, 2, 2);
  149. ret = wait_any(fd, 1, &sem, 123, &index);
  150. EXPECT_EQ(0, ret);
  151. EXPECT_EQ(0, index);
  152. check_sem_state(sem, 1, 2);
  153. ret = wait_any(fd, 1, &sem, 123, &index);
  154. EXPECT_EQ(0, ret);
  155. EXPECT_EQ(0, index);
  156. check_sem_state(sem, 0, 2);
  157. ret = wait_any(fd, 1, &sem, 123, &index);
  158. EXPECT_EQ(-1, ret);
  159. EXPECT_EQ(ETIMEDOUT, errno);
  160. count = 3;
  161. ret = release_sem(sem, &count);
  162. EXPECT_EQ(-1, ret);
  163. EXPECT_EQ(EOVERFLOW, errno);
  164. check_sem_state(sem, 0, 2);
  165. count = 2;
  166. ret = release_sem(sem, &count);
  167. EXPECT_EQ(0, ret);
  168. EXPECT_EQ(0, count);
  169. check_sem_state(sem, 2, 2);
  170. ret = wait_any(fd, 1, &sem, 123, &index);
  171. EXPECT_EQ(0, ret);
  172. ret = wait_any(fd, 1, &sem, 123, &index);
  173. EXPECT_EQ(0, ret);
  174. count = 1;
  175. ret = release_sem(sem, &count);
  176. EXPECT_EQ(0, ret);
  177. EXPECT_EQ(0, count);
  178. check_sem_state(sem, 1, 2);
  179. count = ~0u;
  180. ret = release_sem(sem, &count);
  181. EXPECT_EQ(-1, ret);
  182. EXPECT_EQ(EOVERFLOW, errno);
  183. check_sem_state(sem, 1, 2);
  184. close(sem);
  185. close(fd);
  186. }
  187. TEST(mutex_state)
  188. {
  189. struct ntsync_mutex_args mutex_args;
  190. __u32 owner, count, index;
  191. struct timespec timeout;
  192. int fd, ret, mutex;
  193. clock_gettime(CLOCK_MONOTONIC, &timeout);
  194. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  195. ASSERT_LE(0, fd);
  196. mutex_args.owner = 123;
  197. mutex_args.count = 0;
  198. mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  199. EXPECT_EQ(-1, mutex);
  200. EXPECT_EQ(EINVAL, errno);
  201. mutex_args.owner = 0;
  202. mutex_args.count = 2;
  203. mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  204. EXPECT_EQ(-1, mutex);
  205. EXPECT_EQ(EINVAL, errno);
  206. mutex_args.owner = 123;
  207. mutex_args.count = 2;
  208. mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  209. EXPECT_LE(0, mutex);
  210. check_mutex_state(mutex, 2, 123);
  211. ret = unlock_mutex(mutex, 0, &count);
  212. EXPECT_EQ(-1, ret);
  213. EXPECT_EQ(EINVAL, errno);
  214. ret = unlock_mutex(mutex, 456, &count);
  215. EXPECT_EQ(-1, ret);
  216. EXPECT_EQ(EPERM, errno);
  217. check_mutex_state(mutex, 2, 123);
  218. ret = unlock_mutex(mutex, 123, &count);
  219. EXPECT_EQ(0, ret);
  220. EXPECT_EQ(2, count);
  221. check_mutex_state(mutex, 1, 123);
  222. ret = unlock_mutex(mutex, 123, &count);
  223. EXPECT_EQ(0, ret);
  224. EXPECT_EQ(1, count);
  225. check_mutex_state(mutex, 0, 0);
  226. ret = unlock_mutex(mutex, 123, &count);
  227. EXPECT_EQ(-1, ret);
  228. EXPECT_EQ(EPERM, errno);
  229. ret = wait_any(fd, 1, &mutex, 456, &index);
  230. EXPECT_EQ(0, ret);
  231. EXPECT_EQ(0, index);
  232. check_mutex_state(mutex, 1, 456);
  233. ret = wait_any(fd, 1, &mutex, 456, &index);
  234. EXPECT_EQ(0, ret);
  235. EXPECT_EQ(0, index);
  236. check_mutex_state(mutex, 2, 456);
  237. ret = unlock_mutex(mutex, 456, &count);
  238. EXPECT_EQ(0, ret);
  239. EXPECT_EQ(2, count);
  240. check_mutex_state(mutex, 1, 456);
  241. ret = wait_any(fd, 1, &mutex, 123, &index);
  242. EXPECT_EQ(-1, ret);
  243. EXPECT_EQ(ETIMEDOUT, errno);
  244. owner = 0;
  245. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
  246. EXPECT_EQ(-1, ret);
  247. EXPECT_EQ(EINVAL, errno);
  248. owner = 123;
  249. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
  250. EXPECT_EQ(-1, ret);
  251. EXPECT_EQ(EPERM, errno);
  252. check_mutex_state(mutex, 1, 456);
  253. owner = 456;
  254. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
  255. EXPECT_EQ(0, ret);
  256. memset(&mutex_args, 0xcc, sizeof(mutex_args));
  257. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args);
  258. EXPECT_EQ(-1, ret);
  259. EXPECT_EQ(EOWNERDEAD, errno);
  260. EXPECT_EQ(0, mutex_args.count);
  261. EXPECT_EQ(0, mutex_args.owner);
  262. memset(&mutex_args, 0xcc, sizeof(mutex_args));
  263. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args);
  264. EXPECT_EQ(-1, ret);
  265. EXPECT_EQ(EOWNERDEAD, errno);
  266. EXPECT_EQ(0, mutex_args.count);
  267. EXPECT_EQ(0, mutex_args.owner);
  268. ret = wait_any(fd, 1, &mutex, 123, &index);
  269. EXPECT_EQ(-1, ret);
  270. EXPECT_EQ(EOWNERDEAD, errno);
  271. EXPECT_EQ(0, index);
  272. check_mutex_state(mutex, 1, 123);
  273. owner = 123;
  274. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_KILL, &owner);
  275. EXPECT_EQ(0, ret);
  276. memset(&mutex_args, 0xcc, sizeof(mutex_args));
  277. ret = ioctl(mutex, NTSYNC_IOC_MUTEX_READ, &mutex_args);
  278. EXPECT_EQ(-1, ret);
  279. EXPECT_EQ(EOWNERDEAD, errno);
  280. EXPECT_EQ(0, mutex_args.count);
  281. EXPECT_EQ(0, mutex_args.owner);
  282. ret = wait_any(fd, 1, &mutex, 123, &index);
  283. EXPECT_EQ(-1, ret);
  284. EXPECT_EQ(EOWNERDEAD, errno);
  285. EXPECT_EQ(0, index);
  286. check_mutex_state(mutex, 1, 123);
  287. close(mutex);
  288. mutex_args.owner = 0;
  289. mutex_args.count = 0;
  290. mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  291. EXPECT_LE(0, mutex);
  292. check_mutex_state(mutex, 0, 0);
  293. ret = wait_any(fd, 1, &mutex, 123, &index);
  294. EXPECT_EQ(0, ret);
  295. EXPECT_EQ(0, index);
  296. check_mutex_state(mutex, 1, 123);
  297. close(mutex);
  298. mutex_args.owner = 123;
  299. mutex_args.count = ~0u;
  300. mutex = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  301. EXPECT_LE(0, mutex);
  302. check_mutex_state(mutex, ~0u, 123);
  303. ret = wait_any(fd, 1, &mutex, 123, &index);
  304. EXPECT_EQ(-1, ret);
  305. EXPECT_EQ(ETIMEDOUT, errno);
  306. close(mutex);
  307. close(fd);
  308. }
  309. TEST(manual_event_state)
  310. {
  311. struct ntsync_event_args event_args;
  312. __u32 index, signaled;
  313. int fd, event, ret;
  314. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  315. ASSERT_LE(0, fd);
  316. event_args.manual = 1;
  317. event_args.signaled = 0;
  318. event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  319. EXPECT_LE(0, event);
  320. check_event_state(event, 0, 1);
  321. signaled = 0xdeadbeef;
  322. ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
  323. EXPECT_EQ(0, ret);
  324. EXPECT_EQ(0, signaled);
  325. check_event_state(event, 1, 1);
  326. ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
  327. EXPECT_EQ(0, ret);
  328. EXPECT_EQ(1, signaled);
  329. check_event_state(event, 1, 1);
  330. ret = wait_any(fd, 1, &event, 123, &index);
  331. EXPECT_EQ(0, ret);
  332. EXPECT_EQ(0, index);
  333. check_event_state(event, 1, 1);
  334. signaled = 0xdeadbeef;
  335. ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
  336. EXPECT_EQ(0, ret);
  337. EXPECT_EQ(1, signaled);
  338. check_event_state(event, 0, 1);
  339. ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
  340. EXPECT_EQ(0, ret);
  341. EXPECT_EQ(0, signaled);
  342. check_event_state(event, 0, 1);
  343. ret = wait_any(fd, 1, &event, 123, &index);
  344. EXPECT_EQ(-1, ret);
  345. EXPECT_EQ(ETIMEDOUT, errno);
  346. ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
  347. EXPECT_EQ(0, ret);
  348. EXPECT_EQ(0, signaled);
  349. ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled);
  350. EXPECT_EQ(0, ret);
  351. EXPECT_EQ(1, signaled);
  352. check_event_state(event, 0, 1);
  353. ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled);
  354. EXPECT_EQ(0, ret);
  355. EXPECT_EQ(0, signaled);
  356. check_event_state(event, 0, 1);
  357. close(event);
  358. close(fd);
  359. }
  360. TEST(auto_event_state)
  361. {
  362. struct ntsync_event_args event_args;
  363. __u32 index, signaled;
  364. int fd, event, ret;
  365. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  366. ASSERT_LE(0, fd);
  367. event_args.manual = 0;
  368. event_args.signaled = 1;
  369. event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  370. EXPECT_LE(0, event);
  371. check_event_state(event, 1, 0);
  372. signaled = 0xdeadbeef;
  373. ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
  374. EXPECT_EQ(0, ret);
  375. EXPECT_EQ(1, signaled);
  376. check_event_state(event, 1, 0);
  377. ret = wait_any(fd, 1, &event, 123, &index);
  378. EXPECT_EQ(0, ret);
  379. EXPECT_EQ(0, index);
  380. check_event_state(event, 0, 0);
  381. signaled = 0xdeadbeef;
  382. ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
  383. EXPECT_EQ(0, ret);
  384. EXPECT_EQ(0, signaled);
  385. check_event_state(event, 0, 0);
  386. ret = wait_any(fd, 1, &event, 123, &index);
  387. EXPECT_EQ(-1, ret);
  388. EXPECT_EQ(ETIMEDOUT, errno);
  389. ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
  390. EXPECT_EQ(0, ret);
  391. EXPECT_EQ(0, signaled);
  392. ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled);
  393. EXPECT_EQ(0, ret);
  394. EXPECT_EQ(1, signaled);
  395. check_event_state(event, 0, 0);
  396. ret = ioctl(event, NTSYNC_IOC_EVENT_PULSE, &signaled);
  397. EXPECT_EQ(0, ret);
  398. EXPECT_EQ(0, signaled);
  399. check_event_state(event, 0, 0);
  400. close(event);
  401. close(fd);
  402. }
  403. TEST(test_wait_any)
  404. {
  405. int objs[NTSYNC_MAX_WAIT_COUNT + 1], fd, ret;
  406. struct ntsync_mutex_args mutex_args = {0};
  407. struct ntsync_sem_args sem_args = {0};
  408. __u32 owner, index, count, i;
  409. struct timespec timeout;
  410. clock_gettime(CLOCK_MONOTONIC, &timeout);
  411. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  412. ASSERT_LE(0, fd);
  413. sem_args.count = 2;
  414. sem_args.max = 3;
  415. objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  416. EXPECT_LE(0, objs[0]);
  417. mutex_args.owner = 0;
  418. mutex_args.count = 0;
  419. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  420. EXPECT_LE(0, objs[1]);
  421. ret = wait_any(fd, 2, objs, 123, &index);
  422. EXPECT_EQ(0, ret);
  423. EXPECT_EQ(0, index);
  424. check_sem_state(objs[0], 1, 3);
  425. check_mutex_state(objs[1], 0, 0);
  426. ret = wait_any(fd, 2, objs, 123, &index);
  427. EXPECT_EQ(0, ret);
  428. EXPECT_EQ(0, index);
  429. check_sem_state(objs[0], 0, 3);
  430. check_mutex_state(objs[1], 0, 0);
  431. ret = wait_any(fd, 2, objs, 123, &index);
  432. EXPECT_EQ(0, ret);
  433. EXPECT_EQ(1, index);
  434. check_sem_state(objs[0], 0, 3);
  435. check_mutex_state(objs[1], 1, 123);
  436. count = 1;
  437. ret = release_sem(objs[0], &count);
  438. EXPECT_EQ(0, ret);
  439. EXPECT_EQ(0, count);
  440. ret = wait_any(fd, 2, objs, 123, &index);
  441. EXPECT_EQ(0, ret);
  442. EXPECT_EQ(0, index);
  443. check_sem_state(objs[0], 0, 3);
  444. check_mutex_state(objs[1], 1, 123);
  445. ret = wait_any(fd, 2, objs, 123, &index);
  446. EXPECT_EQ(0, ret);
  447. EXPECT_EQ(1, index);
  448. check_sem_state(objs[0], 0, 3);
  449. check_mutex_state(objs[1], 2, 123);
  450. ret = wait_any(fd, 2, objs, 456, &index);
  451. EXPECT_EQ(-1, ret);
  452. EXPECT_EQ(ETIMEDOUT, errno);
  453. owner = 123;
  454. ret = ioctl(objs[1], NTSYNC_IOC_MUTEX_KILL, &owner);
  455. EXPECT_EQ(0, ret);
  456. ret = wait_any(fd, 2, objs, 456, &index);
  457. EXPECT_EQ(-1, ret);
  458. EXPECT_EQ(EOWNERDEAD, errno);
  459. EXPECT_EQ(1, index);
  460. ret = wait_any(fd, 2, objs, 456, &index);
  461. EXPECT_EQ(0, ret);
  462. EXPECT_EQ(1, index);
  463. close(objs[1]);
  464. /* test waiting on the same object twice */
  465. count = 2;
  466. ret = release_sem(objs[0], &count);
  467. EXPECT_EQ(0, ret);
  468. EXPECT_EQ(0, count);
  469. objs[1] = objs[0];
  470. ret = wait_any(fd, 2, objs, 456, &index);
  471. EXPECT_EQ(0, ret);
  472. EXPECT_EQ(0, index);
  473. check_sem_state(objs[0], 1, 3);
  474. ret = wait_any(fd, 0, NULL, 456, &index);
  475. EXPECT_EQ(-1, ret);
  476. EXPECT_EQ(ETIMEDOUT, errno);
  477. for (i = 1; i < NTSYNC_MAX_WAIT_COUNT + 1; ++i)
  478. objs[i] = objs[0];
  479. ret = wait_any(fd, NTSYNC_MAX_WAIT_COUNT, objs, 123, &index);
  480. EXPECT_EQ(0, ret);
  481. EXPECT_EQ(0, index);
  482. ret = wait_any(fd, NTSYNC_MAX_WAIT_COUNT + 1, objs, 123, &index);
  483. EXPECT_EQ(-1, ret);
  484. EXPECT_EQ(EINVAL, errno);
  485. ret = wait_any(fd, -1, objs, 123, &index);
  486. EXPECT_EQ(-1, ret);
  487. EXPECT_EQ(EINVAL, errno);
  488. close(objs[0]);
  489. close(fd);
  490. }
  491. TEST(test_wait_all)
  492. {
  493. struct ntsync_event_args event_args = {0};
  494. struct ntsync_mutex_args mutex_args = {0};
  495. struct ntsync_sem_args sem_args = {0};
  496. __u32 owner, index, count;
  497. int objs[2], fd, ret;
  498. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  499. ASSERT_LE(0, fd);
  500. sem_args.count = 2;
  501. sem_args.max = 3;
  502. objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  503. EXPECT_LE(0, objs[0]);
  504. mutex_args.owner = 0;
  505. mutex_args.count = 0;
  506. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  507. EXPECT_LE(0, objs[1]);
  508. ret = wait_all(fd, 2, objs, 123, &index);
  509. EXPECT_EQ(0, ret);
  510. EXPECT_EQ(0, index);
  511. check_sem_state(objs[0], 1, 3);
  512. check_mutex_state(objs[1], 1, 123);
  513. ret = wait_all(fd, 2, objs, 456, &index);
  514. EXPECT_EQ(-1, ret);
  515. EXPECT_EQ(ETIMEDOUT, errno);
  516. check_sem_state(objs[0], 1, 3);
  517. check_mutex_state(objs[1], 1, 123);
  518. ret = wait_all(fd, 2, objs, 123, &index);
  519. EXPECT_EQ(0, ret);
  520. EXPECT_EQ(0, index);
  521. check_sem_state(objs[0], 0, 3);
  522. check_mutex_state(objs[1], 2, 123);
  523. ret = wait_all(fd, 2, objs, 123, &index);
  524. EXPECT_EQ(-1, ret);
  525. EXPECT_EQ(ETIMEDOUT, errno);
  526. check_sem_state(objs[0], 0, 3);
  527. check_mutex_state(objs[1], 2, 123);
  528. count = 3;
  529. ret = release_sem(objs[0], &count);
  530. EXPECT_EQ(0, ret);
  531. EXPECT_EQ(0, count);
  532. ret = wait_all(fd, 2, objs, 123, &index);
  533. EXPECT_EQ(0, ret);
  534. EXPECT_EQ(0, index);
  535. check_sem_state(objs[0], 2, 3);
  536. check_mutex_state(objs[1], 3, 123);
  537. owner = 123;
  538. ret = ioctl(objs[1], NTSYNC_IOC_MUTEX_KILL, &owner);
  539. EXPECT_EQ(0, ret);
  540. ret = wait_all(fd, 2, objs, 123, &index);
  541. EXPECT_EQ(-1, ret);
  542. EXPECT_EQ(EOWNERDEAD, errno);
  543. check_sem_state(objs[0], 1, 3);
  544. check_mutex_state(objs[1], 1, 123);
  545. close(objs[1]);
  546. event_args.manual = true;
  547. event_args.signaled = true;
  548. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  549. EXPECT_LE(0, objs[1]);
  550. ret = wait_all(fd, 2, objs, 123, &index);
  551. EXPECT_EQ(0, ret);
  552. EXPECT_EQ(0, index);
  553. check_sem_state(objs[0], 0, 3);
  554. check_event_state(objs[1], 1, 1);
  555. close(objs[1]);
  556. /* test waiting on the same object twice */
  557. objs[1] = objs[0];
  558. ret = wait_all(fd, 2, objs, 123, &index);
  559. EXPECT_EQ(-1, ret);
  560. EXPECT_EQ(EINVAL, errno);
  561. close(objs[0]);
  562. close(fd);
  563. }
  564. struct wake_args {
  565. int fd;
  566. int obj;
  567. };
  568. struct wait_args {
  569. int fd;
  570. unsigned long request;
  571. struct ntsync_wait_args *args;
  572. int ret;
  573. int err;
  574. };
  575. static void *wait_thread(void *arg)
  576. {
  577. struct wait_args *args = arg;
  578. args->ret = ioctl(args->fd, args->request, args->args);
  579. args->err = errno;
  580. return NULL;
  581. }
  582. static __u64 get_abs_timeout(unsigned int ms)
  583. {
  584. struct timespec timeout;
  585. clock_gettime(CLOCK_MONOTONIC, &timeout);
  586. return (timeout.tv_sec * 1000000000) + timeout.tv_nsec + (ms * 1000000);
  587. }
  588. static int wait_for_thread(pthread_t thread, unsigned int ms)
  589. {
  590. struct timespec timeout;
  591. clock_gettime(CLOCK_REALTIME, &timeout);
  592. timeout.tv_nsec += ms * 1000000;
  593. timeout.tv_sec += (timeout.tv_nsec / 1000000000);
  594. timeout.tv_nsec %= 1000000000;
  595. return pthread_timedjoin_np(thread, NULL, &timeout);
  596. }
  597. TEST(wake_any)
  598. {
  599. struct ntsync_event_args event_args = {0};
  600. struct ntsync_mutex_args mutex_args = {0};
  601. struct ntsync_wait_args wait_args = {0};
  602. struct ntsync_sem_args sem_args = {0};
  603. struct wait_args thread_args;
  604. __u32 count, index, signaled;
  605. int objs[2], fd, ret;
  606. pthread_t thread;
  607. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  608. ASSERT_LE(0, fd);
  609. sem_args.count = 0;
  610. sem_args.max = 3;
  611. objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  612. EXPECT_LE(0, objs[0]);
  613. mutex_args.owner = 123;
  614. mutex_args.count = 1;
  615. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  616. EXPECT_LE(0, objs[1]);
  617. /* test waking the semaphore */
  618. wait_args.timeout = get_abs_timeout(1000);
  619. wait_args.objs = (uintptr_t)objs;
  620. wait_args.count = 2;
  621. wait_args.owner = 456;
  622. wait_args.index = 0xdeadbeef;
  623. thread_args.fd = fd;
  624. thread_args.args = &wait_args;
  625. thread_args.request = NTSYNC_IOC_WAIT_ANY;
  626. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  627. EXPECT_EQ(0, ret);
  628. ret = wait_for_thread(thread, 100);
  629. EXPECT_EQ(ETIMEDOUT, ret);
  630. count = 1;
  631. ret = release_sem(objs[0], &count);
  632. EXPECT_EQ(0, ret);
  633. EXPECT_EQ(0, count);
  634. check_sem_state(objs[0], 0, 3);
  635. ret = wait_for_thread(thread, 100);
  636. EXPECT_EQ(0, ret);
  637. EXPECT_EQ(0, thread_args.ret);
  638. EXPECT_EQ(0, wait_args.index);
  639. /* test waking the mutex */
  640. /* first grab it again for owner 123 */
  641. ret = wait_any(fd, 1, &objs[1], 123, &index);
  642. EXPECT_EQ(0, ret);
  643. EXPECT_EQ(0, index);
  644. wait_args.timeout = get_abs_timeout(1000);
  645. wait_args.owner = 456;
  646. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  647. EXPECT_EQ(0, ret);
  648. ret = wait_for_thread(thread, 100);
  649. EXPECT_EQ(ETIMEDOUT, ret);
  650. ret = unlock_mutex(objs[1], 123, &count);
  651. EXPECT_EQ(0, ret);
  652. EXPECT_EQ(2, count);
  653. ret = pthread_tryjoin_np(thread, NULL);
  654. EXPECT_EQ(EBUSY, ret);
  655. ret = unlock_mutex(objs[1], 123, &count);
  656. EXPECT_EQ(0, ret);
  657. EXPECT_EQ(1, mutex_args.count);
  658. check_mutex_state(objs[1], 1, 456);
  659. ret = wait_for_thread(thread, 100);
  660. EXPECT_EQ(0, ret);
  661. EXPECT_EQ(0, thread_args.ret);
  662. EXPECT_EQ(1, wait_args.index);
  663. close(objs[1]);
  664. /* test waking events */
  665. event_args.manual = false;
  666. event_args.signaled = false;
  667. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  668. EXPECT_LE(0, objs[1]);
  669. wait_args.timeout = get_abs_timeout(1000);
  670. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  671. EXPECT_EQ(0, ret);
  672. ret = wait_for_thread(thread, 100);
  673. EXPECT_EQ(ETIMEDOUT, ret);
  674. ret = ioctl(objs[1], NTSYNC_IOC_EVENT_SET, &signaled);
  675. EXPECT_EQ(0, ret);
  676. EXPECT_EQ(0, signaled);
  677. check_event_state(objs[1], 0, 0);
  678. ret = wait_for_thread(thread, 100);
  679. EXPECT_EQ(0, ret);
  680. EXPECT_EQ(0, thread_args.ret);
  681. EXPECT_EQ(1, wait_args.index);
  682. wait_args.timeout = get_abs_timeout(1000);
  683. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  684. EXPECT_EQ(0, ret);
  685. ret = wait_for_thread(thread, 100);
  686. EXPECT_EQ(ETIMEDOUT, ret);
  687. ret = ioctl(objs[1], NTSYNC_IOC_EVENT_PULSE, &signaled);
  688. EXPECT_EQ(0, ret);
  689. EXPECT_EQ(0, signaled);
  690. check_event_state(objs[1], 0, 0);
  691. ret = wait_for_thread(thread, 100);
  692. EXPECT_EQ(0, ret);
  693. EXPECT_EQ(0, thread_args.ret);
  694. EXPECT_EQ(1, wait_args.index);
  695. close(objs[1]);
  696. event_args.manual = true;
  697. event_args.signaled = false;
  698. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  699. EXPECT_LE(0, objs[1]);
  700. wait_args.timeout = get_abs_timeout(1000);
  701. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  702. EXPECT_EQ(0, ret);
  703. ret = wait_for_thread(thread, 100);
  704. EXPECT_EQ(ETIMEDOUT, ret);
  705. ret = ioctl(objs[1], NTSYNC_IOC_EVENT_SET, &signaled);
  706. EXPECT_EQ(0, ret);
  707. EXPECT_EQ(0, signaled);
  708. check_event_state(objs[1], 1, 1);
  709. ret = wait_for_thread(thread, 100);
  710. EXPECT_EQ(0, ret);
  711. EXPECT_EQ(0, thread_args.ret);
  712. EXPECT_EQ(1, wait_args.index);
  713. ret = ioctl(objs[1], NTSYNC_IOC_EVENT_RESET, &signaled);
  714. EXPECT_EQ(0, ret);
  715. EXPECT_EQ(1, signaled);
  716. wait_args.timeout = get_abs_timeout(1000);
  717. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  718. EXPECT_EQ(0, ret);
  719. ret = wait_for_thread(thread, 100);
  720. EXPECT_EQ(ETIMEDOUT, ret);
  721. ret = ioctl(objs[1], NTSYNC_IOC_EVENT_PULSE, &signaled);
  722. EXPECT_EQ(0, ret);
  723. EXPECT_EQ(0, signaled);
  724. check_event_state(objs[1], 0, 1);
  725. ret = wait_for_thread(thread, 100);
  726. EXPECT_EQ(0, ret);
  727. EXPECT_EQ(0, thread_args.ret);
  728. EXPECT_EQ(1, wait_args.index);
  729. /* delete an object while it's being waited on */
  730. wait_args.timeout = get_abs_timeout(200);
  731. wait_args.owner = 123;
  732. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  733. EXPECT_EQ(0, ret);
  734. ret = wait_for_thread(thread, 100);
  735. EXPECT_EQ(ETIMEDOUT, ret);
  736. close(objs[0]);
  737. close(objs[1]);
  738. ret = wait_for_thread(thread, 200);
  739. EXPECT_EQ(0, ret);
  740. EXPECT_EQ(-1, thread_args.ret);
  741. EXPECT_EQ(ETIMEDOUT, thread_args.err);
  742. close(fd);
  743. }
  744. TEST(wake_all)
  745. {
  746. struct ntsync_event_args manual_event_args = {0};
  747. struct ntsync_event_args auto_event_args = {0};
  748. struct ntsync_mutex_args mutex_args = {0};
  749. struct ntsync_wait_args wait_args = {0};
  750. struct ntsync_sem_args sem_args = {0};
  751. struct wait_args thread_args;
  752. __u32 count, index, signaled;
  753. int objs[4], fd, ret;
  754. pthread_t thread;
  755. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  756. ASSERT_LE(0, fd);
  757. sem_args.count = 0;
  758. sem_args.max = 3;
  759. objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  760. EXPECT_LE(0, objs[0]);
  761. mutex_args.owner = 123;
  762. mutex_args.count = 1;
  763. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  764. EXPECT_LE(0, objs[1]);
  765. manual_event_args.manual = true;
  766. manual_event_args.signaled = true;
  767. objs[2] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &manual_event_args);
  768. EXPECT_LE(0, objs[2]);
  769. auto_event_args.manual = false;
  770. auto_event_args.signaled = true;
  771. objs[3] = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &auto_event_args);
  772. EXPECT_EQ(0, objs[3]);
  773. wait_args.timeout = get_abs_timeout(1000);
  774. wait_args.objs = (uintptr_t)objs;
  775. wait_args.count = 4;
  776. wait_args.owner = 456;
  777. thread_args.fd = fd;
  778. thread_args.args = &wait_args;
  779. thread_args.request = NTSYNC_IOC_WAIT_ALL;
  780. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  781. EXPECT_EQ(0, ret);
  782. ret = wait_for_thread(thread, 100);
  783. EXPECT_EQ(ETIMEDOUT, ret);
  784. count = 1;
  785. ret = release_sem(objs[0], &count);
  786. EXPECT_EQ(0, ret);
  787. EXPECT_EQ(0, count);
  788. ret = pthread_tryjoin_np(thread, NULL);
  789. EXPECT_EQ(EBUSY, ret);
  790. check_sem_state(objs[0], 1, 3);
  791. ret = wait_any(fd, 1, &objs[0], 123, &index);
  792. EXPECT_EQ(0, ret);
  793. EXPECT_EQ(0, index);
  794. ret = unlock_mutex(objs[1], 123, &count);
  795. EXPECT_EQ(0, ret);
  796. EXPECT_EQ(1, count);
  797. ret = pthread_tryjoin_np(thread, NULL);
  798. EXPECT_EQ(EBUSY, ret);
  799. check_mutex_state(objs[1], 0, 0);
  800. ret = ioctl(objs[2], NTSYNC_IOC_EVENT_RESET, &signaled);
  801. EXPECT_EQ(0, ret);
  802. EXPECT_EQ(1, signaled);
  803. count = 2;
  804. ret = release_sem(objs[0], &count);
  805. EXPECT_EQ(0, ret);
  806. EXPECT_EQ(0, count);
  807. check_sem_state(objs[0], 2, 3);
  808. ret = ioctl(objs[3], NTSYNC_IOC_EVENT_RESET, &signaled);
  809. EXPECT_EQ(0, ret);
  810. EXPECT_EQ(1, signaled);
  811. ret = ioctl(objs[2], NTSYNC_IOC_EVENT_SET, &signaled);
  812. EXPECT_EQ(0, ret);
  813. EXPECT_EQ(0, signaled);
  814. ret = ioctl(objs[3], NTSYNC_IOC_EVENT_SET, &signaled);
  815. EXPECT_EQ(0, ret);
  816. EXPECT_EQ(0, signaled);
  817. check_sem_state(objs[0], 1, 3);
  818. check_mutex_state(objs[1], 1, 456);
  819. check_event_state(objs[2], 1, 1);
  820. check_event_state(objs[3], 0, 0);
  821. ret = wait_for_thread(thread, 100);
  822. EXPECT_EQ(0, ret);
  823. EXPECT_EQ(0, thread_args.ret);
  824. /* delete an object while it's being waited on */
  825. wait_args.timeout = get_abs_timeout(200);
  826. wait_args.owner = 123;
  827. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  828. EXPECT_EQ(0, ret);
  829. ret = wait_for_thread(thread, 100);
  830. EXPECT_EQ(ETIMEDOUT, ret);
  831. close(objs[0]);
  832. close(objs[1]);
  833. close(objs[2]);
  834. close(objs[3]);
  835. ret = wait_for_thread(thread, 200);
  836. EXPECT_EQ(0, ret);
  837. EXPECT_EQ(-1, thread_args.ret);
  838. EXPECT_EQ(ETIMEDOUT, thread_args.err);
  839. close(fd);
  840. }
  841. TEST(alert_any)
  842. {
  843. struct ntsync_event_args event_args = {0};
  844. struct ntsync_wait_args wait_args = {0};
  845. struct ntsync_sem_args sem_args = {0};
  846. __u32 index, count, signaled;
  847. struct wait_args thread_args;
  848. int objs[2], event, fd, ret;
  849. pthread_t thread;
  850. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  851. ASSERT_LE(0, fd);
  852. sem_args.count = 0;
  853. sem_args.max = 2;
  854. objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  855. EXPECT_LE(0, objs[0]);
  856. sem_args.count = 1;
  857. sem_args.max = 2;
  858. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  859. EXPECT_LE(0, objs[1]);
  860. event_args.manual = true;
  861. event_args.signaled = true;
  862. event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  863. EXPECT_LE(0, event);
  864. ret = wait_any_alert(fd, 0, NULL, 123, event, &index);
  865. EXPECT_EQ(0, ret);
  866. EXPECT_EQ(0, index);
  867. ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
  868. EXPECT_EQ(0, ret);
  869. ret = wait_any_alert(fd, 0, NULL, 123, event, &index);
  870. EXPECT_EQ(-1, ret);
  871. EXPECT_EQ(ETIMEDOUT, errno);
  872. ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
  873. EXPECT_EQ(0, ret);
  874. ret = wait_any_alert(fd, 2, objs, 123, event, &index);
  875. EXPECT_EQ(0, ret);
  876. EXPECT_EQ(1, index);
  877. ret = wait_any_alert(fd, 2, objs, 123, event, &index);
  878. EXPECT_EQ(0, ret);
  879. EXPECT_EQ(2, index);
  880. /* test wakeup via alert */
  881. ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
  882. EXPECT_EQ(0, ret);
  883. wait_args.timeout = get_abs_timeout(1000);
  884. wait_args.objs = (uintptr_t)objs;
  885. wait_args.count = 2;
  886. wait_args.owner = 123;
  887. wait_args.index = 0xdeadbeef;
  888. wait_args.alert = event;
  889. thread_args.fd = fd;
  890. thread_args.args = &wait_args;
  891. thread_args.request = NTSYNC_IOC_WAIT_ANY;
  892. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  893. EXPECT_EQ(0, ret);
  894. ret = wait_for_thread(thread, 100);
  895. EXPECT_EQ(ETIMEDOUT, ret);
  896. ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
  897. EXPECT_EQ(0, ret);
  898. ret = wait_for_thread(thread, 100);
  899. EXPECT_EQ(0, ret);
  900. EXPECT_EQ(0, thread_args.ret);
  901. EXPECT_EQ(2, wait_args.index);
  902. close(event);
  903. /* test with an auto-reset event */
  904. event_args.manual = false;
  905. event_args.signaled = true;
  906. event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  907. EXPECT_LE(0, event);
  908. count = 1;
  909. ret = release_sem(objs[0], &count);
  910. EXPECT_EQ(0, ret);
  911. ret = wait_any_alert(fd, 2, objs, 123, event, &index);
  912. EXPECT_EQ(0, ret);
  913. EXPECT_EQ(0, index);
  914. ret = wait_any_alert(fd, 2, objs, 123, event, &index);
  915. EXPECT_EQ(0, ret);
  916. EXPECT_EQ(2, index);
  917. ret = wait_any_alert(fd, 2, objs, 123, event, &index);
  918. EXPECT_EQ(-1, ret);
  919. EXPECT_EQ(ETIMEDOUT, errno);
  920. close(event);
  921. close(objs[0]);
  922. close(objs[1]);
  923. close(fd);
  924. }
  925. TEST(alert_all)
  926. {
  927. struct ntsync_event_args event_args = {0};
  928. struct ntsync_wait_args wait_args = {0};
  929. struct ntsync_sem_args sem_args = {0};
  930. struct wait_args thread_args;
  931. __u32 index, count, signaled;
  932. int objs[2], event, fd, ret;
  933. pthread_t thread;
  934. fd = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  935. ASSERT_LE(0, fd);
  936. sem_args.count = 2;
  937. sem_args.max = 2;
  938. objs[0] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  939. EXPECT_LE(0, objs[0]);
  940. sem_args.count = 1;
  941. sem_args.max = 2;
  942. objs[1] = ioctl(fd, NTSYNC_IOC_CREATE_SEM, &sem_args);
  943. EXPECT_LE(0, objs[1]);
  944. event_args.manual = true;
  945. event_args.signaled = true;
  946. event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  947. EXPECT_LE(0, event);
  948. ret = wait_all_alert(fd, 2, objs, 123, event, &index);
  949. EXPECT_EQ(0, ret);
  950. EXPECT_EQ(0, index);
  951. ret = wait_all_alert(fd, 2, objs, 123, event, &index);
  952. EXPECT_EQ(0, ret);
  953. EXPECT_EQ(2, index);
  954. /* test wakeup via alert */
  955. ret = ioctl(event, NTSYNC_IOC_EVENT_RESET, &signaled);
  956. EXPECT_EQ(0, ret);
  957. wait_args.timeout = get_abs_timeout(1000);
  958. wait_args.objs = (uintptr_t)objs;
  959. wait_args.count = 2;
  960. wait_args.owner = 123;
  961. wait_args.index = 0xdeadbeef;
  962. wait_args.alert = event;
  963. thread_args.fd = fd;
  964. thread_args.args = &wait_args;
  965. thread_args.request = NTSYNC_IOC_WAIT_ALL;
  966. ret = pthread_create(&thread, NULL, wait_thread, &thread_args);
  967. EXPECT_EQ(0, ret);
  968. ret = wait_for_thread(thread, 100);
  969. EXPECT_EQ(ETIMEDOUT, ret);
  970. ret = ioctl(event, NTSYNC_IOC_EVENT_SET, &signaled);
  971. EXPECT_EQ(0, ret);
  972. ret = wait_for_thread(thread, 100);
  973. EXPECT_EQ(0, ret);
  974. EXPECT_EQ(0, thread_args.ret);
  975. EXPECT_EQ(2, wait_args.index);
  976. close(event);
  977. /* test with an auto-reset event */
  978. event_args.manual = false;
  979. event_args.signaled = true;
  980. event = ioctl(fd, NTSYNC_IOC_CREATE_EVENT, &event_args);
  981. EXPECT_LE(0, event);
  982. count = 2;
  983. ret = release_sem(objs[1], &count);
  984. EXPECT_EQ(0, ret);
  985. ret = wait_all_alert(fd, 2, objs, 123, event, &index);
  986. EXPECT_EQ(0, ret);
  987. EXPECT_EQ(0, index);
  988. ret = wait_all_alert(fd, 2, objs, 123, event, &index);
  989. EXPECT_EQ(0, ret);
  990. EXPECT_EQ(2, index);
  991. ret = wait_all_alert(fd, 2, objs, 123, event, &index);
  992. EXPECT_EQ(-1, ret);
  993. EXPECT_EQ(ETIMEDOUT, errno);
  994. close(event);
  995. close(objs[0]);
  996. close(objs[1]);
  997. close(fd);
  998. }
  999. #define STRESS_LOOPS 10000
  1000. #define STRESS_THREADS 4
  1001. static unsigned int stress_counter;
  1002. static int stress_device, stress_start_event, stress_mutex;
  1003. static void *stress_thread(void *arg)
  1004. {
  1005. struct ntsync_wait_args wait_args = {0};
  1006. __u32 index, count, i;
  1007. int ret;
  1008. wait_args.timeout = UINT64_MAX;
  1009. wait_args.count = 1;
  1010. wait_args.objs = (uintptr_t)&stress_start_event;
  1011. wait_args.owner = gettid();
  1012. wait_args.index = 0xdeadbeef;
  1013. ioctl(stress_device, NTSYNC_IOC_WAIT_ANY, &wait_args);
  1014. wait_args.objs = (uintptr_t)&stress_mutex;
  1015. for (i = 0; i < STRESS_LOOPS; ++i) {
  1016. ioctl(stress_device, NTSYNC_IOC_WAIT_ANY, &wait_args);
  1017. ++stress_counter;
  1018. unlock_mutex(stress_mutex, wait_args.owner, &count);
  1019. }
  1020. return NULL;
  1021. }
  1022. TEST(stress_wait)
  1023. {
  1024. struct ntsync_event_args event_args;
  1025. struct ntsync_mutex_args mutex_args;
  1026. pthread_t threads[STRESS_THREADS];
  1027. __u32 signaled, i;
  1028. int ret;
  1029. stress_device = open("/dev/ntsync", O_CLOEXEC | O_RDONLY);
  1030. ASSERT_LE(0, stress_device);
  1031. mutex_args.owner = 0;
  1032. mutex_args.count = 0;
  1033. stress_mutex = ioctl(stress_device, NTSYNC_IOC_CREATE_MUTEX, &mutex_args);
  1034. EXPECT_LE(0, stress_mutex);
  1035. event_args.manual = 1;
  1036. event_args.signaled = 0;
  1037. stress_start_event = ioctl(stress_device, NTSYNC_IOC_CREATE_EVENT, &event_args);
  1038. EXPECT_LE(0, stress_start_event);
  1039. for (i = 0; i < STRESS_THREADS; ++i)
  1040. pthread_create(&threads[i], NULL, stress_thread, NULL);
  1041. ret = ioctl(stress_start_event, NTSYNC_IOC_EVENT_SET, &signaled);
  1042. EXPECT_EQ(0, ret);
  1043. for (i = 0; i < STRESS_THREADS; ++i) {
  1044. ret = pthread_join(threads[i], NULL);
  1045. EXPECT_EQ(0, ret);
  1046. }
  1047. EXPECT_EQ(STRESS_LOOPS * STRESS_THREADS, stress_counter);
  1048. close(stress_start_event);
  1049. close(stress_mutex);
  1050. close(stress_device);
  1051. }
  1052. TEST_HARNESS_MAIN