jekyll-theme-gaeblogx 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +9 -0
- data/_includes/algolia.html +75 -0
- data/_includes/backToTop.html +5 -0
- data/_includes/category.html +19 -0
- data/_includes/comments.html +46 -0
- data/_includes/footer.html +33 -0
- data/_includes/head.html +58 -0
- data/_includes/header.html +34 -0
- data/_includes/previousAndNext.html +13 -0
- data/_includes/sidebar-search.html +25 -0
- data/_includes/tag.html +16 -0
- data/_layouts/default.html +26 -0
- data/_layouts/demo.html +10 -0
- data/_layouts/page.html +31 -0
- data/_layouts/post.html +107 -0
- data/_sass/_backToTop.scss +49 -0
- data/_sass/_demo.scss +65 -0
- data/_sass/_footer.scss +63 -0
- data/_sass/_header.scss +174 -0
- data/_sass/_index.scss +174 -0
- data/_sass/_layout.scss +242 -0
- data/_sass/_page.scss +238 -0
- data/_sass/_post-old.scss +109 -0
- data/_sass/_post.scss +83 -0
- data/_sass/_reset.scss +119 -0
- data/_sass/_scrollbar.scss +35 -0
- data/_sass/_syntax-highlighting.scss +99 -0
- data/assets/10.jpg +0 -0
- data/assets/AWS-Introduction-ec2.png +0 -0
- data/assets/Cache-Oblivious-Algorithms-FunnelSort.jpg +0 -0
- data/assets/Condition-Variables-fig1.png +0 -0
- data/assets/Dynamic-Compilation-adaptJVM.pdf +0 -0
- data/assets/Dynamic-Compilation-dyncomp.pdf +0 -0
- data/assets/Fibonacci-Heap-Fig3.png +0 -0
- data/assets/Fibonacci-Heap-Fig5.png +0 -0
- data/assets/Fibonacci-Heap-Fig6.png +0 -0
- data/assets/Fibonacci-Heap-Fig7.png +0 -0
- data/assets/File-System-bc.jpg +0 -0
- data/assets/File-System-filetable.rich.jpg +0 -0
- data/assets/GIL-Battle.png +0 -0
- data/assets/GIL-CPU.png +0 -0
- data/assets/GIL-Check.png +0 -0
- data/assets/GIL-IO.png +0 -0
- data/assets/GIL-Measure-1.png +0 -0
- data/assets/GIL-Measure-2.png +0 -0
- data/assets/GIL-Signal.png +0 -0
- data/assets/GIL-Tick.png +0 -0
- data/assets/Garbage-Collection-Slides-gc.pdf +0 -0
- data/assets/Garbage-Collection-copying-1.png +0 -0
- data/assets/Garbage-Collection-copying-2.png +0 -0
- data/assets/Garbage-Collection-free-list.png +0 -0
- data/assets/Garbage-Collection-generation-1.png +0 -0
- data/assets/Garbage-Collection-mark-sweep.png +0 -0
- data/assets/Garbage-Collection-nursery-1.png +0 -0
- data/assets/Garbage-Collection-nursery-2.png +0 -0
- data/assets/Garbage-Collection-nursery-3.png +0 -0
- data/assets/Garbage-Collection-nursery-4.png +0 -0
- data/assets/Garbage-Collection-nursery-5.png +0 -0
- data/assets/Garbage-Collection-process.png +0 -0
- data/assets/Garbage-Collection-ref-counting.png +0 -0
- data/assets/Interpreter-Optimization-interp.pdf +0 -0
- data/assets/Memory-Management-fig1.png +0 -0
- data/assets/Memory-Management-fig2.png +0 -0
- data/assets/Memory-Management-fig3.png +0 -0
- data/assets/Memory-Management-fig4.png +0 -0
- data/assets/Memory-Management-fig5.png +0 -0
- data/assets/Memory-Management-fig6.png +0 -0
- data/assets/Memory-Management-fig7.png +0 -0
- data/assets/Memory-Management-fig8.png +0 -0
- data/assets/Multicore-GIL-1.png +0 -0
- data/assets/Multicore-GIL-2.png +0 -0
- data/assets/My-Photo.JPG +0 -0
- data/assets/Operating-System-Virtualization-ept.png +0 -0
- data/assets/Operating-System-Virtualization-guest-page.png +0 -0
- data/assets/Operating-System-Virtualization-kvm-arch.png +0 -0
- data/assets/Operating-System-Virtualization-kvm-process.png +0 -0
- data/assets/Operating-System-Virtualization-kvm-qemu.png +0 -0
- data/assets/Operating-System-Virtualization-kvm-state.png +0 -0
- data/assets/Operating-System-Virtualization-vtx.png +0 -0
- data/assets/Operating-System-Virtualization-xen-arch.png +0 -0
- data/assets/Program-Profiling-profiling.pdf +0 -0
- data/assets/Programming-Language-Virtual-Machine-vm.pdf +0 -0
- data/assets/Remote-Shell-Session-Setup-1.png +0 -0
- data/assets/Signals-1.png +0 -0
- data/assets/Signals-2.png +0 -0
- data/assets/Signals-3.png +0 -0
- data/assets/Some-Slides-about-Containers-Kubernetes.pdf +0 -0
- data/assets/Some-Slides-about-Containers-UCSB-nurmi.pdf +0 -0
- data/assets/Some-Slides-about-PaaS-CS293B_CloudPlatforms.pdf +0 -0
- data/assets/avg-1thread.c +172 -0
- data/assets/avg-manythread.c +284 -0
- data/assets/avg-nothread.c +71 -0
- data/assets/file-create1.c +75 -0
- data/assets/file-create2.c +120 -0
- data/assets/file-fd1.c +56 -0
- data/assets/file-fd2.c +25 -0
- data/assets/file-fd3.c +23 -0
- data/assets/file-read1.c +62 -0
- data/assets/file-read2.c +66 -0
- data/assets/file-seek1.c +87 -0
- data/assets/fork-1.c +35 -0
- data/assets/fork-2.c +44 -0
- data/assets/fork-3.c +60 -0
- data/assets/fork-4.c +64 -0
- data/assets/joinall-1.c +163 -0
- data/assets/joinall-2.c +162 -0
- data/assets/market-kthreads.c +465 -0
- data/assets/market-semaphore.c +504 -0
- data/assets/market1.c +478 -0
- data/assets/market2.c +490 -0
- data/assets/market3.c +503 -0
- data/assets/market4.c +509 -0
- data/assets/my-cat.c +35 -0
- data/assets/pipe-1.c +45 -0
- data/assets/pipe-2.c +80 -0
- data/assets/pipe-3.c +83 -0
- data/assets/pipe-4.c +116 -0
- data/assets/race1.c +75 -0
- data/assets/race2.c +77 -0
- data/assets/race3.c +87 -0
- data/assets/race_ABC.c +144 -0
- data/assets/search-by-algolia.svg +1 -0
- data/assets/semaphore.book.ps +8827 -0
- data/assets/sys-call1.c +20 -0
- data/assets/sys-call2.c +16 -0
- data/assets//350/265/253/347/202/2161.PNG +0 -0
- data/feed.xml +30 -0
- data/index.html +164 -0
- data/js/jekyll-search.min.js +1 -0
- data/js/lunr.min.js +2977 -0
- data/js/main.js +57 -0
- data/js/masonry.pkgd.min.js +9 -0
- data/js/pageContent.js +166 -0
- data/js/search.js +17 -0
- data/js/smooth-scroll.min.js +2 -0
- data/js/waterfall.js +214 -0
- data/page/0archives.html +83 -0
- data/page/1category.html +62 -0
- data/page/2tags.html +64 -0
- data/page/3search.html +112 -0
- data/page/4about.md +34 -0
- metadata +270 -0
data/assets/joinall-2.c
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* cs170 -- Rich wolski
|
|
3
|
+
* ping-pong code illustrating kt_joinall() functionality
|
|
4
|
+
*/
|
|
5
|
+
#include <unistd.h>
|
|
6
|
+
#include <stdlib.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <string.h>
|
|
9
|
+
|
|
10
|
+
#include "kt.h"
|
|
11
|
+
|
|
12
|
+
#define RAND() (drand48())
|
|
13
|
+
|
|
14
|
+
struct thread_arg
|
|
15
|
+
{
|
|
16
|
+
int id;
|
|
17
|
+
int count;
|
|
18
|
+
double *shared_counter;
|
|
19
|
+
kt_sem next;
|
|
20
|
+
int *finished;
|
|
21
|
+
int verbose;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
* bumps the shared counter by 1 each time it is enabled
|
|
26
|
+
*/
|
|
27
|
+
void *PingPongThread(void *arg)
|
|
28
|
+
{
|
|
29
|
+
struct thread_arg *ta = (struct thread_arg *)arg;
|
|
30
|
+
int i;
|
|
31
|
+
|
|
32
|
+
for(i=0; i < ta->count; i++) {
|
|
33
|
+
P_kt_sem(ta->next);
|
|
34
|
+
*(ta->shared_counter) =
|
|
35
|
+
*(ta->shared_counter) + 1.0;
|
|
36
|
+
if(ta->verbose == 1) {
|
|
37
|
+
printf("thread %d: incremented shared counter to %f\n",
|
|
38
|
+
ta->id,
|
|
39
|
+
*(ta->shared_counter));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
*(ta->finished) = *(ta->finished) + 1;
|
|
44
|
+
|
|
45
|
+
kt_exit();
|
|
46
|
+
return(NULL);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#define ARGS "t:VC:"
|
|
50
|
+
char *Usage = "ping-pong-joinall -C count -t threads -V <verbose on>\n";
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
int main(int argc, char **argv)
|
|
54
|
+
{
|
|
55
|
+
int c;
|
|
56
|
+
int threads;
|
|
57
|
+
struct thread_arg *ta;
|
|
58
|
+
void **ids;
|
|
59
|
+
double counter;
|
|
60
|
+
int done_threads;
|
|
61
|
+
int count;
|
|
62
|
+
int verbose;
|
|
63
|
+
int i;
|
|
64
|
+
kt_sem sema;
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* defaults
|
|
69
|
+
*/
|
|
70
|
+
threads = 1;
|
|
71
|
+
counter = 0;
|
|
72
|
+
count = 1;
|
|
73
|
+
while((c = getopt(argc,argv,ARGS)) != EOF) {
|
|
74
|
+
switch(c) {
|
|
75
|
+
case 'C':
|
|
76
|
+
count = atoi(optarg);
|
|
77
|
+
break;
|
|
78
|
+
case 't':
|
|
79
|
+
threads = atoi(optarg);
|
|
80
|
+
break;
|
|
81
|
+
case 'V':
|
|
82
|
+
verbose = 1;
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
fprintf(stderr,
|
|
86
|
+
"unrecognized command %c\n",
|
|
87
|
+
(char)c);
|
|
88
|
+
fprintf(stderr,"usage: %s",Usage);
|
|
89
|
+
exit(1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
ids = (void **)malloc(threads*sizeof(void *));
|
|
94
|
+
if(ids == NULL) {
|
|
95
|
+
exit(1);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
ta = (struct thread_arg *)malloc(threads*sizeof(struct thread_arg));
|
|
99
|
+
if(ta == NULL) {
|
|
100
|
+
exit(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
sema = make_kt_sem(0);
|
|
104
|
+
if(sema == NULL) {
|
|
105
|
+
exit(1);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
done_threads = 0;
|
|
109
|
+
for(i=0; i < threads; i++) {
|
|
110
|
+
ta[i].id = i;
|
|
111
|
+
ta[i].next = sema;
|
|
112
|
+
ta[i].count = count;
|
|
113
|
+
ta[i].shared_counter = &counter;
|
|
114
|
+
ta[i].finished = &done_threads;
|
|
115
|
+
ta[i].verbose = verbose;
|
|
116
|
+
ids[i] = kt_fork(PingPongThread,(void *)&ta[i]);
|
|
117
|
+
if(ids[i] == NULL) {
|
|
118
|
+
fprintf(stderr,"thread create %d failed\n",i);
|
|
119
|
+
exit(1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/*
|
|
124
|
+
* loop showing progress
|
|
125
|
+
*/
|
|
126
|
+
while(done_threads < threads) {
|
|
127
|
+
V_kt_sem(sema); /* enable a thread */
|
|
128
|
+
printf("shared counter: %f\n",counter);
|
|
129
|
+
fflush(stdout);
|
|
130
|
+
kt_joinall(); /* gets here when all else is stopped */
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
* join with the threads after exit
|
|
135
|
+
*/
|
|
136
|
+
for(i=0; i < threads; i++) {
|
|
137
|
+
kt_join(ids[i]);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
kill_kt_sem(sema);
|
|
141
|
+
free(ta);
|
|
142
|
+
free(ids);
|
|
143
|
+
|
|
144
|
+
printf("final count: %f\n",counter);
|
|
145
|
+
|
|
146
|
+
return(0);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* cs170 -- Rich wolski
|
|
3
|
+
* producer-consumer example using kthreads
|
|
4
|
+
* uses condition variables for full/empty conditions
|
|
5
|
+
* uses condition variable to fulfill order
|
|
6
|
+
* uses separate lock for each stock
|
|
7
|
+
*/
|
|
8
|
+
#include <unistd.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <stdio.h>
|
|
11
|
+
#include <string.h>
|
|
12
|
+
|
|
13
|
+
#include "c-timer.h"
|
|
14
|
+
#include "kt.h"
|
|
15
|
+
|
|
16
|
+
#define RAND() (drand48())
|
|
17
|
+
|
|
18
|
+
struct order
|
|
19
|
+
{
|
|
20
|
+
int stock_id;
|
|
21
|
+
int quantity;
|
|
22
|
+
int action; /* buy or sell */
|
|
23
|
+
kt_sem fulfilled;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
struct order_que
|
|
27
|
+
{
|
|
28
|
+
struct order **orders;
|
|
29
|
+
int size;
|
|
30
|
+
int head;
|
|
31
|
+
int tail;
|
|
32
|
+
kt_sem full;
|
|
33
|
+
kt_sem empty;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
struct stock
|
|
37
|
+
{
|
|
38
|
+
int quantity;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
struct market
|
|
42
|
+
{
|
|
43
|
+
struct stock *stocks;
|
|
44
|
+
int count;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
struct order *InitOrder(int id, int quantity, int action)
|
|
48
|
+
{
|
|
49
|
+
struct order *order;
|
|
50
|
+
|
|
51
|
+
order = (struct order *)malloc(sizeof(struct order));
|
|
52
|
+
if(order == NULL) {
|
|
53
|
+
return(NULL);
|
|
54
|
+
}
|
|
55
|
+
order->stock_id = id;
|
|
56
|
+
order->quantity = quantity;
|
|
57
|
+
order->action = action;
|
|
58
|
+
order->fulfilled = make_kt_sem(0);
|
|
59
|
+
return(order);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
void FreeOrder(struct order *order)
|
|
63
|
+
{
|
|
64
|
+
kill_kt_sem(order->fulfilled);
|
|
65
|
+
free(order);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
struct order_que *InitOrderQue(int size)
|
|
69
|
+
{
|
|
70
|
+
struct order_que *oq;
|
|
71
|
+
|
|
72
|
+
oq = (struct order_que *)malloc(sizeof(struct order_que));
|
|
73
|
+
if(oq == NULL) {
|
|
74
|
+
return(NULL);
|
|
75
|
+
}
|
|
76
|
+
memset(oq,0,sizeof(struct order_que));
|
|
77
|
+
|
|
78
|
+
oq->size = size+1; /* empty condition burns a slot */
|
|
79
|
+
oq->orders = (struct order **)malloc(size*sizeof(struct order *));
|
|
80
|
+
if(oq->orders == NULL) {
|
|
81
|
+
free(oq);
|
|
82
|
+
return(NULL);
|
|
83
|
+
}
|
|
84
|
+
memset(oq->orders,0,size*sizeof(struct order *));
|
|
85
|
+
|
|
86
|
+
oq->full = make_kt_sem(size);
|
|
87
|
+
oq->empty = make_kt_sem(0);
|
|
88
|
+
|
|
89
|
+
return(oq);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
void FreeOrderQue(struct order_que *oq)
|
|
93
|
+
{
|
|
94
|
+
while(oq->head != oq->tail) {
|
|
95
|
+
FreeOrder(oq->orders[oq->tail]);
|
|
96
|
+
oq->tail = (oq->tail + 1) % oq->size;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
kill_kt_sem(oq->full);
|
|
100
|
+
kill_kt_sem(oq->empty);
|
|
101
|
+
free(oq->orders);
|
|
102
|
+
free(oq);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
struct market *InitMarket(int stock_count, int init_quantity)
|
|
107
|
+
{
|
|
108
|
+
struct market *m;
|
|
109
|
+
int i;
|
|
110
|
+
|
|
111
|
+
m = (struct market *)malloc(sizeof(struct market));
|
|
112
|
+
if(m == NULL) {
|
|
113
|
+
return(NULL);
|
|
114
|
+
}
|
|
115
|
+
m->count = stock_count;
|
|
116
|
+
|
|
117
|
+
m->stocks = (struct stock *)malloc(stock_count*sizeof(struct stock));
|
|
118
|
+
if(m->stocks == NULL) {
|
|
119
|
+
free(m);
|
|
120
|
+
return(NULL);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for(i=0; i < stock_count; i++) {
|
|
124
|
+
m->stocks[i].quantity = init_quantity;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return(m);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void FreeMarket(struct market *m)
|
|
131
|
+
{
|
|
132
|
+
free(m->stocks);
|
|
133
|
+
free(m);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
void PrintMarket(struct market *m)
|
|
138
|
+
{
|
|
139
|
+
int i;
|
|
140
|
+
for(i=0; i < m->count; i++) {
|
|
141
|
+
printf("stock: %d, quantity: %d\n",
|
|
142
|
+
i,m->stocks[i].quantity);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
struct client_arg
|
|
149
|
+
{
|
|
150
|
+
int id;
|
|
151
|
+
int order_count;
|
|
152
|
+
struct order_que *order_que;
|
|
153
|
+
int max_stock_id;
|
|
154
|
+
int max_quantity;
|
|
155
|
+
int verbose;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
struct trader_arg
|
|
159
|
+
{
|
|
160
|
+
int id;
|
|
161
|
+
struct order_que *order_que;
|
|
162
|
+
struct market *market;
|
|
163
|
+
int *done;
|
|
164
|
+
int verbose;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
void ClientThread(void *arg)
|
|
168
|
+
{
|
|
169
|
+
struct client_arg *ca = (struct client_arg *)arg;
|
|
170
|
+
int i;
|
|
171
|
+
int next;
|
|
172
|
+
struct order *order;
|
|
173
|
+
int stock_id;
|
|
174
|
+
int quantity;
|
|
175
|
+
int action;
|
|
176
|
+
int queued;
|
|
177
|
+
double now;
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
for(i=0; i < ca->order_count; i++) {
|
|
181
|
+
/*
|
|
182
|
+
* create an order for a random stock
|
|
183
|
+
*/
|
|
184
|
+
stock_id = (int)(RAND() * ca->max_stock_id);
|
|
185
|
+
quantity = (int)(RAND() * ca->max_quantity);
|
|
186
|
+
if(RAND() > 0.5) {
|
|
187
|
+
action = 0; /* 0 => buy */
|
|
188
|
+
} else {
|
|
189
|
+
action = 1; /* 1 => sell */
|
|
190
|
+
}
|
|
191
|
+
order = InitOrder(stock_id,quantity,action);
|
|
192
|
+
if(order == NULL) {
|
|
193
|
+
fprintf(stderr,"no space for order\n");
|
|
194
|
+
exit(1);
|
|
195
|
+
}
|
|
196
|
+
/*
|
|
197
|
+
* queue it for the traders
|
|
198
|
+
*/
|
|
199
|
+
P_kt_sem(ca->order_que->full);
|
|
200
|
+
next = (ca->order_que->head + 1) % ca->order_que->size;
|
|
201
|
+
/*
|
|
202
|
+
* there is space in the queue, add the order and bump
|
|
203
|
+
* the head
|
|
204
|
+
*/
|
|
205
|
+
if(ca->verbose == 1) {
|
|
206
|
+
now = CTimer();
|
|
207
|
+
printf("%10.0f client %d: ",now,ca->id);
|
|
208
|
+
printf("queued stock %d, for %d, %s\n",
|
|
209
|
+
order->stock_id,
|
|
210
|
+
order->quantity,
|
|
211
|
+
(order->action ? "SELL" : "BUY"));
|
|
212
|
+
}
|
|
213
|
+
ca->order_que->orders[next] = order;
|
|
214
|
+
ca->order_que->head = next;
|
|
215
|
+
/*
|
|
216
|
+
* signal traders that there is another order
|
|
217
|
+
*/
|
|
218
|
+
V_kt_sem(ca->order_que->empty);
|
|
219
|
+
/*
|
|
220
|
+
* wait until the order is fulfilled
|
|
221
|
+
*/
|
|
222
|
+
P_kt_sem(order->fulfilled);
|
|
223
|
+
/*
|
|
224
|
+
* done, free the order and repeat
|
|
225
|
+
*/
|
|
226
|
+
FreeOrder(order);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
void TraderThread(void *arg)
|
|
233
|
+
{
|
|
234
|
+
struct trader_arg *ta = (struct trader_arg *)arg;
|
|
235
|
+
int dequeued;
|
|
236
|
+
struct order *order;
|
|
237
|
+
int tail;
|
|
238
|
+
double now;
|
|
239
|
+
int next;
|
|
240
|
+
struct stock *stock;
|
|
241
|
+
|
|
242
|
+
while(1) {
|
|
243
|
+
/*
|
|
244
|
+
* wait until there is a new order
|
|
245
|
+
*/
|
|
246
|
+
P_kt_sem(ta->order_que->empty);
|
|
247
|
+
/*
|
|
248
|
+
* are we done? Tell the next trader and exit
|
|
249
|
+
*/
|
|
250
|
+
if(*(ta->done) == 1) {
|
|
251
|
+
V_kt_sem(ta->order_que->empty);
|
|
252
|
+
kt_exit();
|
|
253
|
+
}
|
|
254
|
+
/*
|
|
255
|
+
* get the next order
|
|
256
|
+
*/
|
|
257
|
+
next = (ta->order_que->tail + 1) % ta->order_que->size;
|
|
258
|
+
order = ta->order_que->orders[next];
|
|
259
|
+
ta->order_que->tail = next;
|
|
260
|
+
/*
|
|
261
|
+
* tell the clients there is another free slot
|
|
262
|
+
*/
|
|
263
|
+
V_kt_sem(ta->order_que->full);
|
|
264
|
+
/*
|
|
265
|
+
* have an order to process
|
|
266
|
+
*/
|
|
267
|
+
stock = &(ta->market->stocks[order->stock_id]);
|
|
268
|
+
if(order->action == 1) { /* BUY */
|
|
269
|
+
stock->quantity -= order->quantity;
|
|
270
|
+
if(stock->quantity < 0) {
|
|
271
|
+
stock->quantity = 0;
|
|
272
|
+
}
|
|
273
|
+
} else {
|
|
274
|
+
stock->quantity += order->quantity;
|
|
275
|
+
}
|
|
276
|
+
if(ta->verbose == 1) {
|
|
277
|
+
now = CTimer();
|
|
278
|
+
printf("%10.0f trader: %d ",now,ta->id);
|
|
279
|
+
printf("fulfilled stock %d for %d\n",
|
|
280
|
+
order->stock_id,
|
|
281
|
+
order->quantity);
|
|
282
|
+
}
|
|
283
|
+
/*
|
|
284
|
+
* tell the client the order is done
|
|
285
|
+
*/
|
|
286
|
+
V_kt_sem(order->fulfilled);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
#define ARGS "c:t:o:q:s:V"
|
|
293
|
+
char *Usage = "market1 -c clients -t traders -o orders -q queue-size -s stock-count -V <verbose on>\n";
|
|
294
|
+
|
|
295
|
+
#define INIT_COUNT 5000
|
|
296
|
+
|
|
297
|
+
int main(int argc, char **argv)
|
|
298
|
+
{
|
|
299
|
+
int c;
|
|
300
|
+
int client_threads;
|
|
301
|
+
int trader_threads;
|
|
302
|
+
int orders_per_client;
|
|
303
|
+
int que_size;
|
|
304
|
+
int max_stock;
|
|
305
|
+
int verbose;
|
|
306
|
+
struct client_arg *ca;
|
|
307
|
+
struct trader_arg *ta;
|
|
308
|
+
void **client_ids;
|
|
309
|
+
void **trader_ids;
|
|
310
|
+
struct order_que *order_que;
|
|
311
|
+
struct market *market;
|
|
312
|
+
int i;
|
|
313
|
+
int done;
|
|
314
|
+
int err;
|
|
315
|
+
double start;
|
|
316
|
+
double end;
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
/*
|
|
320
|
+
* defaults
|
|
321
|
+
*/
|
|
322
|
+
client_threads = 1;
|
|
323
|
+
trader_threads = 1;
|
|
324
|
+
orders_per_client = 1;
|
|
325
|
+
verbose = 0;
|
|
326
|
+
que_size = 1;
|
|
327
|
+
max_stock = 1;
|
|
328
|
+
|
|
329
|
+
while((c = getopt(argc,argv,ARGS)) != EOF) {
|
|
330
|
+
switch(c) {
|
|
331
|
+
case 'c':
|
|
332
|
+
client_threads = atoi(optarg);
|
|
333
|
+
break;
|
|
334
|
+
case 't':
|
|
335
|
+
trader_threads = atoi(optarg);
|
|
336
|
+
break;
|
|
337
|
+
case 'o':
|
|
338
|
+
orders_per_client = atoi(optarg);
|
|
339
|
+
break;
|
|
340
|
+
case 'q':
|
|
341
|
+
que_size = atoi(optarg);
|
|
342
|
+
break;
|
|
343
|
+
case 's':
|
|
344
|
+
max_stock = atoi(optarg);
|
|
345
|
+
break;
|
|
346
|
+
case 'V':
|
|
347
|
+
verbose = 1;
|
|
348
|
+
break;
|
|
349
|
+
default:
|
|
350
|
+
fprintf(stderr,
|
|
351
|
+
"unrecognized command %c\n",
|
|
352
|
+
(char)c);
|
|
353
|
+
fprintf(stderr,"usage: %s",Usage);
|
|
354
|
+
exit(1);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
client_ids = (void **)malloc(client_threads*sizeof(void *));
|
|
359
|
+
if(client_ids == NULL) {
|
|
360
|
+
exit(1);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
ca = (struct client_arg *)malloc(client_threads*sizeof(struct client_arg));
|
|
364
|
+
if(ca == NULL) {
|
|
365
|
+
exit(1);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
trader_ids = (void **)malloc(trader_threads*sizeof(void *));
|
|
369
|
+
if(trader_ids == NULL) {
|
|
370
|
+
exit(1);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
ta = (struct trader_arg *)malloc(trader_threads*sizeof(struct trader_arg));
|
|
374
|
+
if(ta == NULL) {
|
|
375
|
+
exit(1);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
order_que = InitOrderQue(que_size);
|
|
379
|
+
if(order_que == NULL) {
|
|
380
|
+
exit(1);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
market = InitMarket(max_stock,INIT_COUNT);
|
|
384
|
+
if(market == NULL) {
|
|
385
|
+
exit(1);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
start = CTimer();
|
|
389
|
+
for(i=0; i < client_threads; i++) {
|
|
390
|
+
ca[i].id = i;
|
|
391
|
+
ca[i].order_count = orders_per_client;
|
|
392
|
+
ca[i].max_stock_id = max_stock;
|
|
393
|
+
ca[i].max_quantity = INIT_COUNT;
|
|
394
|
+
ca[i].order_que = order_que;
|
|
395
|
+
ca[i].verbose = verbose;
|
|
396
|
+
client_ids[i] = kt_fork(ClientThread,(void *)&ca[i]);
|
|
397
|
+
if(client_ids[i] == NULL) {
|
|
398
|
+
fprintf(stderr,"client thread create %d failed\n",i);
|
|
399
|
+
exit(1);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
done = 0;
|
|
404
|
+
for(i=0; i < trader_threads; i++) {
|
|
405
|
+
ta[i].id = i;
|
|
406
|
+
ta[i].order_que = order_que;
|
|
407
|
+
ta[i].market = market;
|
|
408
|
+
ta[i].done = &done;
|
|
409
|
+
ta[i].verbose = verbose;
|
|
410
|
+
trader_ids[i] = kt_fork(TraderThread,(void *)&ta[i]);
|
|
411
|
+
if(trader_ids[i] == NULL) {
|
|
412
|
+
fprintf(stderr,"trader thread create %d failed\n",i);
|
|
413
|
+
exit(1);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/*
|
|
418
|
+
* wait for the clients to finish
|
|
419
|
+
*/
|
|
420
|
+
for(i=0; i < client_threads; i++) {
|
|
421
|
+
kt_join(client_ids[i]);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/*
|
|
425
|
+
* tell the traders we are done
|
|
426
|
+
*/
|
|
427
|
+
done = 1;
|
|
428
|
+
V_kt_sem(order_que->empty);
|
|
429
|
+
|
|
430
|
+
for(i=0; i < trader_threads; i++) {
|
|
431
|
+
kt_join(trader_ids[i]);
|
|
432
|
+
}
|
|
433
|
+
end = CTimer();
|
|
434
|
+
|
|
435
|
+
if(verbose == 1) {
|
|
436
|
+
PrintMarket(market);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
printf("%f transactions / sec\n",
|
|
440
|
+
(double)(orders_per_client*client_threads) / (end-start));
|
|
441
|
+
|
|
442
|
+
free(ca);
|
|
443
|
+
free(ta);
|
|
444
|
+
free(client_ids);
|
|
445
|
+
free(trader_ids);
|
|
446
|
+
FreeMarket(market);
|
|
447
|
+
FreeOrderQue(order_que);
|
|
448
|
+
|
|
449
|
+
return(0);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
|