Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/tests/aso/tlock.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1999-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#include "terror.h"
21
22
#include <sys/mman.h>
23
24
/* Test concurrency locking based on Atomic Scalar Operations
25
**
26
** Written by Kiem-Phong Vo
27
*/
28
29
#ifndef N_PROC
30
#define N_PROC 16
31
#endif
32
33
#define N_SLOT 12 /* number of lock slots */
34
#define N_STEP 1000 /* number of working steps */
35
static int Pnum; /* process number */
36
static unsigned int *Nproc; /* number of processes */
37
static pid_t *Pid; /* process id */
38
static unsigned char *Lckc; /* slots of char locks */
39
static unsigned short *Lcks; /* slots of short locks */
40
static unsigned int *Lcki; /* slots of int locks */
41
static unsigned int *Done; /* count done workloads */
42
43
int lockobj(void* lck, ssize_t size, int locking)
44
{
45
int lckv, k, aso;
46
47
if(locking == 0) /* unlocking a slot */
48
{ if(size == sizeof(char))
49
lckv = *((char*)lck);
50
else if(size == sizeof(short))
51
lckv = *((short*)lck);
52
else lckv = *((int*)lck);
53
if(lckv != Pnum ) /* unlocking a wrong lock */
54
terror("Process %3d(pid=%d): unlocking %d(pid=%d)?",
55
Pnum, Pid[Pnum], lckv);
56
57
if(size == sizeof(char))
58
aso = asocaschar(lck, Pnum, 0);
59
else if(size == sizeof(short))
60
aso = asocasshort(lck, Pnum, 0);
61
else aso = asocasint(lck, Pnum, 0);
62
if(aso != Pnum) /* CAS failed! */
63
terror("Process %3d(pid=%d): unlocking CAS error %d",
64
Pnum, Pid[Pnum], aso);
65
66
return 0;
67
}
68
69
for(k = 0;; ++k, usleep(100) ) /* locking a slot */
70
{ if(size == sizeof(char))
71
aso = asocaschar(lck, 0, Pnum);
72
else if(size == sizeof(short))
73
aso = asocasshort(lck, 0, Pnum);
74
else aso = asocasint(lck, 0, Pnum);
75
76
if(aso == 0)
77
break;
78
else if(aso < 0)
79
terror("Process %3d(pid=%d): locking CAS error %d",
80
Pnum, Pid[Pnum], aso);
81
else if(k > 0 && (k%10000) == 0)
82
twarn("Process %3d(pid=%d): locking loop %d blocked by %d",
83
Pnum, Pid[Pnum], k, aso);
84
}
85
86
for(k = 0; k < 2; ++k, usleep(100) ) /* make sure that lock is good */
87
{ if(size == sizeof(char))
88
lckv = *((char*)lck);
89
else if(size == sizeof(short))
90
lckv = *((short*)lck);
91
else lckv = *((int*)lck);
92
if(lckv != Pnum)
93
terror("Process %3d(pid=%d): at step %d lock=%d?",
94
Pnum, Pid[Pnum], k, lckv);
95
}
96
97
return 0;
98
}
99
100
static void workload(int pnum)
101
{
102
int k, r;
103
104
Pnum = pnum;
105
for(k = 0; k < N_STEP; ++k)
106
{ if(k > 0 && (k%100) == 0)
107
tinfo("Process %3d(pid=%d): progress to %d", Pnum, Pid[Pnum], k);
108
109
r = random()%N_SLOT;
110
lockobj(Lcki+r, sizeof(int), 1);
111
if(Lcki[r] != Pnum)
112
terror("Process %3d(pid=%d): bad int lock %d",
113
Pnum, Pid[Pnum], (int)Lcki[r]);
114
lockobj(Lcki+r, sizeof(int), 0);
115
116
r = random()%N_SLOT;
117
lockobj(Lcks+r, sizeof(short), 1);
118
if(Lcks[r] != Pnum)
119
terror("Process %3d(pid=%d): bad short lock %d",
120
Pnum, Pid[Pnum], (int)Lcks[r]);
121
lockobj(Lcks+r, sizeof(short), 0);
122
123
r = random()%N_SLOT;
124
lockobj(Lckc+r, sizeof(char), 1);
125
if(Lckc[r] != Pnum)
126
terror("Process %3d(pid=%d): bad char lock %d",
127
Pnum, Pid[Pnum], (int)Lckc[r]);
128
lockobj(Lckc+r, sizeof(char), 0);
129
}
130
asoincint(Done);
131
}
132
133
tmain()
134
{
135
ssize_t k, z;
136
Void_t *addr;
137
int zerof;
138
pid_t pid;
139
140
taso(ASO_PROCESS);
141
if (!Tstall && !(asometh(0, 0)->type & ASO_INTRINSIC))
142
{
143
twarn("only ASO_INTRINSIC methods are tested by default");
144
texit(0);
145
}
146
tchild();
147
148
if((zerof = open("/dev/zero", O_RDWR)) < 0)
149
terror("Can't open /dev/zero");
150
151
/* get shared memory */
152
z = sizeof(*Nproc) + (N_PROC+1)*sizeof(pid_t) + sizeof(*Done) +
153
N_SLOT*sizeof(unsigned char) +
154
N_SLOT*sizeof(unsigned short) +
155
N_SLOT*sizeof(unsigned int);
156
addr = mmap(0,z,PROT_READ|PROT_WRITE,MAP_SHARED,zerof,0);
157
if(!addr || addr == (Void_t*)(-1))
158
terror("mmap failed");
159
memset(addr, 0, z);
160
161
Nproc = (unsigned int*)addr;
162
Pid = (pid_t*)(Nproc+1);
163
Done = (unsigned int*)(Pid + (N_PROC+1)*sizeof(pid_t));
164
Lcki = (unsigned int*)(Done + 1);
165
Lcks = (unsigned short*)(Lcki + N_SLOT);
166
Lckc = (unsigned char* )(Lcks + N_SLOT);
167
168
for(k = 1; k <= N_PROC; ++k)
169
{ if((pid = fork()) < 0 )
170
terror("Can't create a child process");
171
else if(pid > 0 ) /* parent process */
172
{ Pid[k] = pid; *Nproc += 1;
173
continue;
174
}
175
else /* child process */
176
{ for(;; usleep(1000) ) /* wait until all are alive */
177
if(*Nproc == N_PROC)
178
break;
179
workload(k); /* now start working concurrently */
180
texit(0);
181
}
182
}
183
184
if (twait(Pid+1, N_PROC))
185
terror("workload subprocess error");
186
187
if(*Done != N_PROC)
188
terror("Some subprocess did not finish its workload");
189
190
texit(0);
191
}
192
193