1145519Sdarrenr/*	$FreeBSD: stable/11/contrib/ipfilter/lib/rwlock_emul.c 314251 2017-02-25 08:07:28Z cy $	*/
2145510Sdarrenr
3170268Sdarrenr/*
4255332Scy * Copyright (C) 2012 by Darren Reed.
5255332Scy *
6255332Scy * See the IPFILTER.LICENCE file for details on licencing.
7255332Scy *
8255332Scy * $Id$
9255332Scy */
10170268Sdarrenr
11145510Sdarrenr#include "ipf.h"
12145510Sdarrenr
13145510Sdarrenr#define	EMM_MAGIC	0x97dd8b3a
14145510Sdarrenr
15145510Sdarrenrvoid eMrwlock_read_enter(rw, file, line)
16255332Scy	eMrwlock_t *rw;
17255332Scy	char *file;
18255332Scy	int line;
19145510Sdarrenr{
20145510Sdarrenr	if (rw->eMrw_magic != EMM_MAGIC) {
21145510Sdarrenr		fprintf(stderr, "%s:eMrwlock_read_enter(%p): bad magic: %#x\n",
22145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_magic);
23145510Sdarrenr		abort();
24145510Sdarrenr	}
25145510Sdarrenr	if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
26145510Sdarrenr		fprintf(stderr,
27145510Sdarrenr			"%s:eMrwlock_read_enter(%p): already locked: %d/%d\n",
28145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
29145510Sdarrenr		abort();
30145510Sdarrenr	}
31145510Sdarrenr	rw->eMrw_read++;
32145510Sdarrenr	rw->eMrw_heldin = file;
33145510Sdarrenr	rw->eMrw_heldat = line;
34145510Sdarrenr}
35145510Sdarrenr
36145510Sdarrenr
37145510Sdarrenrvoid eMrwlock_write_enter(rw, file, line)
38255332Scy	eMrwlock_t *rw;
39255332Scy	char *file;
40255332Scy	int line;
41145510Sdarrenr{
42145510Sdarrenr	if (rw->eMrw_magic != EMM_MAGIC) {
43145510Sdarrenr		fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
44145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_magic);
45145510Sdarrenr		abort();
46145510Sdarrenr	}
47145510Sdarrenr	if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
48145510Sdarrenr		fprintf(stderr,
49145510Sdarrenr			"%s:eMrwlock_write_enter(%p): already locked: %d/%d\n",
50145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
51145510Sdarrenr		abort();
52145510Sdarrenr	}
53145510Sdarrenr	rw->eMrw_write++;
54145510Sdarrenr	rw->eMrw_heldin = file;
55145510Sdarrenr	rw->eMrw_heldat = line;
56145510Sdarrenr}
57145510Sdarrenr
58145510Sdarrenr
59314251Scyvoid eMrwlock_try_upgrade(rw, file, line)
60314251Scy	eMrwlock_t *rw;
61314251Scy	char *file;
62314251Scy	int line;
63314251Scy{
64314251Scy	if (rw->eMrw_magic != EMM_MAGIC) {
65314251Scy		fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
66314251Scy			rw->eMrw_owner, rw, rw->eMrw_magic);
67314251Scy		abort();
68314251Scy	}
69314251Scy	if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
70314251Scy		fprintf(stderr,
71314251Scy			"%s:eMrwlock_try_upgrade(%p): already locked: %d/%d\n",
72314251Scy			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
73314251Scy		abort();
74314251Scy	}
75314251Scy	rw->eMrw_write++;
76314251Scy	rw->eMrw_heldin = file;
77314251Scy	rw->eMrw_heldat = line;
78314251Scy}
79314251Scy
80145510Sdarrenrvoid eMrwlock_downgrade(rw, file, line)
81255332Scy	eMrwlock_t *rw;
82255332Scy	char *file;
83255332Scy	int line;
84145510Sdarrenr{
85145510Sdarrenr	if (rw->eMrw_magic != EMM_MAGIC) {
86145510Sdarrenr		fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
87145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_magic);
88145510Sdarrenr		abort();
89145510Sdarrenr	}
90145510Sdarrenr	if (rw->eMrw_read != 0 || rw->eMrw_write != 1) {
91145510Sdarrenr		fprintf(stderr,
92145510Sdarrenr			"%s:eMrwlock_write_enter(%p): already locked: %d/%d\n",
93145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
94145510Sdarrenr		abort();
95145510Sdarrenr	}
96145510Sdarrenr	rw->eMrw_write--;
97145510Sdarrenr	rw->eMrw_read++;
98145510Sdarrenr	rw->eMrw_heldin = file;
99145510Sdarrenr	rw->eMrw_heldat = line;
100145510Sdarrenr}
101145510Sdarrenr
102145510Sdarrenr
103145510Sdarrenrvoid eMrwlock_exit(rw)
104255332Scy	eMrwlock_t *rw;
105145510Sdarrenr{
106145510Sdarrenr	if (rw->eMrw_magic != EMM_MAGIC) {
107145510Sdarrenr		fprintf(stderr, "%s:eMrwlock_exit(%p): bad magic: %#x\n",
108145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_magic);
109145510Sdarrenr		abort();
110145510Sdarrenr	}
111145510Sdarrenr	if (rw->eMrw_read != 1 && rw->eMrw_write != 1) {
112145510Sdarrenr		fprintf(stderr, "%s:eMrwlock_exit(%p): not locked: %d/%d\n",
113145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
114145510Sdarrenr		abort();
115145510Sdarrenr	}
116145510Sdarrenr	if (rw->eMrw_read == 1)
117145510Sdarrenr		rw->eMrw_read--;
118145510Sdarrenr	else if (rw->eMrw_write == 1)
119145510Sdarrenr		rw->eMrw_write--;
120145510Sdarrenr	rw->eMrw_heldin = NULL;
121145510Sdarrenr	rw->eMrw_heldat = 0;
122145510Sdarrenr}
123145510Sdarrenr
124145510Sdarrenr
125255332Scystatic int initcount = 0;
126255332Scy
127145510Sdarrenrvoid eMrwlock_init(rw, who)
128255332Scy	eMrwlock_t *rw;
129255332Scy	char *who;
130145510Sdarrenr{
131145510Sdarrenr	if (rw->eMrw_magic == EMM_MAGIC) {	/* safe bet ? */
132145510Sdarrenr		fprintf(stderr,
133145510Sdarrenr			"%s:eMrwlock_init(%p): already initialised?: %#x\n",
134145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_magic);
135145510Sdarrenr		abort();
136145510Sdarrenr	}
137145510Sdarrenr	rw->eMrw_magic = EMM_MAGIC;
138145510Sdarrenr	rw->eMrw_read = 0;
139145510Sdarrenr	rw->eMrw_write = 0;
140145510Sdarrenr	if (who != NULL)
141145510Sdarrenr		rw->eMrw_owner = strdup(who);
142145510Sdarrenr	else
143145510Sdarrenr		rw->eMrw_owner = NULL;
144255332Scy	initcount++;
145145510Sdarrenr}
146145510Sdarrenr
147145510Sdarrenr
148145510Sdarrenrvoid eMrwlock_destroy(rw)
149255332Scy	eMrwlock_t *rw;
150145510Sdarrenr{
151145510Sdarrenr	if (rw->eMrw_magic != EMM_MAGIC) {
152145510Sdarrenr		fprintf(stderr, "%s:eMrwlock_destroy(%p): bad magic: %#x\n",
153145510Sdarrenr			rw->eMrw_owner, rw, rw->eMrw_magic);
154145510Sdarrenr		abort();
155145510Sdarrenr	}
156255332Scy	if (rw->eMrw_owner != NULL)
157255332Scy		free(rw->eMrw_owner);
158145510Sdarrenr	memset(rw, 0xa5, sizeof(*rw));
159255332Scy	initcount--;
160145510Sdarrenr}
161255332Scy
162255332Scyvoid ipf_rwlock_clean()
163255332Scy{
164255332Scy	if (initcount != 0)
165255332Scy		abort();
166255332Scy}
167