1272343Sngie/*	$NetBSD: alloc.c,v 1.1 2010/06/14 21:06:09 pooka Exp $	*/
2272343Sngie
3272343Sngie/*-
4272343Sngie * Copyright (c) 2010 The NetBSD Foundation, Inc.
5272343Sngie * All rights reserved.
6272343Sngie *
7272343Sngie * Redistribution and use in source and binary forms, with or without
8272343Sngie * modification, are permitted provided that the following conditions
9272343Sngie * are met:
10272343Sngie * 1. Redistributions of source code must retain the above copyright
11272343Sngie *    notice, this list of conditions and the following disclaimer.
12272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
13272343Sngie *    notice, this list of conditions and the following disclaimer in the
14272343Sngie *    documentation and/or other materials provided with the distribution.
15272343Sngie *
16272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17272343Sngie * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18272343Sngie * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19272343Sngie * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20272343Sngie * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21272343Sngie * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22272343Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23272343Sngie * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25272343Sngie * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26272343Sngie * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27272343Sngie * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28272343Sngie */
29272343Sngie
30272343Sngie#include <sys/cdefs.h>
31272343Sngie#if !defined(lint)
32272343Sngie__RCSID("$NetBSD: alloc.c,v 1.1 2010/06/14 21:06:09 pooka Exp $");
33272343Sngie#endif /* !lint */
34272343Sngie
35272343Sngie#include <sys/param.h>
36272343Sngie#include <sys/condvar.h>
37272343Sngie#include <sys/kmem.h>
38272343Sngie#include <sys/kthread.h>
39272343Sngie#include <sys/mutex.h>
40272343Sngie#include <sys/pool.h>
41272343Sngie#include <sys/proc.h>
42272343Sngie
43272343Sngie#include <uvm/uvm.h>
44272343Sngie
45272343Sngie#include <rump/rumpuser.h>
46272343Sngie#include "kernspace.h"
47272343Sngie
48272343Sngiestatic void *store[32];
49272343Sngiestatic struct pool pp1, pp2;
50272343Sngie
51272343Sngiestatic kmutex_t mtx;
52272343Sngiestatic kcondvar_t kcv;
53272343Sngiestatic int curstat;
54272343Sngie
55272343Sngiestatic void
56272343Sngiehthr(void *arg)
57272343Sngie{
58272343Sngie	int i;
59272343Sngie
60272343Sngie	mutex_enter(&mtx);
61272343Sngie	curstat++;
62272343Sngie	cv_signal(&kcv);
63272343Sngie
64272343Sngie	while (curstat < 2)
65272343Sngie		cv_wait(&kcv, &mtx);
66272343Sngie	mutex_exit(&mtx);
67272343Sngie
68272343Sngie	/* try to guarantee that the sleep is triggered in PR_WAITOK */
69272343Sngie	while ((kernel_map->flags & VM_MAP_WANTVA) == 0)
70272343Sngie		kpause("take5", false, 1, NULL);
71272343Sngie
72272343Sngie	for (i = 0; i < __arraycount(store); i++) {
73272343Sngie		pool_put(&pp1, store[i]);
74272343Sngie	}
75272343Sngie
76272343Sngie	kthread_exit(0);
77272343Sngie}
78272343Sngie
79272343Sngievoid
80272343Sngierumptest_alloc(size_t thelimit)
81272343Sngie{
82272343Sngie	char *c;
83272343Sngie	int succ, i;
84272343Sngie
85272343Sngie	mutex_init(&mtx, MUTEX_DEFAULT, IPL_NONE);
86272343Sngie	cv_init(&kcv, "venailu");
87272343Sngie
88272343Sngie	kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, hthr, NULL, NULL, "h");
89272343Sngie
90272343Sngie	pool_init(&pp1, 1024, 0, 0, 0, "vara-allas",
91272343Sngie	    &pool_allocator_nointr, IPL_NONE);
92272343Sngie	pool_init(&pp2, 1024, 0, 0, 0, "allas",
93272343Sngie	    &pool_allocator_nointr, IPL_NONE);
94272343Sngie
95272343Sngie	for (i = 0; i < __arraycount(store); i++) {
96272343Sngie		store[i] = pool_get(&pp1, PR_NOWAIT);
97272343Sngie		if (store[i] == NULL) {
98272343Sngie			panic("pool_get store failed");
99272343Sngie		}
100272343Sngie	}
101272343Sngie
102272343Sngie	/* wait until other thread runs */
103272343Sngie	mutex_enter(&mtx);
104272343Sngie	while (curstat == 0)
105272343Sngie		cv_wait(&kcv, &mtx);
106272343Sngie	mutex_exit(&mtx);
107272343Sngie
108272343Sngie	for (succ = 0;; succ++) {
109272343Sngie		if (succ * 1024 > thelimit)
110272343Sngie			panic("managed to allocate over limit");
111272343Sngie		if ((c = pool_get(&pp2, PR_NOWAIT)) == NULL) {
112272343Sngie			mutex_enter(&mtx);
113272343Sngie			curstat++;
114272343Sngie			cv_signal(&kcv);
115272343Sngie			mutex_exit(&mtx);
116272343Sngie			if (pool_get(&pp2, PR_WAITOK) == NULL)
117272343Sngie				panic("pool get PR_WAITOK failed");
118272343Sngie			break;
119272343Sngie		}
120272343Sngie		*c = 'a';
121272343Sngie	}
122272343Sngie}
123