diff options
author | Dirk Engling <erdgeist@erdgeist.org> | 2021-04-19 03:25:18 +0200 |
---|---|---|
committer | Dirk Engling <erdgeist@erdgeist.org> | 2021-04-19 03:25:18 +0200 |
commit | 7c905ba729f78b71a77be198a5c9680ce3644367 (patch) | |
tree | eddc0ae0e8bf9bbca30e9bfe56724d2980879927 /ot_mutex.c | |
parent | 6411f1567f64248b0d145493c2e61004d2822623 (diff) |
De-bottleneck mutex access code
Diffstat (limited to 'ot_mutex.c')
-rw-r--r-- | ot_mutex.c | 76 |
1 files changed, 10 insertions, 66 deletions
@@ -25,65 +25,14 @@ | |||
25 | 25 | ||
26 | /* Our global all torrents list */ | 26 | /* Our global all torrents list */ |
27 | static ot_vector all_torrents[OT_BUCKET_COUNT]; | 27 | static ot_vector all_torrents[OT_BUCKET_COUNT]; |
28 | static pthread_mutex_t bucket_mutex[OT_BUCKET_COUNT]; | ||
28 | static size_t g_torrent_count; | 29 | static size_t g_torrent_count; |
29 | 30 | ||
30 | /* Bucket Magic */ | ||
31 | static int bucket_locklist[ OT_MAX_THREADS ]; | ||
32 | static int bucket_locklist_count = 0; | ||
33 | static pthread_mutex_t bucket_mutex; | ||
34 | static pthread_cond_t bucket_being_unlocked; | ||
35 | |||
36 | /* Self pipe from opentracker.c */ | 31 | /* Self pipe from opentracker.c */ |
37 | extern int g_self_pipe[2]; | 32 | extern int g_self_pipe[2]; |
38 | 33 | ||
39 | static int bucket_check( int bucket ) { | ||
40 | /* C should come with auto-i ;) */ | ||
41 | int i; | ||
42 | |||
43 | /* No more space to acquire lock to bucket -- should not happen */ | ||
44 | if( bucket_locklist_count == OT_MAX_THREADS ) { | ||
45 | fprintf( stderr, "More lock requests than mutexes. Consult source code.\n" ); | ||
46 | return -1; | ||
47 | } | ||
48 | |||
49 | /* See, if bucket is already locked */ | ||
50 | for( i=0; i<bucket_locklist_count; ++i ) | ||
51 | if( bucket_locklist[ i ] == bucket ) { | ||
52 | stats_issue_event( EVENT_BUCKET_LOCKED, 0, 0 ); | ||
53 | return -1; | ||
54 | } | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static void bucket_push( int bucket ) { | ||
60 | bucket_locklist[ bucket_locklist_count++ ] = bucket; | ||
61 | } | ||
62 | |||
63 | static void bucket_remove( int bucket ) { | ||
64 | int i = 0; | ||
65 | |||
66 | while( ( i < bucket_locklist_count ) && ( bucket_locklist[ i ] != bucket ) ) | ||
67 | ++i; | ||
68 | |||
69 | if( i == bucket_locklist_count ) { | ||
70 | fprintf( stderr, "Request to unlock bucket that was never locked. Consult source code.\n" ); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | for( ; i < bucket_locklist_count - 1; ++i ) | ||
75 | bucket_locklist[ i ] = bucket_locklist[ i + 1 ]; | ||
76 | |||
77 | --bucket_locklist_count; | ||
78 | } | ||
79 | |||
80 | /* Can block */ | ||
81 | ot_vector *mutex_bucket_lock( int bucket ) { | 34 | ot_vector *mutex_bucket_lock( int bucket ) { |
82 | pthread_mutex_lock( &bucket_mutex ); | 35 | pthread_mutex_lock(bucket_mutex + bucket ); |
83 | while( bucket_check( bucket ) ) | ||
84 | pthread_cond_wait( &bucket_being_unlocked, &bucket_mutex ); | ||
85 | bucket_push( bucket ); | ||
86 | pthread_mutex_unlock( &bucket_mutex ); | ||
87 | return all_torrents + bucket; | 36 | return all_torrents + bucket; |
88 | } | 37 | } |
89 | 38 | ||
@@ -92,11 +41,8 @@ ot_vector *mutex_bucket_lock_by_hash( ot_hash hash ) { | |||
92 | } | 41 | } |
93 | 42 | ||
94 | void mutex_bucket_unlock( int bucket, int delta_torrentcount ) { | 43 | void mutex_bucket_unlock( int bucket, int delta_torrentcount ) { |
95 | pthread_mutex_lock( &bucket_mutex ); | 44 | pthread_mutex_unlock(bucket_mutex + bucket); |
96 | bucket_remove( bucket ); | ||
97 | g_torrent_count += delta_torrentcount; | 45 | g_torrent_count += delta_torrentcount; |
98 | pthread_cond_broadcast( &bucket_being_unlocked ); | ||
99 | pthread_mutex_unlock( &bucket_mutex ); | ||
100 | } | 46 | } |
101 | 47 | ||
102 | void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) { | 48 | void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) { |
@@ -104,11 +50,7 @@ void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) { | |||
104 | } | 50 | } |
105 | 51 | ||
106 | size_t mutex_get_torrent_count( ) { | 52 | size_t mutex_get_torrent_count( ) { |
107 | size_t torrent_count; | 53 | return g_torrent_count; |
108 | pthread_mutex_lock( &bucket_mutex ); | ||
109 | torrent_count = g_torrent_count; | ||
110 | pthread_mutex_unlock( &bucket_mutex ); | ||
111 | return torrent_count; | ||
112 | } | 54 | } |
113 | 55 | ||
114 | /* TaskQueue Magic */ | 56 | /* TaskQueue Magic */ |
@@ -318,16 +260,18 @@ int64 mutex_workqueue_popresult( int *iovec_entries, struct iovec ** iovec ) { | |||
318 | } | 260 | } |
319 | 261 | ||
320 | void mutex_init( ) { | 262 | void mutex_init( ) { |
263 | int i; | ||
321 | pthread_mutex_init(&tasklist_mutex, NULL); | 264 | pthread_mutex_init(&tasklist_mutex, NULL); |
322 | pthread_cond_init (&tasklist_being_filled, NULL); | 265 | pthread_cond_init (&tasklist_being_filled, NULL); |
323 | pthread_mutex_init(&bucket_mutex, NULL); | 266 | for (i=0; i < OT_BUCKET_COUNT; ++i) |
324 | pthread_cond_init (&bucket_being_unlocked, NULL); | 267 | pthread_mutex_init(bucket_mutex + i, NULL); |
325 | byte_zero( all_torrents, sizeof( all_torrents ) ); | 268 | byte_zero( all_torrents, sizeof( all_torrents ) ); |
326 | } | 269 | } |
327 | 270 | ||
328 | void mutex_deinit( ) { | 271 | void mutex_deinit( ) { |
329 | pthread_mutex_destroy(&bucket_mutex); | 272 | int i; |
330 | pthread_cond_destroy(&bucket_being_unlocked); | 273 | for (i=0; i < OT_BUCKET_COUNT; ++i) |
274 | pthread_mutex_destroy(bucket_mutex + i); | ||
331 | pthread_mutex_destroy(&tasklist_mutex); | 275 | pthread_mutex_destroy(&tasklist_mutex); |
332 | pthread_cond_destroy(&tasklist_being_filled); | 276 | pthread_cond_destroy(&tasklist_being_filled); |
333 | byte_zero( all_torrents, sizeof( all_torrents ) ); | 277 | byte_zero( all_torrents, sizeof( all_torrents ) ); |