void __lockfunc _read_lock_bh(rwlock_t *lock) { local_bh_disable(); preempt_disable(); rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); }
static void readerthread(void *junk, unsigned long num) { (void)junk; if(num < 80) { //kprintf_n("Thread %lu trying to acquire read lock\n", num); random_yielder(4); rwlock_acquire_read(testrwlock); random_yielder(4); kprintf_n("Thread %lu: Reader val:%lu\n", num, testval1); for(int i=0; i<40000; i++); random_yielder(4); rwlock_release_read(testrwlock); random_yielder(4); //kprintf_n("Thread %lu released read lock\n", num); V(donesem); } else { //kprintf_n("Thread %lu trying to acquire write lock\n", num); random_yielder(4); rwlock_acquire_write(testrwlock); random_yielder(4); testval1++; kprintf_n("Thread %lu: Writer val:%lu\n", num, testval1); for(int i=0; i<40000; i++); random_yielder(4); rwlock_release_write(testrwlock); random_yielder(4); //kprintf_n("Thread %lu released write lock\n", num); V(donesem); } return; }
int bacstack_session_send(bacstack_session_t *session, bacstack_message_t *message) { assert(session != NULL); assert(message != NULL); int ret = 0; bacstack_route_t *route = NULL; int has_route = 0; int route_local = 0; uint8_t port_id = 0; bacstack_mac_t mac; if(message->endpoint.is_device_instance) { // the message has been addressed using a device instance, // which we must resolve to a port/mac here. // since we don't have a device table yet, we are unable // to send these sorts of message } if(!message->endpoint.is_device_instance) { // the message has been addressed using a network/mac // pair, and we must resolve our route to the network here if(!rwlock_acquire_read(&session->routetable_lock)) { warn("failed to acquire routetable read lock"); goto done; } if(bacstack_routetable_get_route( &session->routetable, message->endpoint.network_number, &route)) { has_route = 1; route_local = route->is_local; port_id = route->port_id; mac = route->next_hop_mac; } if(!rwlock_release(&session->routetable_lock)) { error("failed to release routetable read lock"); goto done; } } if(!has_route) { // we failed to find a route to the network, // so we should search for the network, and queue // this message to be sent when and if we find // that new network } done: return ret; }
unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) { unsigned long flags; local_irq_save(flags); preempt_disable(); rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); return flags; }
static void rwlocktestthread_reader(void *junk, unsigned long num) { int i; (void)junk; unsigned long tv_1; unsigned long tv_2; unsigned long tv_3; for (i=0; i<NLOCKLOOPS; i++) { rwlock_acquire_read(testrwlock); tv_1 = testval1; tv_2 = testval2; tv_3 = testval3; if(tv_1 != testval1){ fail_reader(num, "testval1 changed"); } if(tv_2 != testval2){ fail_reader(num, "testval2 changed"); } if(tv_3 != testval3){ fail_reader(num, "testval3 changed"); } // if (testval2 != testval1*testval1) { // fail_reader(num, "testval2/testval1"); // } // // if (testval2%3 != (testval3*testval3)%3) { // fail_reader(num, "testval2/testval3"); // } // // if (testval3 != testval1%3) { // fail_reader(num, "testval3/testval1"); // } // // if (testval1 != num) { // fail_reader(num, "testval1/num"); // } // // if (testval2 != num*num) { // fail_reader(num, "testval2/num"); // } // // if (testval3 != num%3) { // fail_reader(num, "testval3/num"); // } rwlock_release_read(testrwlock); } V(donesem); }
int __lockfunc _read_trylock(rwlock_t *lock) { preempt_disable(); if (_raw_read_trylock(lock)) { rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); return 1; } preempt_enable(); return 0; }
void __lockfunc rt_read_lock(rwlock_t *rwlock) { struct rt_mutex *lock = &rwlock->lock; rwlock_acquire_read(&rwlock->dep_map, 0, 0, _RET_IP_); /* * recursive read locks succeed when current owns the lock */ if (rt_mutex_real_owner(lock) != current) __rt_spin_lock(lock); rwlock->read_depth++; }
int __lockfunc rt_read_trylock(rwlock_t *rwlock) { struct rt_mutex *lock = &rwlock->lock; unsigned long flags; int ret; /* * Read locks within the self-held write lock succeed. */ spin_lock_irqsave(&lock->wait_lock, flags); if (rt_mutex_real_owner(lock) == current) { spin_unlock_irqrestore(&lock->wait_lock, flags); rwlock->read_depth++; rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); return 1; } spin_unlock_irqrestore(&lock->wait_lock, flags); ret = rt_mutex_trylock(lock); if (ret) rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); return ret; }
void __lockfunc rt_read_lock(rwlock_t *rwlock) { unsigned long flags; struct rt_mutex *lock = &rwlock->lock; rwlock_acquire_read(&rwlock->dep_map, 0, 0, _RET_IP_); /* * Read locks within the write lock succeed. */ spin_lock_irqsave(&lock->wait_lock, flags); if (rt_mutex_real_owner(lock) == current) { spin_unlock_irqrestore(&lock->wait_lock, flags); rwlock->read_depth++; return; } spin_unlock_irqrestore(&lock->wait_lock, flags); __rt_spin_lock(lock); }
int __lockfunc rt_read_trylock(rwlock_t *rwlock) { struct rt_mutex *lock = &rwlock->lock; int ret = 1; /* * recursive read locks succeed when current owns the lock, * but not when read_depth == 0 which means that the lock is * write locked. */ if (rt_mutex_real_owner(lock) != current) ret = rt_mutex_trylock(lock); else if (!rwlock->read_depth) ret = 0; if (ret) { rwlock->read_depth++; rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); } return ret; }
static void readtestthread(void *junk, unsigned long num) { int i; (void)junk; unsigned long localtestval ; int j ; for (i=0; i<NRWLOOPS; i++) { rwlock_acquire_read(testrwlock); kprintf("Lock Acquired for Read Thread %lu \n", num); localtestval = testval4 ; //Empty loop to pass time. No other thread should modify the value in this time. for(j=0 ; j<3000 ;j++) ; //assert operation to verify whether the value has been changed after the lock is acquired. KASSERT(localtestval == testval4); kprintf("Read Thread %lu : Read Value %lu \n", num, testval4); kprintf("Lock Released for Read Thread %lu \n", num); rwlock_release_read(testrwlock); } V(donesem); }