summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2021-04-19 03:25:18 +0200
committerDirk Engling <erdgeist@erdgeist.org>2021-04-19 03:25:18 +0200
commit7c905ba729f78b71a77be198a5c9680ce3644367 (patch)
treeeddc0ae0e8bf9bbca30e9bfe56724d2980879927
parent6411f1567f64248b0d145493c2e61004d2822623 (diff)
De-bottleneck mutex access code
-rw-r--r--ot_mutex.c76
1 files changed, 10 insertions, 66 deletions
diff --git a/ot_mutex.c b/ot_mutex.c
index 772d936..9d87d0f 100644
--- a/ot_mutex.c
+++ b/ot_mutex.c
@@ -25,65 +25,14 @@
25 25
26/* Our global all torrents list */ 26/* Our global all torrents list */
27static ot_vector all_torrents[OT_BUCKET_COUNT]; 27static ot_vector all_torrents[OT_BUCKET_COUNT];
28static pthread_mutex_t bucket_mutex[OT_BUCKET_COUNT];
28static size_t g_torrent_count; 29static size_t g_torrent_count;
29 30
30/* Bucket Magic */
31static int bucket_locklist[ OT_MAX_THREADS ];
32static int bucket_locklist_count = 0;
33static pthread_mutex_t bucket_mutex;
34static pthread_cond_t bucket_being_unlocked;
35
36/* Self pipe from opentracker.c */ 31/* Self pipe from opentracker.c */
37extern int g_self_pipe[2]; 32extern int g_self_pipe[2];
38 33
39static 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
59static void bucket_push( int bucket ) {
60 bucket_locklist[ bucket_locklist_count++ ] = bucket;
61}
62
63static 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 */
81ot_vector *mutex_bucket_lock( int bucket ) { 34ot_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
94void mutex_bucket_unlock( int bucket, int delta_torrentcount ) { 43void 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
102void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) { 48void 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
106size_t mutex_get_torrent_count( ) { 52size_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
320void mutex_init( ) { 262void 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
328void mutex_deinit( ) { 271void 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 ) );