Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2456 → Rev 2450

/branches/rcu/kernel/test/synch/rcu1.c
42,7 → 42,7
#include <proc/thread.h>
 
//number of nodes in the list. The sum of the list will grow up to RCU_MAX_I^2
#define RCU_MAX_I 5000
#define RCU_MAX_I 500
//number of reader and writer threads in the test
#define READER_THREADS 10
#define WRITER_THREADS 10
69,7 → 69,8
a = (a);
data_t* cur;
int i = 0;
while (true) {
while (true)
{
//entering read critical section
rcu_read_lock();
//proper dereferencing
78,17 → 79,14
i += cur->number;
}
rcu_read_unlock();
if (i>RCU_MAX_I*RCU_MAX_I || cfinished>0) {
if (!gquiet)
printf("@");
if (i>RCU_MAX_I*RCU_MAX_I || cfinished>0)
{
printf("@");
break;
}
thread_usleep(THREADS_SLEEP_LENGTH);
}
//we must achieve some kind of synchronization gcc wont emit inc [cfinished]
spinlock_lock(&write_lock);
cfinished++;
spinlock_unlock(&write_lock);
}
 
static void writer(void* a)
99,7 → 97,8
data_t* oldata;
rcu_callback_list_t* rcudata;
int i = 0;
while (true) {
while (true)
{
//we must allocate the rcu structure each time, because it gets freed after the callback
//we allocate it outside any critical section, as it could block
rcudata = malloc(sizeof(rcu_callback_list_t),0);
109,11 → 108,11
i += cur->number;
}
rcu_read_unlock();
if (!gquiet && false)
if (!gquiet)
printf("i%d ",i);
if (i>RCU_MAX_I*RCU_MAX_I || cfinished>0) {
if (!gquiet)
printf("!");
if (i>RCU_MAX_I*RCU_MAX_I || cfinished>0)
{
printf("!");
break;
}
 
120,17 → 119,20
//insert a new member
newdata = malloc(sizeof(data_t),0);
newdata->number = (i/(RCU_MAX_I/2))+1;
rcu_read_lock();
//we have to acquire the lock for writing to the structure
spinlock_lock(&write_lock);
newdata->next = first;
//rcu_assign_pointer takes care of the necessary write barriers
rcu_assign_pointer(first, newdata);
if (!gquiet && false)
if (!gquiet)
printf("prepending:%x,n:%d ", newdata, newdata->number);
spinlock_unlock(&write_lock);
rcu_read_unlock();
 
 
//replace a random member
rcu_read_lock();
//we have to lock the spinlock now, because we'll use the cur pointer later
//RCU doesn't provide guarantee that cur->next will point to a member of the list
//note that read critical section DOES guarantee that the *cur will be allocated space
142,10 → 144,10
if (cur->next != NULL) {
newdata = malloc(sizeof(data_t),0);
//the change of number member could be done atomically, its here just to simulate some real work
newdata->number = (i/(RCU_MAX_I/2))+10;
newdata->number = (i/(RCU_MAX_I/2))+5;
newdata->next = cur->next->next;
oldata = cur->next;
if (!gquiet && false)
if (!gquiet)
printf("free:%x,n:%d ", cur->next, cur->next->number);
rcu_assign_pointer(cur->next, newdata);
//free the old member when it is safe (i.e. no references are held)
152,11 → 154,9
rcu_sync_callback(&rcu_callback_free, oldata, rcudata);
spinlock_unlock(&write_lock);
}
rcu_read_unlock();
}
//we must achieve some kind of synchronization gcc wont emit inc [cfinished]
spinlock_lock(&write_lock);
cfinished++;
spinlock_unlock(&write_lock);
}
 
char * test_rcu1(bool quiet)
195,8 → 195,7
}
//wait for completion
while (cfinished<WRITER_THREADS+READER_THREADS);
if (!gquiet)
printf("\nfinished all threads!\n");
printf("\nfinished all threads!\n");
//free the list
for(cur=first->next;cur!=NULL;) {
oldata = cur->next;
/branches/rcu/kernel/test/tasklet/tasklet1.c
37,13 → 37,12
#include <arch/types.h>
#include <config.h>
 
bool gquiet;
static void func(void *data)
{
if (!gquiet)
printf("cpu%d: %s",CPU->id, data);
printf("cpu%d: %s",CPU->id, data);
}
 
bool gquiet;
#ifdef CONFIG_SMP
 
static void running_tasklet(void * data)