Rev 2330 | Rev 2430 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2330 | Rev 2400 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | #include <arch/types.h> |
33 | #include <arch/types.h> |
34 | #include <proc/tasklet.h> |
34 | #include <proc/tasklet.h> |
35 | #include <arch/barrier.h> |
35 | #include <arch/barrier.h> |
36 | #include <arch.h> |
36 | #include <arch.h> |
37 | #include <preemption.h> |
37 | #include <preemption.h> |
- | 38 | #include <proc/thread.h> |
|
- | 39 | ||
- | 40 | ||
- | 41 | #define RCU_MAX_I 1000 |
|
- | 42 | #define READER_THREADS 10 |
|
- | 43 | #define WRITER_THREADS 10 |
|
- | 44 | #define THREADS_SLEEP_LENGTH (uint32_t)50 |
|
- | 45 | ||
38 | bool gquiet; |
46 | bool gquiet; |
39 | volatile bool called; |
47 | volatile bool finished; |
- | 48 | typedef struct data_struc { |
|
- | 49 | int number; |
|
- | 50 | struct data_struc* next; |
|
- | 51 | } data_t; |
|
- | 52 | ||
- | 53 | data_t* first; |
|
- | 54 | SPINLOCK_INITIALIZE(write_lock); |
|
- | 55 | ||
40 | 56 | ||
- | 57 | ||
41 | static void callback(void* data) |
58 | static void reader(void* a) |
42 | { |
59 | { |
- | 60 | a = (a); |
|
- | 61 | data_t* cur; |
|
- | 62 | int i = 0; |
|
43 | if (!gquiet) |
63 | while (true) |
- | 64 | { |
|
- | 65 | i = 0; |
|
- | 66 | rcu_read_lock(); |
|
- | 67 | for (cur = rcu_dereference_pointer(first).next; cur != first; cur = cur->next) { |
|
- | 68 | i += rcu_dereference_pointer(cur).number; |
|
- | 69 | } |
|
- | 70 | rcu_read_unlock(); |
|
- | 71 | thread_usleep(THREADS_SLEEP_LENGTH); |
|
- | 72 | if (i>RCU_MAX_I || finished) |
|
- | 73 | { |
|
44 | printf("callback called\n"); |
74 | printf("@"); |
- | 75 | break; |
|
- | 76 | } |
|
- | 77 | } |
|
45 | called = true; |
78 | finished = true; |
46 | } |
79 | } |
- | 80 | ||
- | 81 | static void writer(void* a) |
|
- | 82 | { |
|
- | 83 | a = (a); |
|
- | 84 | data_t* cur; |
|
- | 85 | data_t* newdata, *oldata; |
|
- | 86 | rcu_callback_list_t* rcudata; |
|
- | 87 | int i = 0; |
|
- | 88 | printf("a1 "); |
|
- | 89 | rcudata = malloc(sizeof(rcu_callback_list_t),0); |
|
- | 90 | while (true) |
|
- | 91 | { |
|
- | 92 | i = rcu_dereference_pointer(first).number; |
|
- | 93 | rcu_read_lock(); |
|
- | 94 | printf("a2 "); |
|
- | 95 | for (cur = rcu_dereference_pointer(first).next; cur != first; cur = rcu_dereference_pointer(cur).next) { |
|
- | 96 | i += rcu_dereference_pointer(cur).number; |
|
- | 97 | } |
|
- | 98 | rcu_read_unlock(); |
|
- | 99 | if (!gquiet) |
|
- | 100 | printf("i%d ",i); |
|
- | 101 | if (i>RCU_MAX_I || finished) |
|
- | 102 | { |
|
- | 103 | printf("!"); |
|
- | 104 | break; |
|
- | 105 | } |
|
- | 106 | printf("a2b "); |
|
- | 107 | thread_usleep(THREADS_SLEEP_LENGTH); |
|
- | 108 | ||
- | 109 | printf("a3 "); |
|
- | 110 | newdata = malloc(sizeof(data_t),0); |
|
- | 111 | printf("a4 "); |
|
- | 112 | rcu_read_lock(); |
|
- | 113 | //prepend a new member |
|
- | 114 | spinlock_lock(&write_lock); |
|
- | 115 | printf("a5 "); |
|
- | 116 | newdata->number = (i/10)+1; |
|
- | 117 | oldata = first; |
|
- | 118 | newdata->next = first; |
|
- | 119 | rcu_assign_pointer(first, newdata); |
|
- | 120 | printf("a6 "); |
|
- | 121 | rcu_sync_callback(&rcu_callback_free, oldata, rcudata); |
|
- | 122 | spinlock_unlock(&write_lock); |
|
- | 123 | printf("a7 "); |
|
- | 124 | rcu_read_unlock(); |
|
- | 125 | thread_usleep(THREADS_SLEEP_LENGTH); |
|
- | 126 | printf("a8 "); |
|
- | 127 | if (!gquiet) |
|
- | 128 | printf(".",i); |
|
- | 129 | ||
- | 130 | rcu_read_lock(); |
|
- | 131 | for (cur = rcu_dereference_pointer(first).next; rcu_dereference_pointer(cur).number % 5 != 4 && cur != first; cur = rcu_dereference_pointer(cur).next) { |
|
- | 132 | } |
|
- | 133 | if (cur != first){ |
|
- | 134 | //delete the cur->next |
|
- | 135 | spinlock_lock(&write_lock); |
|
- | 136 | oldata = rcu_dereference_pointer(cur).next; |
|
- | 137 | newdata->next = rcu_dereference_pointer(rcu_dereference_pointer(cur).next).next; |
|
- | 138 | rcu_assign_pointer(rcu_dereference_pointer(cur).next, newdata); |
|
- | 139 | rcu_sync_callback(&rcu_callback_free, oldata, rcudata); |
|
- | 140 | spinlock_unlock(&write_lock); |
|
- | 141 | if (!gquiet) |
|
- | 142 | printf(", ",i); |
|
- | 143 | ||
- | 144 | } |
|
- | 145 | rcu_read_unlock(); |
|
- | 146 | thread_usleep(THREADS_SLEEP_LENGTH); |
|
- | 147 | } |
|
- | 148 | finished = true; |
|
- | 149 | } |
|
- | 150 | ||
47 | char * test_rcu1(bool quiet) |
151 | char * test_rcu1(bool quiet) |
48 | { |
152 | { |
49 | gquiet = quiet; |
153 | gquiet = quiet; |
50 | called = false; |
154 | data_t* cur, *oldata; |
51 | int* p; |
155 | int i; |
52 | rcu_read_lock(); |
156 | thread_t* t; |
- | 157 | thread_t** threads; |
|
53 | rcu_assign_pointer(p,malloc(sizeof(int),0)); |
158 | first = malloc(sizeof(data_t),0); |
54 | if (!quiet) |
159 | first->number = 10; |
- | 160 | first->next = first; |
|
55 | printf("p:%x\n",rcu_dereference_pointer(p)); |
161 | threads = malloc(sizeof(thread_t*),0); |
- | 162 | finished = false; |
|
- | 163 | ||
- | 164 | for(i = 0; i< WRITER_THREADS; i++) { |
|
- | 165 | threads[i]=t=thread_create(writer,NULL, TASK, 0, "writerthread", false ); |
|
- | 166 | if (t != NULL) |
|
56 | rcu_read_unlock(); |
167 | thread_ready(t); |
- | 168 | } |
|
- | 169 | ||
57 | rcu_sync_callback(&callback, NULL); |
170 | for(i = 0; i< READER_THREADS; i++) { |
- | 171 | threads[WRITER_THREADS+i]=t=thread_create(reader,NULL, TASK, 0, "readerthread", false ); |
|
58 | if (!quiet) |
172 | if (t != NULL) |
59 | printf("Callback scheduled\n"); |
173 | thread_ready(t); |
- | 174 | } |
|
- | 175 | ||
- | 176 | for (i=0;i<WRITER_THREADS+READER_THREADS;i++) |
|
60 | // while(!called); |
177 | thread_join(threads[i]); |
- | 178 | ||
- | 179 | for(cur=first->next;cur->next!=first;) { |
|
61 | rcu_synchronize(); |
180 | oldata = cur->next; |
62 | if (!quiet) |
181 | free(cur); |
63 | printf("Synchronized\n"); |
182 | cur = oldata; |
- | 183 | } |
|
- | 184 | free(first); |
|
64 | return NULL; |
185 | return NULL; |
65 | 186 | ||
66 | } |
187 | } |
67 | 188 | ||
68 | 189 |