1#[derive(Copy, Clone, Debug, PartialEq, Eq)]
77 pub enum ICoWLockTypes
78 {
79 Atomic,
81
82 RwLock,
84 }
85
86impl fmt::Display for ICoWLockTypes
87{
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
89 {
90 match self
91 {
92 Self::Atomic =>
93 write!(f, "atomic"),
94 Self::RwLock =>
95 write!(f, "rwlock"),
96 }
97 }
98}
99
100#[derive(Copy, Clone, Debug, PartialEq, Eq)]
102pub enum ICoWError
103{
104 ExclusiveLockPending,
107
108 WouldBlock,
110}
111
112impl fmt::Display for ICoWError
113{
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
115 {
116 match self
117 {
118 Self::ExclusiveLockPending =>
119 write!(f, "already exlcusivly locked"),
120 Self::WouldBlock =>
121 write!(f, "cannot perform try operation due to blocking"),
122 }
123 }
124}
125
126extern crate crossbeam_utils;
127extern crate crossbeam_deque;
128
129#[cfg(all(target_has_atomic = "32", feature = "prefer_mutex"))]
131pub mod cow;
132
133#[cfg(any(not(target_has_atomic = "32"), not(feature = "prefer_mutex")))]
135pub mod cow_mutex;
136
137#[cfg(any(not(target_has_atomic = "32"), not(feature = "prefer_mutex")))]
138pub mod cow_refcell;
139
140use std::fmt;
141
142#[cfg(all(target_has_atomic = "32", feature = "prefer_mutex"))]
143pub use cow::{ICoW, ICoWRead, ICoWCopy, ICoWLock, ICoWWeak, ICoWWeakRead};
144
145#[cfg(any(not(target_has_atomic = "32"), not(feature = "prefer_mutex")))]
146pub use cow_mutex::{ICoW, ICoWRead, ICoWCopy, ICoWLock, ICoWWeak, ICoWWeakRead};
147
148#[cfg(all(not(target_has_atomic = "32"), feature = "prefer_mutex"))]
149compile_error!("target CPU does not support 'target_has_atomic'");
150
151pub trait ICowType
152{
153 fn get_lock_type() -> ICoWLockTypes;
154}
155
156#[cfg(test)]
157mod test
158{
159 use std::{sync::{LazyLock, mpsc}, thread, time::{Duration, Instant}};
160
161 use super::*;
162
163
164
165
166 #[test]
167 fn test_3()
168 {
169 #[derive(Debug, Clone)]
170 struct Test { s: String }
171
172 let icow = ICoW::new(Test{ s: "test".into() });
173
174 for _ in 0..10
175 {
176 let s = Instant::now();
177
178 let read0 = icow.read();
179
180 let e = s.elapsed();
181
182 println!("{:?}", e);
183 }
184
185 }
186
187 #[test]
188 fn test_33()
189 {
190 #[derive(Debug, Clone)]
191 struct Test { s: String };
192
193 let icow = ICoW::new(Test{ s: "test".into() });
194
195 let write_ex = icow.try_clone_copy_exclusivly().unwrap();
196
197 {
198 let write_ex_err = icow.try_clone_copy_exclusivly();
199 assert_eq!(write_ex_err.is_none(), true);
200 }
201
202 {
203 let write_ex_err = icow.try_clone_copy();
204 assert_eq!(write_ex_err.is_none(), true);
205 }
206 {
207 let read1 = icow.try_read();
208 assert_eq!(read1.is_none(), true);
209 }
210
211 drop(write_ex);
212
213 drop(icow);
214
215 }
216
217 #[test]
218 fn test_4()
219 {
220 #[derive(Debug, Clone)]
221 struct Test { s: u32 }
222
223 let icow = ICoW::new(Test{ s: 1 });
224
225 let read0 = icow.read();
226 let read1 = icow.read();
227
228 let mut excl_write = icow.try_clone_copy_exclusivly().unwrap();
229
230 excl_write.s = 5;
231
232
233 excl_write.commit();
234
235 assert_eq!(read0.s, 1);
236
237 let read3 = icow.read();
238 assert_eq!(read3.s, 5);
239
240 let mut writing = icow.try_clone_copy().unwrap();
241 writing.s = 4;
242
243 writing.commit().unwrap();
244
245 assert_eq!(read0.s, 1);
246 assert_eq!(read3.s, 5);
247
248 let read4 = icow.read();
249 assert_eq!(read4.s, 4);
250 }
251
252 #[test]
253 fn test_parking_lot_reader_wakeup()
254 {
255 #[derive(Debug, Clone)]
256 struct Test { s: u32 }
257
258 let icow = ICoW::new(Test{ s: 1 });
259
260 let read0 = icow.read();
261 let read2 = icow.read();
262
263 let c_icow = icow.clone();
264 let (se, rc) = mpsc::channel::<()>();
265 let handler0 =
266 std::thread::spawn(move ||
267 {
268 let mut lock0 = c_icow.try_clone_copy_exclusivly().unwrap();
269
270 se.send(()).unwrap();
271
272 lock0.s = 5;
273
274 std::thread::sleep(Duration::from_secs(2));
275
276 lock0.commit();
277 }
278 );
279
280 rc.recv().unwrap();
281
282 let s = Instant::now();
283
284 let read1 = icow.read();
285
286 let e = s.elapsed();
287
288 println!("thread wait: {:?}", e);
289
290 assert_eq!(e.as_secs(), 2);
291
292 handler0.join().unwrap();
293
294 drop(read0);
295 drop(read1);
296 drop(read2);
297 }
298
299 #[test]
300 fn text_9_exclu_lock_pend()
301 {
302 #[derive(Debug, Clone)]
303 struct Test { s: u32 }
304
305 let icow = ICoW::new(Test{ s: 1 });
306
307 let mut write0 = icow.clone_copy();
308 write0.s = 1222;
309
310 let c_icow = icow.clone();
311 let (se, rc) = mpsc::channel::<()>();
312 let handler0 =
313 std::thread::spawn(move ||
314 {
315 let mut lock0 =
316 loop
317 {
318 let res = c_icow.try_clone_copy_exclusivly();
319
320 if res.is_none() == true
321 {
322 continue;
323 }
324
325 break res.unwrap();
326 };
327
328 se.send(()).unwrap();
329
330 lock0.s = 5;
331
332 std::thread::sleep(Duration::from_secs(1));
333
334 lock0.commit();
335 }
336 );
337
338
339 rc.recv().unwrap();
340
341 let s = Instant::now();
342
343 let commit_res = write0.commit();
344 assert_eq!(commit_res.is_err(), true);
345 assert_eq!(commit_res.as_ref().err().unwrap().0, ICoWError::ExclusiveLockPending);
346 write0 = commit_res.err().unwrap().1;
347
348 write0.commit_blocking(true).unwrap();
349
350 let e = s.elapsed();
351
352 println!("thread wait: {:?}", e);
353
354 assert_eq!(e.as_secs(), 1);
355
356 handler0.join().unwrap();
357
358 return;
359 }
360
361 #[test]
362 fn test_5()
363 {
364 #[derive(Debug, Clone)]
365 struct Test { s: u32 }
366
367 let icow = ICoW::new(Test{ s: 1 });
368
369 let read0 = icow.read();
370 let read2 = icow.read();
371
372 let c_icow = icow.clone();
373
374 let (se, rc) = mpsc::channel::<()>();
375 let handler0 =
376 std::thread::spawn(move ||
377 {
378 let mut lock0 = c_icow.try_clone_copy_exclusivly().unwrap();
379
380 se.send(()).unwrap();
381
382 lock0.s = 5;
383
384 std::thread::sleep(Duration::from_micros(2));
385
386 lock0.commit();
387 }
388 );
389
390 rc.recv().unwrap();
391
392 let s = Instant::now();
393
394 let read1 = icow.read();
395
396 let e = s.elapsed();
397
398 println!("{:?}", e);
399
400
401 assert_eq!(read1.s, 5);
402 assert_eq!(read0.s, 1);
403
404 handler0.join().unwrap();
405
406 let weak0 = read0.weak();
407 let weak1 = read1.weak();
408
409 drop(read0);
410 drop(read1);
411
412 assert_eq!(weak0.upgrade().is_some(), true);
413 assert_eq!(weak1.upgrade().is_some(), true);
414
415 drop(read2);
416 assert_eq!(weak0.upgrade().is_none(), true);
417 assert_eq!(weak1.upgrade().is_some(), true);
418 }
419
420 #[test]
421 fn test_5_read_lock()
422 {
423 #[derive(Debug, Clone)]
424 struct Test { s: u32 }
425
426 let icow = ICoW::new(Test{ s: 1 });
427
428 let c_icow = icow.clone();
429
430 let (se, rc) = mpsc::channel::<()>();
431 let (se2, rc2) = mpsc::channel::<()>();
432 let handler0 =
433 std::thread::spawn(move ||
434 {
435 rc2.recv().unwrap();
436
437 let mut lock0 =
438 loop
439 {
440 let res = c_icow.try_clone_copy_exclusivly();
441
442 if res.is_none() == true
443 {
444 continue;
445 }
446
447 break res.unwrap();
448 };
449
450 se.send(()).unwrap();
451
452 lock0.s = 5;
453
454 lock0.commit();
455 }
456 );
457
458 let mut reads = Vec::<ICoWRead<'_, Test>>::with_capacity(20000);
459 let mut sent = false;
460
461 let s = Instant::now();
462
463 for i in 0..10000
464 {
465 let read0 = icow.read();
466 if read0.s == 5
467 {
468 println!("break at {}", i);
469 break;
470 }
471
472 reads.push(read0);
473
474 if sent == false
475 {
476 se2.send(());
477 sent = true;
478 }
479 }
480
481 let e = s.elapsed();
482
483 println!("{:?}", e);
484
485 assert_eq!(reads[0].s, 1);
486
487 handler0.join().unwrap();
488 }
489
490 #[test]
491 fn test_6()
492 {
493 #[derive(Debug, Clone)]
494 struct Test { s: u32 }
495
496 let icow = ICoW::new(Test{ s: 1 });
497
498 let read0 = icow.read();
499 let read2 = icow.read();
500
501 let c_icow = icow.clone();
502
503 let (se, rc) = mpsc::channel::<()>();
504 let handler0 =
505 std::thread::spawn(move ||
506 {
507 let read2 = c_icow.read();
508
509 let mut lock0 = c_icow.try_clone_copy_exclusivly().unwrap();
510
511 se.send(()).unwrap();
512
513 lock0.s = 5;
514
515 std::thread::sleep(Duration::from_nanos(50));
516 lock0.commit();
517
518 let read3 = c_icow.read();
519
520 assert_eq!(read2.s, 1);
521 assert_eq!(read3.s, 5);
522 }
523 );
524
525 rc.recv().unwrap();
526
527 for _ in 0..100000000
528 {
529 let read1 = icow.read();
530
531 if read1.s == 1
532 {
533 continue;
534 }
535 else
536 {
537 break;
538 }
539 }
540
541 let read1 = icow.read();
542 assert_eq!(read1.item.s, 5);
543
544 handler0.join().unwrap();
545
546 return;
547 }
548
549 #[test]
550 fn test_6_drop()
551 {
552 #[derive(Debug, Clone)]
553 struct Test { s: u32 }
554
555 let icow = ICoW::new(Test{ s: 1 });
556
557 let read0 = icow.read();
558 let read2 = icow.read();
559
560 let c_icow = icow.clone();
561
562 let (se, rc) = mpsc::channel::<()>();
563 let handler0 =
564 std::thread::spawn(move ||
565 {
566 let read2 = c_icow.read();
567
568 let mut lock0 = c_icow.try_clone_copy_exclusivly().unwrap();
569
570 rc.recv().unwrap();
571
572 lock0.s = 5;
573
574 std::thread::sleep(Duration::from_millis(1500));
575 lock0.commit();
576
577 let read3 = c_icow.read();
578
579 assert_eq!(read2.s, 1);
580 assert_eq!(read3.s, 5);
581 }
582 );
583
584 drop(read0);
585 let r2 = read2.clone_copy_into_inner();
586
587 se.send(()).unwrap();
588
589 drop(icow);
590
591 assert_eq!(r2.s, 1);
592
593 handler0.join().unwrap();
594
595 return;
596 }
597
598
599 #[test]
600 fn test_7()
601 {
602 #[derive(Debug, Clone)]
603 struct TestStruct { s: u32 }
604
605 impl TestStruct
606 {
607 fn new(s: u32) -> Self
608 {
609 return Self{ s: s };
610 }
611 }
612
613 static VAL: LazyLock<ICoW<TestStruct>> =
614 LazyLock::new(|| ICoW::new(TestStruct::new(1)));
615
616
617
618
619 let borrow1 = VAL.read();
620 assert_eq!(borrow1.item.s, 1);
621
622 let (mpsc_send, mpsc_rcv) = mpsc::channel::<u64>();
623 let (mpsc_send2, mpsc_rcv2) = mpsc::channel::<u64>();
624
625 let thread1 =
626 std::thread::spawn(move ||
627 {
628 for _ in 0..1000
629 {
630 let _ = mpsc_rcv2.recv();
631 let borrow1 = VAL.read();
632
633 let mut transaction = VAL.try_clone_copy_exclusivly().unwrap();
634
635 transaction.s = 5;
636
637
638
639 std::thread::sleep(Duration::from_nanos(1001));
640 transaction.commit();
641 let borrow2 = VAL.read();
642
643
644 assert_eq!(borrow1.item.s, 1);
645
646 assert_eq!(borrow2.item.s, 5);
647
648 let _ = mpsc_send.send(1);
649 }
650 }
651 );
652
653
654
655 for x in 0..1000
656 {
657 println!("{}", x);
658 mpsc_send2.send(1).unwrap();
659 let _ = mpsc_rcv.recv();
660
661 let borrow1 = VAL.read();
662 assert_eq!(borrow1.s, 5);
663
664 let mut transaction = VAL.try_clone_copy_exclusivly().unwrap();
665 transaction.s = 1;
666 transaction.commit();
667
668 let borrow1 = VAL.read();
669 assert_eq!(borrow1.s, 1);
670
671 }
672
673
674
675 thread1.join().unwrap();
676
677
678 }
679
680
681 #[test]
682 fn test_8()
683 {
684 #[derive(Debug, Clone)]
685 struct Test { s: u32 }
686
687 let icow = ICoW::new(Test{ s: 1 });
688
689 for _ in 0..20
690 {
691 let read0 = icow.read();
692 let read2 = icow.read();
693
694 let c_icow = icow.clone();
695
696 let handler0 =
698 std::thread::spawn(move ||
699 {
700 let read2 = c_icow.read();
701
702 let mut lock0 = c_icow.clone_copy();
703
704 lock0.s = 5;
707
708 std::thread::sleep(Duration::from_micros(1));
709 lock0.commit_blocking(false).unwrap();
710
711 let read3 = c_icow.read();
712
713 assert_eq!(read2.s, 1);
714 assert_eq!(read3.s, 5);
715 }
716 );
717
718 for i in 0..1000000000
721 {
722 let read1 = icow.read();
723
724 if read1.s == 1
725 {
726 continue;
727 }
728 else
729 {
730 println!("{}", i);
731 break;
732 }
733 }
734
735 let read1 = icow.read();
736 assert_eq!(read1.s, 5);
737
738 handler0.join().unwrap();
739
740 let mut lock0 = icow.try_clone_copy().unwrap();
741 lock0.s = 1;
742 lock0.commit_blocking(false).unwrap();
743 }
744
745 return;
746 }
747
748 #[test]
749 fn test_9()
750 {
751 #[derive(Debug, Clone)]
752 struct Test { s: u32 }
753
754 let icow = ICoW::new(Test{ s: 1 });
755
756 let weak_reader = icow.reader();
757
758 let weak_r0 = weak_reader.aquire().unwrap();
759
760 assert_eq!(weak_r0.s, 1);
761
762 drop(weak_r0);
763
764 let mut copy1 = icow.clone_copy();
765 copy1.s = 8;
766 copy1.commit_blocking(true).unwrap();
767
768 let weak_r0 = weak_reader.aquire().unwrap();
769
770 assert_eq!(weak_r0.s, 8);
771
772 drop(weak_r0);
773
774 drop(icow);
777
778 let weak_r0 = weak_reader.aquire();
779 assert_eq!(weak_r0.is_none(), true);
780
781 }
782
783 #[test]
784 fn test_10()
785 {
786 #[derive(Debug, Clone)]
787 struct Test { s: u32 }
788
789 let icow = ICoW::new(Test{ s: 1 });
790
791 let weak_reader = icow.reader();
792
793 let (tx, rx) = mpsc::channel::<()>();
794 let (tx2, rx2) = mpsc::channel::<()>();
795
796 let thread_hndl =
797 thread::spawn(move ||
798 {
799 let weak_r0 = weak_reader.aquire().unwrap();
800
801 assert_eq!(weak_r0.s, 1);
802
803 drop(weak_r0);
804
805 tx.send(()).unwrap();
806
807 let _ = rx2.recv().unwrap();
809
810 let weak_r0 = weak_reader.aquire().unwrap();
811
812 assert_eq!(weak_r0.item_updated(), true);
813 assert_eq!(weak_r0.s, 8);
814
815 drop(weak_r0);
816
817 tx.send(()).unwrap();
818 let _ = rx2.recv().unwrap();
820
821 let weak_r0 = weak_reader.aquire();
823 assert_eq!(weak_r0.is_none(), true);
824 }
825 );
826
827 let _ = rx.recv().unwrap();
828
829 let mut copy1 = icow.clone_copy();
830 copy1.s = 8;
831 copy1.commit_blocking(true).unwrap();
832
833 tx2.send(()).unwrap();
834 let _ = rx.recv().unwrap();
835
836 drop(icow);
839
840 tx2.send(()).unwrap();
841
842 thread_hndl.join().unwrap();
843
844 return;
845
846 }
847}