Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/fibril_synch.c

    rd161715 r84b7384  
    3636#include <fibril.h>
    3737#include <async.h>
     38#include <async_priv.h>
    3839#include <adt/list.h>
    3940#include <futex.h>
     
    4344#include <stacktrace.h>
    4445#include <stdlib.h>
    45 #include <stdio.h>
    46 #include "private/async.h"
    4746
    4847static void optimize_execution_power(void)
     
    5655         */
    5756        if (atomic_get(&threads_in_ipc_wait) > 0)
    58                 async_poke();
     57                ipc_poke();
     58}
     59
     60static bool check_for_deadlock(fibril_owner_info_t *oi)
     61{
     62        while (oi && oi->owned_by) {
     63                if (oi->owned_by == (fibril_t *) fibril_get_id())
     64                        return true;
     65                oi = oi->owned_by->waits_for;
     66        }
     67
     68        return false;
    5969}
    6070
     
    7989                oi = oi->owned_by->waits_for;
    8090        }
    81 }
    82 
    83 
    84 static void check_for_deadlock(fibril_owner_info_t *oi)
    85 {
    86         while (oi && oi->owned_by) {
    87                 if (oi->owned_by == (fibril_t *) fibril_get_id()) {
    88                         print_deadlock(oi);
    89                         abort();
    90                 }
    91                 oi = oi->owned_by->waits_for;
    92         }
    93 }
    94 
     91
     92        abort();
     93}
    9594
    9695void fibril_mutex_initialize(fibril_mutex_t *fm)
     
    104103{
    105104        fibril_t *f = (fibril_t *) fibril_get_id();
    106 
    107         if (fibril_get_sercount() != 0)
    108                 abort();
    109105
    110106        futex_down(&async_futex);
     
    117113                link_initialize(&wdata.wu_event.link);
    118114                list_append(&wdata.wu_event.link, &fm->waiters);
    119                 check_for_deadlock(&fm->oi);
     115
     116                if (check_for_deadlock(&fm->oi))
     117                        print_deadlock(&fm->oi);
    120118                f->waits_for = &fm->oi;
     119
    121120                fibril_switch(FIBRIL_TO_MANAGER);
    122121        } else {
     
    143142static void _fibril_mutex_unlock_unsafe(fibril_mutex_t *fm)
    144143{
     144        assert(fm->counter <= 0);
    145145        if (fm->counter++ < 0) {
    146146                link_t *tmp;
     
    168168void fibril_mutex_unlock(fibril_mutex_t *fm)
    169169{
    170         assert(fibril_mutex_is_locked(fm));
    171170        futex_down(&async_futex);
    172171        _fibril_mutex_unlock_unsafe(fm);
    173172        futex_up(&async_futex);
    174 }
    175 
    176 bool fibril_mutex_is_locked(fibril_mutex_t *fm)
    177 {
    178         bool locked = false;
    179        
    180         futex_down(&async_futex);
    181         if (fm->counter <= 0)
    182                 locked = true;
    183         futex_up(&async_futex);
    184        
    185         return locked;
    186173}
    187174
     
    196183void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
    197184{
    198         fibril_t *f = (fibril_t *) fibril_get_id();
    199        
    200         if (fibril_get_sercount() != 0)
    201                 abort();
    202 
    203185        futex_down(&async_futex);
    204186        if (frw->writers) {
     187                fibril_t *f = (fibril_t *) fibril_get_id();
    205188                awaiter_t wdata;
    206189
     
    211194                f->flags &= ~FIBRIL_WRITER;
    212195                list_append(&wdata.wu_event.link, &frw->waiters);
    213                 check_for_deadlock(&frw->oi);
    214                 f->waits_for = &frw->oi;
    215196                fibril_switch(FIBRIL_TO_MANAGER);
    216197        } else {
    217                 /* Consider the first reader the owner. */
    218                 if (frw->readers++ == 0)
    219                         frw->oi.owned_by = f;
     198                frw->readers++;
    220199                futex_up(&async_futex);
    221200        }
     
    224203void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
    225204{
    226         fibril_t *f = (fibril_t *) fibril_get_id();
    227        
    228         if (fibril_get_sercount() != 0)
    229                 abort();
    230 
    231205        futex_down(&async_futex);
    232206        if (frw->writers || frw->readers) {
     207                fibril_t *f = (fibril_t *) fibril_get_id();
    233208                awaiter_t wdata;
    234209
     
    239214                f->flags |= FIBRIL_WRITER;
    240215                list_append(&wdata.wu_event.link, &frw->waiters);
    241                 check_for_deadlock(&frw->oi);
    242                 f->waits_for = &frw->oi;
    243216                fibril_switch(FIBRIL_TO_MANAGER);
    244217        } else {
    245                 frw->oi.owned_by = f;
    246218                frw->writers++;
    247219                futex_up(&async_futex);
     
    252224{
    253225        futex_down(&async_futex);
     226        assert(frw->readers || (frw->writers == 1));
    254227        if (frw->readers) {
    255                 if (--frw->readers) {
    256                         if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) {
    257                                 /*
    258                                  * If this reader firbril was considered the
    259                                  * owner of this rwlock, clear the ownership
    260                                  * information even if there are still more
    261                                  * readers.
    262                                  *
    263                                  * This is the limitation of the detection
    264                                  * mechanism rooted in the fact that tracking
    265                                  * all readers would require dynamically
    266                                  * allocated memory for keeping linkage info.
    267                                  */
    268                                 frw->oi.owned_by = NULL;
    269                         }
     228                if (--frw->readers)
    270229                        goto out;
    271                 }
    272230        } else {
    273231                frw->writers--;
     
    275233       
    276234        assert(!frw->readers && !frw->writers);
    277        
    278         frw->oi.owned_by = NULL;
    279235       
    280236        while (!list_empty(&frw->waiters)) {
     
    285241                wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
    286242                f = (fibril_t *) wdp->fid;
    287                
    288                 f->waits_for = NULL;
    289243               
    290244                if (f->flags & FIBRIL_WRITER) {
     
    296250                        fibril_add_ready(wdp->fid);
    297251                        frw->writers++;
    298                         frw->oi.owned_by = f;
    299252                        optimize_execution_power();
    300253                        break;
     
    304257                        list_remove(&wdp->wu_event.link);
    305258                        fibril_add_ready(wdp->fid);
    306                         if (frw->readers++ == 0) {
    307                                 /* Consider the first reader the owner. */
    308                                 frw->oi.owned_by = f;
    309                         }
     259                        frw->readers++;
    310260                        optimize_execution_power();
    311261                }
     
    317267void fibril_rwlock_read_unlock(fibril_rwlock_t *frw)
    318268{
    319         assert(fibril_rwlock_is_read_locked(frw));
    320269        _fibril_rwlock_common_unlock(frw);
    321270}
     
    323272void fibril_rwlock_write_unlock(fibril_rwlock_t *frw)
    324273{
    325         assert(fibril_rwlock_is_write_locked(frw));
    326274        _fibril_rwlock_common_unlock(frw);
    327 }
    328 
    329 bool fibril_rwlock_is_read_locked(fibril_rwlock_t *frw)
    330 {
    331         bool locked = false;
    332 
    333         futex_down(&async_futex);
    334         if (frw->readers)
    335                 locked = true;
    336         futex_up(&async_futex);
    337 
    338         return locked;
    339 }
    340 
    341 bool fibril_rwlock_is_write_locked(fibril_rwlock_t *frw)
    342 {
    343         bool locked = false;
    344 
    345         futex_down(&async_futex);
    346         if (frw->writers) {
    347                 assert(frw->writers == 1);
    348                 locked = true;
    349         }
    350         futex_up(&async_futex);
    351 
    352         return locked;
    353 }
    354 
    355 bool fibril_rwlock_is_locked(fibril_rwlock_t *frw)
    356 {
    357         return fibril_rwlock_is_read_locked(frw) ||
    358             fibril_rwlock_is_write_locked(frw);
    359275}
    360276
     
    369285{
    370286        awaiter_t wdata;
    371 
    372         assert(fibril_mutex_is_locked(fm));
    373287
    374288        if (timeout < 0)
Note: See TracChangeset for help on using the changeset viewer.