Changeset 0163063 in rtems
- Timestamp:
- 07/08/15 18:42:08 (9 years ago)
- Branches:
- 5, master
- Children:
- ec349b58
- Parents:
- 4d0ade9
- git-author:
- Konstantin Belousov <kib@…> (07/08/15 18:42:08)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (10/12/17 05:04:10)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/score/src/kern_tc.c
r4d0ade9 r0163063 35 35 #define boottimebin _Timecounter_Boottimebin 36 36 #include <rtems/score/timecounterimpl.h> 37 #include <rtems/score/atomic.h> 37 38 #include <rtems/score/smp.h> 38 39 #include <rtems/score/todimpl.h> … … 83 84 /* FIXME: https://devel.rtems.org/ticket/2348 */ 84 85 #define ntp_update_second(a, b) do { (void) a; (void) b; } while (0) 86 87 static inline void 88 atomic_thread_fence_acq(void) 89 { 90 91 _Atomic_Fence(ATOMIC_ORDER_ACQUIRE); 92 } 93 94 static inline void 95 atomic_thread_fence_rel(void) 96 { 97 98 _Atomic_Fence(ATOMIC_ORDER_RELEASE); 99 } 100 101 static inline u_int 102 atomic_load_acq_int(Atomic_Uint *i) 103 { 104 105 return (_Atomic_Load_uint(i, ATOMIC_ORDER_ACQUIRE)); 106 } 107 108 static inline void 109 atomic_store_rel_int(Atomic_Uint *i, u_int val) 110 { 111 112 _Atomic_Store_uint(i, val, ATOMIC_ORDER_RELEASE); 113 } 85 114 #endif /* __rtems__ */ 86 115 … … 128 157 u_int th_generation; 129 158 #else /* __rtems__ */ 130 Atomic_U longth_generation;159 Atomic_Uint th_generation; 131 160 #endif /* __rtems__ */ 132 161 struct timehands *th_next; … … 278 307 } 279 308 280 static inline u_int281 tc_getgen(struct timehands *th)282 {283 284 #ifndef __rtems__285 #ifdef SMP286 return (atomic_load_acq_int(&th->th_generation));287 #else288 u_int gen;289 290 gen = th->th_generation;291 __compiler_membar();292 return (gen);293 #endif294 #else /* __rtems__ */295 return (_Atomic_Load_ulong(&th->th_generation, ATOMIC_ORDER_ACQUIRE));296 #endif /* __rtems__ */297 }298 299 static inline void300 tc_setgen(struct timehands *th, u_int newgen)301 {302 303 #ifndef __rtems__304 #ifdef SMP305 atomic_store_rel_int(&th->th_generation, newgen);306 #else307 __compiler_membar();308 th->th_generation = newgen;309 #endif310 #else /* __rtems__ */311 _Atomic_Store_ulong(&th->th_generation, newgen, ATOMIC_ORDER_RELEASE);312 #endif /* __rtems__ */313 }314 315 309 /* 316 310 * Functions for reading the time. We have to loop until we are sure that … … 328 322 do { 329 323 th = timehands; 330 gen = tc_getgen(th);324 gen = atomic_load_acq_int(&th->th_generation); 331 325 *bt = th->th_offset; 332 326 bintime_addx(bt, th->th_scale * tc_delta(th)); 333 } while (gen == 0 || gen != tc_getgen(th)); 327 atomic_thread_fence_acq(); 328 } while (gen == 0 || gen != th->th_generation); 334 329 } 335 330 … … 386 381 do { 387 382 th = timehands; 388 gen = tc_getgen(th);383 gen = atomic_load_acq_int(&th->th_generation); 389 384 *bt = th->th_offset; 390 } while (gen == 0 || gen != tc_getgen(th)); 385 atomic_thread_fence_acq(); 386 } while (gen == 0 || gen != th->th_generation); 391 387 } 392 388 … … 399 395 do { 400 396 th = timehands; 401 gen = tc_getgen(th);397 gen = atomic_load_acq_int(&th->th_generation); 402 398 bintime2timespec(&th->th_offset, tsp); 403 } while (gen == 0 || gen != tc_getgen(th)); 399 atomic_thread_fence_acq(); 400 } while (gen == 0 || gen != th->th_generation); 404 401 } 405 402 … … 412 409 do { 413 410 th = timehands; 414 gen = tc_getgen(th);411 gen = atomic_load_acq_int(&th->th_generation); 415 412 bintime2timeval(&th->th_offset, tvp); 416 } while (gen == 0 || gen != tc_getgen(th)); 413 atomic_thread_fence_acq(); 414 } while (gen == 0 || gen != th->th_generation); 417 415 } 418 416 … … 425 423 do { 426 424 th = timehands; 427 gen = tc_getgen(th);425 gen = atomic_load_acq_int(&th->th_generation); 428 426 *bt = th->th_offset; 429 } while (gen == 0 || gen != tc_getgen(th)); 427 atomic_thread_fence_acq(); 428 } while (gen == 0 || gen != th->th_generation); 430 429 bintime_add(bt, &boottimebin); 431 430 } … … 439 438 do { 440 439 th = timehands; 441 gen = tc_getgen(th);440 gen = atomic_load_acq_int(&th->th_generation); 442 441 *tsp = th->th_nanotime; 443 } while (gen == 0 || gen != tc_getgen(th)); 442 atomic_thread_fence_acq(); 443 } while (gen == 0 || gen != th->th_generation); 444 444 } 445 445 … … 452 452 do { 453 453 th = timehands; 454 gen = tc_getgen(th);454 gen = atomic_load_acq_int(&th->th_generation); 455 455 *tvp = th->th_microtime; 456 } while (gen == 0 || gen != tc_getgen(th)); 456 atomic_thread_fence_acq(); 457 } while (gen == 0 || gen != th->th_generation); 457 458 } 458 459 #else /* !FFCLOCK */ … … 465 466 do { 466 467 th = timehands; 467 gen = tc_getgen(th);468 gen = atomic_load_acq_int(&th->th_generation); 468 469 *bt = th->th_offset; 469 470 bintime_addx(bt, th->th_scale * tc_delta(th)); 470 } while (gen == 0 || gen != tc_getgen(th)); 471 atomic_thread_fence_acq(); 472 } while (gen == 0 || gen != th->th_generation); 471 473 } 472 474 #ifdef __rtems__ … … 480 482 do { 481 483 th = timehands; 482 gen = tc_getgen(th);484 gen = atomic_load_acq_int(&th->th_generation); 483 485 sbt = bttosbt(th->th_offset); 484 486 sbt += (th->th_scale * tc_delta(th)) >> 32; 485 } while (gen == 0 || gen != tc_getgen(th)); 487 atomic_thread_fence_acq(); 488 } while (gen == 0 || gen != th->th_generation); 486 489 487 490 return (sbt); … … 541 544 do { 542 545 th = timehands; 543 gen = tc_getgen(th);546 gen = atomic_load_acq_int(&th->th_generation); 544 547 *bt = th->th_offset; 545 } while (gen == 0 || gen != tc_getgen(th)); 548 atomic_thread_fence_acq(); 549 } while (gen == 0 || gen != th->th_generation); 546 550 } 547 551 … … 554 558 do { 555 559 th = timehands; 556 gen = tc_getgen(th);560 gen = atomic_load_acq_int(&th->th_generation); 557 561 bintime2timespec(&th->th_offset, tsp); 558 } while (gen == 0 || gen != tc_getgen(th)); 562 atomic_thread_fence_acq(); 563 } while (gen == 0 || gen != th->th_generation); 559 564 } 560 565 … … 567 572 do { 568 573 th = timehands; 569 gen = tc_getgen(th);574 gen = atomic_load_acq_int(&th->th_generation); 570 575 bintime2timeval(&th->th_offset, tvp); 571 } while (gen == 0 || gen != tc_getgen(th)); 576 atomic_thread_fence_acq(); 577 } while (gen == 0 || gen != th->th_generation); 572 578 } 573 579 … … 580 586 do { 581 587 th = timehands; 582 gen = tc_getgen(th);588 gen = atomic_load_acq_int(&th->th_generation); 583 589 *bt = th->th_offset; 584 } while (gen == 0 || gen != tc_getgen(th)); 590 atomic_thread_fence_acq(); 591 } while (gen == 0 || gen != th->th_generation); 585 592 bintime_add(bt, &boottimebin); 586 593 } … … 594 601 do { 595 602 th = timehands; 596 gen = tc_getgen(th);603 gen = atomic_load_acq_int(&th->th_generation); 597 604 *tsp = th->th_nanotime; 598 } while (gen == 0 || gen != tc_getgen(th)); 605 atomic_thread_fence_acq(); 606 } while (gen == 0 || gen != th->th_generation); 599 607 } 600 608 … … 607 615 do { 608 616 th = timehands; 609 gen = tc_getgen(th);617 gen = atomic_load_acq_int(&th->th_generation); 610 618 *tvp = th->th_microtime; 611 } while (gen == 0 || gen != tc_getgen(th)); 619 atomic_thread_fence_acq(); 620 } while (gen == 0 || gen != th->th_generation); 612 621 } 613 622 #endif /* FFCLOCK */ … … 1022 1031 do { 1023 1032 th = timehands; 1024 gen = tc_getgen(th);1033 gen = atomic_load_acq_int(&th->th_generation); 1025 1034 ffth = fftimehands; 1026 1035 delta = tc_delta(th); 1027 1036 *ffcount = ffth->tick_ffcount; 1028 } while (gen == 0 || gen != tc_getgen(th)); 1037 atomic_thread_fence_acq(); 1038 } while (gen == 0 || gen != th->th_generation); 1029 1039 1030 1040 *ffcount += delta; … … 1131 1141 do { 1132 1142 th = timehands; 1133 gen = tc_getgen(th);1143 gen = atomic_load_acq_int(&th->th_generation); 1134 1144 *tsp = th->th_nanotime; 1135 } while (gen == 0 || gen != tc_getgen(th)); 1145 atomic_thread_fence_acq(); 1146 } while (gen == 0 || gen != th->th_generation); 1136 1147 } 1137 1148 #endif /* __rtems__ */ … … 1175 1186 do { 1176 1187 th = timehands; 1177 gen = tc_getgen(th);1188 gen = atomic_load_acq_int(&th->th_generation); 1178 1189 fbi->th_scale = th->th_scale; 1179 1190 fbi->tick_time = th->th_offset; … … 1189 1200 if (!fast) 1190 1201 delta = tc_delta(th); 1191 } while (gen == 0 || gen != tc_getgen(th)); 1202 atomic_thread_fence_acq(); 1203 } while (gen == 0 || gen != th->th_generation); 1192 1204 1193 1205 clock_snap->delta = delta; … … 1438 1450 1439 1451 /* 1440 * Make the next timehands a copy of the current one, but do not 1441 * overwrite the generation or next pointer. While we update 1442 * the contents, the generation must be zero. 1452 * Make the next timehands a copy of the current one, but do 1453 * not overwrite the generation or next pointer. While we 1454 * update the contents, the generation must be zero. We need 1455 * to ensure that the zero generation is visible before the 1456 * data updates become visible, which requires release fence. 1457 * For similar reasons, re-reading of the generation after the 1458 * data is read should use acquire fence. 1443 1459 */ 1444 1460 tho = timehands; … … 1449 1465 #endif 1450 1466 ogen = th->th_generation; 1451 tc_setgen(th, 0); 1467 th->th_generation = 0; 1468 atomic_thread_fence_rel(); 1452 1469 #if defined(RTEMS_SMP) 1453 1470 bcopy(tho, th, offsetof(struct timehands, th_generation)); … … 1572 1589 if (++ogen == 0) 1573 1590 ogen = 1; 1574 tc_setgen(th, ogen);1591 atomic_store_rel_int(&th->th_generation, ogen); 1575 1592 1576 1593 /* Go live with the new struct timehands. */ … … 1856 1873 KASSERT(pps != NULL, ("NULL pps pointer in pps_capture")); 1857 1874 th = timehands; 1858 pps->capgen = tc_getgen(th);1875 pps->capgen = atomic_load_acq_int(&th->th_generation); 1859 1876 pps->capth = th; 1860 1877 #ifdef FFCLOCK … … 1862 1879 #endif 1863 1880 pps->capcount = th->th_counter->tc_get_timecount(th->th_counter); 1864 if (pps->capgen != tc_getgen(th)) 1881 atomic_thread_fence_acq(); 1882 if (pps->capgen != th->th_generation) 1865 1883 pps->capgen = 0; 1866 1884 } … … 1882 1900 KASSERT(pps != NULL, ("NULL pps pointer in pps_event")); 1883 1901 /* If the timecounter was wound up underneath us, bail out. */ 1884 if (pps->capgen == 0 || pps->capgen != tc_getgen(pps->capth)) 1902 if (pps->capgen == 0 || pps->capgen != 1903 atomic_load_acq_int(&pps->capth->th_generation)) 1885 1904 return; 1886 1905 … … 1932 1951 1933 1952 /* If the timecounter was wound up underneath us, bail out. */ 1934 if (pps->capgen != tc_getgen(pps->capth)) 1953 atomic_thread_fence_acq(); 1954 if (pps->capgen != pps->capth->th_generation) 1935 1955 return; 1936 1956
Note: See TracChangeset
for help on using the changeset viewer.