tlock.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder/***********************************************************************
e9458b1a7a19a63aa4c179f9ab20f4d50681c168Jens Elkner* *
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder* This software is part of the ast package *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* Copyright (c) 1999-2012 AT&T Intellectual Property *
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu* and is licensed under the *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* Eclipse Public License, Version 1.0 *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* by AT&T Intellectual Property *
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder* *
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder* A copy of the License is available at *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* http://www.eclipse.org/org/documents/epl-v10.html *
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* Information and Software Systems Research *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* AT&T Research *
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder* Florham Park NJ *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* Glenn Fowler <gsf@research.att.com> *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder* *
b35e053c2c5a5ea0f13decfd0303894861d82b4dJonathan von Schroeder***********************************************************************/
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder#include "terror.h"
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder#include <sys/mman.h>
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder/* Test concurrency locking based on Atomic Scalar Operations
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder**
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder** Written by Kiem-Phong Vo
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder*/
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder#ifndef N_PROC
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder#define N_PROC 16
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder#endif
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder#define N_SLOT 12 /* number of lock slots */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder#define N_STEP 1000 /* number of working steps */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederstatic int Pnum; /* process number */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederstatic unsigned int *Nproc; /* number of processes */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederstatic pid_t *Pid; /* process id */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederstatic unsigned char *Lckc; /* slots of char locks */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederstatic unsigned short *Lcks; /* slots of short locks */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederstatic unsigned int *Lcki; /* slots of int locks */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederstatic unsigned int *Done; /* count done workloads */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederint lockobj(void* lck, ssize_t size, int locking)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder{
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder int lckv, k, aso;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(locking == 0) /* unlocking a slot */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder { if(size == sizeof(char))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lckv = *((char*)lck);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else if(size == sizeof(short))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lckv = *((short*)lck);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else lckv = *((int*)lck);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(lckv != Pnum ) /* unlocking a wrong lock */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Process %3d(pid=%d): unlocking %d(pid=%d)?",
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum, Pid[Pnum], lckv);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(size == sizeof(char))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder aso = asocaschar(lck, Pnum, 0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else if(size == sizeof(short))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder aso = asocasshort(lck, Pnum, 0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else aso = asocasint(lck, Pnum, 0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(aso != Pnum) /* CAS failed! */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Process %3d(pid=%d): unlocking CAS error %d",
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum, Pid[Pnum], aso);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder return 0;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder }
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder for(k = 0;; ++k, usleep(100) ) /* locking a slot */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder { if(size == sizeof(char))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder aso = asocaschar(lck, 0, Pnum);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else if(size == sizeof(short))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder aso = asocasshort(lck, 0, Pnum);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else aso = asocasint(lck, 0, Pnum);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(aso == 0)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder break;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else if(aso < 0)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Process %3d(pid=%d): locking CAS error %d",
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum, Pid[Pnum], aso);
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder else if(k > 0 && (k%10000) == 0)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder twarn("Process %3d(pid=%d): locking loop %d blocked by %d",
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum, Pid[Pnum], k, aso);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder }
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder for(k = 0; k < 2; ++k, usleep(100) ) /* make sure that lock is good */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder { if(size == sizeof(char))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lckv = *((char*)lck);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else if(size == sizeof(short))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lckv = *((short*)lck);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else lckv = *((int*)lck);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(lckv != Pnum)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Process %3d(pid=%d): at step %d lock=%d?",
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum, Pid[Pnum], k, lckv);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder }
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder return 0;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder}
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroederstatic void workload(int pnum)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder{
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder int k, r;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum = pnum;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder for(k = 0; k < N_STEP; ++k)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder { if(k > 0 && (k%100) == 0)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder tinfo("Process %3d(pid=%d): progress to %d", Pnum, Pid[Pnum], k);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder r = random()%N_SLOT;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lockobj(Lcki+r, sizeof(int), 1);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(Lcki[r] != Pnum)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Process %3d(pid=%d): bad int lock %d",
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum, Pid[Pnum], (int)Lcki[r]);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lockobj(Lcki+r, sizeof(int), 0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder r = random()%N_SLOT;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lockobj(Lcks+r, sizeof(short), 1);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(Lcks[r] != Pnum)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Process %3d(pid=%d): bad short lock %d",
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum, Pid[Pnum], (int)Lcks[r]);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lockobj(Lcks+r, sizeof(short), 0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder r = random()%N_SLOT;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lockobj(Lckc+r, sizeof(char), 1);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(Lckc[r] != Pnum)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Process %3d(pid=%d): bad char lock %d",
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pnum, Pid[Pnum], (int)Lckc[r]);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder lockobj(Lckc+r, sizeof(char), 0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder }
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder asoincint(Done);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder}
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroedertmain()
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder{
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder ssize_t k, z;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Void_t *addr;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder int zerof;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder pid_t pid;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder taso(ASO_PROCESS);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if (!Tstall && !(asometh(0, 0)->type & ASO_INTRINSIC))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder {
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder twarn("only ASO_INTRINSIC methods are tested by default");
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder texit(0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder }
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder tchild();
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if((zerof = open("/dev/zero", O_RDWR)) < 0)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Can't open /dev/zero");
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder /* get shared memory */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder z = sizeof(*Nproc) + (N_PROC+1)*sizeof(pid_t) + sizeof(*Done) +
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder N_SLOT*sizeof(unsigned char) +
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder N_SLOT*sizeof(unsigned short) +
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder N_SLOT*sizeof(unsigned int);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder addr = mmap(0,z,PROT_READ|PROT_WRITE,MAP_SHARED,zerof,0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(!addr || addr == (Void_t*)(-1))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("mmap failed");
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder memset(addr, 0, z);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Nproc = (unsigned int*)addr;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Pid = (pid_t*)(Nproc+1);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Done = (unsigned int*)(Pid + (N_PROC+1)*sizeof(pid_t));
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Lcki = (unsigned int*)(Done + 1);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Lcks = (unsigned short*)(Lcki + N_SLOT);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder Lckc = (unsigned char* )(Lcks + N_SLOT);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder for(k = 1; k <= N_PROC; ++k)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder { if((pid = fork()) < 0 )
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Can't create a child process");
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else if(pid > 0 ) /* parent process */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder { Pid[k] = pid; *Nproc += 1;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder continue;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder }
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder else /* child process */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder { for(;; usleep(1000) ) /* wait until all are alive */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(*Nproc == N_PROC)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder break;
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder workload(k); /* now start working concurrently */
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder texit(0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder }
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder }
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if (twait(Pid+1, N_PROC))
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("workload subprocess error");
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder if(*Done != N_PROC)
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder terror("Some subprocess did not finish its workload");
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder texit(0);
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder}
c56a356d3fcc5e123efa790aab320781d94df3c7Jonathan von Schroeder