![]() |
От: |
remark
|
http://www.1024cores.net/ |
Дата: | 19.08.08 23:57 | ||
Оценка: |
1:#include "stdafx.h"
2:#include "../../relacy/relacy_std.hpp"
3:
4:class business_logic
5:{
6:public:
7: typedef unsigned account_id_t;
8: typedef double balance_t;
9:
10: business_logic()
11: {
12: rl::pthread_rwlock_init(&accounts_guard, 0, $);
13: }
14:
15: ~business_logic()
16: {
17: rl::pthread_rwlock_destroy(&accounts_guard, $);
18: }
19:
20: bool add_account(account_id_t acc_id, balance_t balance)
21: {
22: rl::pthread_rwlock_wrlock(&accounts_guard, $);
23: if (accounts.find(acc_id) != accounts.end())
24: {
25: rl::pthread_rwlock_unlock(&accounts_guard, $);
26: return false;
27: }
28: accounts[acc_id].balance = balance;
29: rl::pthread_rwlock_unlock(&accounts_guard, $);
30: return true;
31: }
32:
33: bool transfer_balance(account_id_t acc_id1, account_id_t acc_id2, balance_t amount)
34: {
35: //if (acc_id1 == acc_id2)
36: // return true;
37: rl::pthread_rwlock_rdlock(&accounts_guard, $);
38: if (accounts.find(acc_id1) == accounts.end()
39: || accounts.find(acc_id2) == accounts.end())
40: {
41: rl::pthread_rwlock_unlock(&accounts_guard, $);
42: return false;
43: }
44: account_info& acc1 = accounts[acc_id1];
45: account_info& acc2 = accounts[acc_id2];
46: //if (acc_id1 > acc_id2)
47: {
48: rl::pthread_mutex_lock(&acc1.mtx, $);
49: rl::pthread_mutex_lock(&acc2.mtx, $);
50: }
51: //else
52: //{
53: // rl::pthread_mutex_lock(&acc2.mtx, $);
54: // rl::pthread_mutex_lock(&acc1.mtx, $);
55: //}
56: rl::pthread_rwlock_unlock(&accounts_guard, $);
57:
58: acc1.balance -= amount;
59: acc2.balance += amount;
60:
61: rl::pthread_mutex_unlock(&acc1.mtx, $);
62: rl::pthread_mutex_unlock(&acc2.mtx, $);
63: return true;
64: }
65:
66:private:
67: struct account_info
68: {
69: balance_t balance;
70: rl::pthread_mutex_t mtx;
71:
72: account_info()
73: : balance()
74: {
75: rl::pthread_mutex_init(&mtx, 0, $);
76: }
77:
78: account_info(account_info const& acc)
79: : balance(acc.balance)
80: {
81: rl::pthread_mutex_init(&mtx, 0, $);
82: }
83:
84: ~account_info()
85: {
86: rl::pthread_mutex_destroy(&mtx, $);
87: }
88: };
89:
90: typedef std::map<account_id_t, account_info> account_map_t;
91: account_map_t accounts;
92: rl::pthread_rwlock_t accounts_guard;
93:};
94:
95:struct business_logic_test : rl::test_suite<business_logic_test, 2>
96:{
97: business_logic bl;
98:
99: static size_t const account_count = 4;
100:
101: void before()
102: {
103: for (size_t i = 0; i != account_count; ++i)
104: {
105: bool rv = bl.add_account(i, i * 10.0);
106: RL_ASSERT(rv);
107: }
108: }
109:
110: void thread(unsigned /*index*/)
111: {
112: business_logic::account_id_t acc1 = rl::rand(account_count);
113: business_logic::account_id_t acc2 = rl::rand(account_count);
114: bool rv = bl.transfer_balance(acc1, acc2, 1.0);
115: RL_ASSERT(rv);
116: }
117:};
118:
119:int main()
120:{
121: rl::simulate<business_logic_test>();
122:}
123:
struct business_logic_test
RECURSION ON NON-RECURSIVE MUTEX
iteration: 3
execution history:
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [0] 1: [CTOR BEGIN]
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [1] 1: [CTOR END]
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [2] 1: [BEFORE BEGIN]
..\peterson.cpp(22) : [3] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [4] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [5] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [6] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [7] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [8] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [9] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [10] 1: <00358008> mutex: exclusive unlock
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [11] 1: [BEFORE END]
..\peterson.cpp(37) : [12] 0: <00358008> mutex: shared lock
..\peterson.cpp(37) : [13] 1: <00358008> mutex: shared lock
..\peterson.cpp(48) : [14] 0: <00357E88> mutex: exclusive lock
..\peterson.cpp(49) : [15] 0: <00357F48> mutex: exclusive lock
..\peterson.cpp(56) : [16] 0: <00358008> mutex: shared unlock
..\peterson.cpp(48) : [17] 1: <00357F08> mutex: exclusive lock
..\peterson.cpp(49) : [18] 1: <00357F08> mutex: recursive exclusive lock
..\peterson.cpp(49) : [19] 1: RECURSION ON NON-RECURSIVE MUTEX
thread 0:
..\peterson.cpp(37) : [12] 0: <00358008> mutex: shared lock
..\peterson.cpp(48) : [14] 0: <00357E88> mutex: exclusive lock
..\peterson.cpp(49) : [15] 0: <00357F48> mutex: exclusive lock
..\peterson.cpp(56) : [16] 0: <00358008> mutex: shared unlock
thread 1:
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [0] 1: [CTOR BEGIN]
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [1] 1: [CTOR END]
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [2] 1: [BEFORE BEGIN]
..\peterson.cpp(22) : [3] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [4] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [5] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [6] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [7] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [8] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [9] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [10] 1: <00358008> mutex: exclusive unlock
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [11] 1: [BEFORE END]
..\peterson.cpp(37) : [13] 1: <00358008> mutex: shared lock
..\peterson.cpp(48) : [17] 1: <00357F08> mutex: exclusive lock
..\peterson.cpp(49) : [18] 1: <00357F08> mutex: recursive exclusive lock
..\peterson.cpp(49) : [19] 1: RECURSION ON NON-RECURSIVE MUTEX
35: if (acc_id1 == acc_id2)
36: return true;
struct business_logic_test
DEADLOCK (deadlock detected)
iteration: 135
execution history:
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [0] 1: [CTOR BEGIN]
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [1] 1: [CTOR END]
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [2] 1: [BEFORE BEGIN]
..\peterson.cpp(22) : [3] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [4] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [5] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [6] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [7] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [8] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [9] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [10] 1: <00358008> mutex: exclusive unlock
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [11] 1: [BEFORE END]
..\peterson.cpp(37) : [12] 1: <00358008> mutex: shared lock
..\peterson.cpp(37) : [13] 0: <00358008> mutex: shared lock
..\peterson.cpp(48) : [14] 1: <00357EC8> mutex: exclusive lock
..\peterson.cpp(48) : [15] 0: <00357E88> mutex: exclusive lock
..\peterson.cpp(49) : [16] 1: <00357E88> mutex: blocking
..\peterson.cpp(49) : [17] 1: blocking current thread
..\peterson.cpp(49) : [18] 0: <00357EC8> mutex: blocking
..\peterson.cpp(49) : [19] 0: blocking current thread
..\peterson.cpp(49) : [20] 0: DEADLOCK (deadlock detected)
thread 0:
..\peterson.cpp(37) : [13] 0: <00358008> mutex: shared lock
..\peterson.cpp(48) : [15] 0: <00357E88> mutex: exclusive lock
..\peterson.cpp(49) : [18] 0: <00357EC8> mutex: blocking
..\peterson.cpp(49) : [19] 0: blocking current thread
..\peterson.cpp(49) : [20] 0: DEADLOCK (deadlock detected)
thread 1:
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [0] 1: [CTOR BEGIN]
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [1] 1: [CTOR END]
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [2] 1: [BEFORE BEGIN]
..\peterson.cpp(22) : [3] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [4] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [5] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [6] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [7] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [8] 1: <00358008> mutex: exclusive unlock
..\peterson.cpp(22) : [9] 1: <00358008> mutex: exclusive lock
..\peterson.cpp(29) : [10] 1: <00358008> mutex: exclusive unlock
c:\root\relacy_1_0\rrd\relacy\context.hpp(385) : [11] 1: [BEFORE END]
..\peterson.cpp(37) : [12] 1: <00358008> mutex: shared lock
..\peterson.cpp(48) : [14] 1: <00357EC8> mutex: exclusive lock
..\peterson.cpp(49) : [16] 1: <00357E88> mutex: blocking
..\peterson.cpp(49) : [17] 1: blocking current thread
46: if (acc_id1 > acc_id2)
47: {
48: rl::pthread_mutex_lock(&acc1.mtx, $);
49: rl::pthread_mutex_lock(&acc2.mtx, $);
50: }
51: else
52: {
53: rl::pthread_mutex_lock(&acc2.mtx, $);
54: rl::pthread_mutex_lock(&acc1.mtx, $);
55: }