diff options
| author | erdgeist <> | 2007-11-15 03:35:03 +0000 |
|---|---|---|
| committer | erdgeist <> | 2007-11-15 03:35:03 +0000 |
| commit | d3963803caab5b1cb30bb58b271dede1b731bbd8 (patch) | |
| tree | 0ebdfeb1c427a230127032f689d53fab0c863f13 /ot_mutex.c | |
| parent | e476006019722606d0dcfc032224bad55010631a (diff) | |
tasklist code now tested in a multi threaded environment.
Diffstat (limited to 'ot_mutex.c')
| -rw-r--r-- | ot_mutex.c | 43 |
1 files changed, 37 insertions, 6 deletions
| @@ -14,6 +14,9 @@ | |||
| 14 | #include "trackerlogic.h" | 14 | #include "trackerlogic.h" |
| 15 | #include "ot_mutex.h" | 15 | #include "ot_mutex.h" |
| 16 | 16 | ||
| 17 | //#define MTX_DBG( STRING ) fprintf( stderr, STRING ) | ||
| 18 | #define MTX_DBG( STRING ) | ||
| 19 | |||
| 17 | /* Our global all torrents list */ | 20 | /* Our global all torrents list */ |
| 18 | static ot_vector all_torrents[OT_BUCKET_COUNT]; | 21 | static ot_vector all_torrents[OT_BUCKET_COUNT]; |
| 19 | 22 | ||
| @@ -114,14 +117,18 @@ int mutex_workqueue_pushtask( int64 socket, ot_tasktype tasktype ) { | |||
| 114 | struct ot_task ** tmptask, * task; | 117 | struct ot_task ** tmptask, * task; |
| 115 | 118 | ||
| 116 | /* Want exclusive access to tasklist */ | 119 | /* Want exclusive access to tasklist */ |
| 120 | MTX_DBG( "pushtask locks.\n" ); | ||
| 117 | pthread_mutex_lock( &tasklist_mutex ); | 121 | pthread_mutex_lock( &tasklist_mutex ); |
| 122 | MTX_DBG( "pushtask locked.\n" ); | ||
| 118 | 123 | ||
| 119 | task = malloc(sizeof( struct ot_task)); | 124 | task = malloc(sizeof( struct ot_task)); |
| 120 | if( !task ) { | 125 | if( !task ) { |
| 126 | MTX_DBG( "pushtask fail unlocks.\n" ); | ||
| 121 | pthread_mutex_unlock( &tasklist_mutex ); | 127 | pthread_mutex_unlock( &tasklist_mutex ); |
| 128 | MTX_DBG( "pushtask fail unlocked.\n" ); | ||
| 122 | return -1; | 129 | return -1; |
| 123 | } | 130 | } |
| 124 | 131 | ||
| 125 | /* Skip to end of list */ | 132 | /* Skip to end of list */ |
| 126 | tmptask = &tasklist; | 133 | tmptask = &tasklist; |
| 127 | while( *tmptask ) | 134 | while( *tmptask ) |
| @@ -136,8 +143,11 @@ int mutex_workqueue_pushtask( int64 socket, ot_tasktype tasktype ) { | |||
| 136 | task->next = 0; | 143 | task->next = 0; |
| 137 | 144 | ||
| 138 | /* Inform waiting workers and release lock */ | 145 | /* Inform waiting workers and release lock */ |
| 146 | MTX_DBG( "pushtask broadcasts.\n" ); | ||
| 139 | pthread_cond_broadcast( &tasklist_being_filled ); | 147 | pthread_cond_broadcast( &tasklist_being_filled ); |
| 148 | MTX_DBG( "pushtask broadcasted, mutex unlocks.\n" ); | ||
| 140 | pthread_mutex_unlock( &tasklist_mutex ); | 149 | pthread_mutex_unlock( &tasklist_mutex ); |
| 150 | MTX_DBG( "pushtask end mutex unlocked.\n" ); | ||
| 141 | return 0; | 151 | return 0; |
| 142 | } | 152 | } |
| 143 | 153 | ||
| @@ -145,7 +155,9 @@ void mutex_workqueue_canceltask( int64 socket ) { | |||
| 145 | struct ot_task ** task; | 155 | struct ot_task ** task; |
| 146 | 156 | ||
| 147 | /* Want exclusive access to tasklist */ | 157 | /* Want exclusive access to tasklist */ |
| 158 | MTX_DBG( "canceltask locks.\n" ); | ||
| 148 | pthread_mutex_lock( &tasklist_mutex ); | 159 | pthread_mutex_lock( &tasklist_mutex ); |
| 160 | MTX_DBG( "canceltask locked.\n" ); | ||
| 149 | 161 | ||
| 150 | task = &tasklist; | 162 | task = &tasklist; |
| 151 | while( *task && ( (*task)->socket != socket ) ) | 163 | while( *task && ( (*task)->socket != socket ) ) |
| @@ -165,7 +177,9 @@ void mutex_workqueue_canceltask( int64 socket ) { | |||
| 165 | } | 177 | } |
| 166 | 178 | ||
| 167 | /* Release lock */ | 179 | /* Release lock */ |
| 180 | MTX_DBG( "canceltask unlocks.\n" ); | ||
| 168 | pthread_mutex_unlock( &tasklist_mutex ); | 181 | pthread_mutex_unlock( &tasklist_mutex ); |
| 182 | MTX_DBG( "canceltask unlocked.\n" ); | ||
| 169 | } | 183 | } |
| 170 | 184 | ||
| 171 | ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { | 185 | ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { |
| @@ -173,7 +187,9 @@ ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { | |||
| 173 | ot_taskid taskid = 0; | 187 | ot_taskid taskid = 0; |
| 174 | 188 | ||
| 175 | /* Want exclusive access to tasklist */ | 189 | /* Want exclusive access to tasklist */ |
| 190 | MTX_DBG( "poptask mutex locks.\n" ); | ||
| 176 | pthread_mutex_lock( &tasklist_mutex ); | 191 | pthread_mutex_lock( &tasklist_mutex ); |
| 192 | MTX_DBG( "poptask mutex locked.\n" ); | ||
| 177 | 193 | ||
| 178 | while( !taskid ) { | 194 | while( !taskid ) { |
| 179 | /* Skip to the first unassigned task this worker wants to do */ | 195 | /* Skip to the first unassigned task this worker wants to do */ |
| @@ -185,15 +201,18 @@ ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { | |||
| 185 | and leave the loop */ | 201 | and leave the loop */ |
| 186 | if( task ) { | 202 | if( task ) { |
| 187 | task->taskid = taskid = ++next_free_taskid; | 203 | task->taskid = taskid = ++next_free_taskid; |
| 188 | break; | 204 | } else { |
| 205 | /* Wait until the next task is being fed */ | ||
| 206 | MTX_DBG( "poptask cond waits.\n" ); | ||
| 207 | pthread_cond_wait( &tasklist_being_filled, &tasklist_mutex ); | ||
| 208 | MTX_DBG( "poptask cond waited.\n" ); | ||
| 189 | } | 209 | } |
| 190 | |||
| 191 | /* Wait until the next task is being fed */ | ||
| 192 | pthread_cond_wait( &tasklist_being_filled, &tasklist_mutex ); | ||
| 193 | } | 210 | } |
| 194 | 211 | ||
| 195 | /* Release lock */ | 212 | /* Release lock */ |
| 213 | MTX_DBG( "poptask end mutex unlocks.\n" ); | ||
| 196 | pthread_mutex_unlock( &tasklist_mutex ); | 214 | pthread_mutex_unlock( &tasklist_mutex ); |
| 215 | MTX_DBG( "poptask end mutex unlocked.\n" ); | ||
| 197 | 216 | ||
| 198 | return taskid; | 217 | return taskid; |
| 199 | } | 218 | } |
| @@ -201,7 +220,9 @@ ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { | |||
| 201 | int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iovec *iovec ) { | 220 | int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iovec *iovec ) { |
| 202 | struct ot_task * task; | 221 | struct ot_task * task; |
| 203 | /* Want exclusive access to tasklist */ | 222 | /* Want exclusive access to tasklist */ |
| 223 | MTX_DBG( "pushresult locks.\n" ); | ||
| 204 | pthread_mutex_lock( &tasklist_mutex ); | 224 | pthread_mutex_lock( &tasklist_mutex ); |
| 225 | MTX_DBG( "pushresult locked.\n" ); | ||
| 205 | 226 | ||
| 206 | task = tasklist; | 227 | task = tasklist; |
| 207 | while( task && ( task->taskid != taskid ) ) | 228 | while( task && ( task->taskid != taskid ) ) |
| @@ -214,7 +235,9 @@ int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iove | |||
| 214 | } | 235 | } |
| 215 | 236 | ||
| 216 | /* Release lock */ | 237 | /* Release lock */ |
| 238 | MTX_DBG( "pushresult unlocks.\n" ); | ||
| 217 | pthread_mutex_unlock( &tasklist_mutex ); | 239 | pthread_mutex_unlock( &tasklist_mutex ); |
| 240 | MTX_DBG( "pushresult unlocked.\n" ); | ||
| 218 | 241 | ||
| 219 | /* Indicate whether the worker has to throw away results */ | 242 | /* Indicate whether the worker has to throw away results */ |
| 220 | return task ? 0 : -1; | 243 | return task ? 0 : -1; |
| @@ -225,11 +248,13 @@ int64 mutex_workqueue_popresult( int *iovec_entries, struct iovec ** iovec ) { | |||
| 225 | int64 socket = -1; | 248 | int64 socket = -1; |
| 226 | 249 | ||
| 227 | /* Want exclusive access to tasklist */ | 250 | /* Want exclusive access to tasklist */ |
| 251 | MTX_DBG( "popresult locks.\n" ); | ||
| 228 | pthread_mutex_lock( &tasklist_mutex ); | 252 | pthread_mutex_lock( &tasklist_mutex ); |
| 253 | MTX_DBG( "popresult locked.\n" ); | ||
| 229 | 254 | ||
| 230 | task = &tasklist; | 255 | task = &tasklist; |
| 231 | while( *task && ( (*task)->tasktype != OT_TASKTYPE_DONE ) ) | 256 | while( *task && ( (*task)->tasktype != OT_TASKTYPE_DONE ) ) |
| 232 | *task = (*task)->next; | 257 | task = &(*task)->next; |
| 233 | 258 | ||
| 234 | if( *task && ( (*task)->tasktype == OT_TASKTYPE_DONE ) ) { | 259 | if( *task && ( (*task)->tasktype == OT_TASKTYPE_DONE ) ) { |
| 235 | struct ot_task *ptask = *task; | 260 | struct ot_task *ptask = *task; |
| @@ -243,11 +268,15 @@ int64 mutex_workqueue_popresult( int *iovec_entries, struct iovec ** iovec ) { | |||
| 243 | } | 268 | } |
| 244 | 269 | ||
| 245 | /* Release lock */ | 270 | /* Release lock */ |
| 271 | MTX_DBG( "popresult unlocks.\n" ); | ||
| 246 | pthread_mutex_unlock( &tasklist_mutex ); | 272 | pthread_mutex_unlock( &tasklist_mutex ); |
| 273 | MTX_DBG( "popresult unlocked.\n" ); | ||
| 247 | return socket; | 274 | return socket; |
| 248 | } | 275 | } |
| 249 | 276 | ||
| 250 | void mutex_init( ) { | 277 | void mutex_init( ) { |
| 278 | pthread_mutex_init(&tasklist_mutex, NULL); | ||
| 279 | pthread_cond_init (&tasklist_being_filled, NULL); | ||
| 251 | pthread_mutex_init(&bucket_mutex, NULL); | 280 | pthread_mutex_init(&bucket_mutex, NULL); |
| 252 | pthread_cond_init (&bucket_being_unlocked, NULL); | 281 | pthread_cond_init (&bucket_being_unlocked, NULL); |
| 253 | byte_zero( all_torrents, sizeof( all_torrents ) ); | 282 | byte_zero( all_torrents, sizeof( all_torrents ) ); |
| @@ -256,5 +285,7 @@ void mutex_init( ) { | |||
| 256 | void mutex_deinit( ) { | 285 | void mutex_deinit( ) { |
| 257 | pthread_mutex_destroy(&bucket_mutex); | 286 | pthread_mutex_destroy(&bucket_mutex); |
| 258 | pthread_cond_destroy(&bucket_being_unlocked); | 287 | pthread_cond_destroy(&bucket_being_unlocked); |
| 288 | pthread_mutex_destroy(&tasklist_mutex); | ||
| 289 | pthread_cond_destroy(&tasklist_being_filled); | ||
| 259 | byte_zero( all_torrents, sizeof( all_torrents ) ); | 290 | byte_zero( all_torrents, sizeof( all_torrents ) ); |
| 260 | } | 291 | } |
