16acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak/******************************************************************************
26acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
31378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modak *   Copyright © International Business Machines  Corp., 2005, 2008
46acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
56acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   This program is free software;  you can redistribute it and/or modify
66acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   it under the terms of the GNU General Public License as published by
76acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   the Free Software Foundation; either version 2 of the License, or
86acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   (at your option) any later version.
96acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
106acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   This program is distributed in the hope that it will be useful,
116acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
126acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
136acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   the GNU General Public License for more details.
146acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
156acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   You should have received a copy of the GNU General Public License
166acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *   along with this program;  if not, write to the Free Software
174548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
186acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
196acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * NAME
206acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *      testpi-4.c
216acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
226acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * DESCRIPTION
235305c4a10cf26799c81e6f0362750988457d3002Subrata Modak *     This testcase verifies that the SCHED_OTHER thread can preempt
245305c4a10cf26799c81e6f0362750988457d3002Subrata Modak *     the SCHED_RR thread via priority inheritance.
256acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
266acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * USAGE:
276acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *      Use run_auto.sh script in current directory to build and run test.
286acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
296acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * AUTHOR
306acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
316acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
326acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * HISTORY
3365f7070cb3f67eba009e68413187727f508623e1Subrata Modak *      2010-06-29 Thread synchronization changes by using
347d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper *		   conditional variables by Gowrishankar.
357d0a4a57fbcd47f72b67c08df532e8ef47f6fdaeGarrett Cooper *		   by Gowrishankar <gowrishankar.m@in.ibm.com>
366acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *
376acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak *****************************************************************************/
386acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
396acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdio.h>
406acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <stdlib.h>
416acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <string.h>
426acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <sched.h>
436acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <errno.h>
446acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <pthread.h>
456acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <sys/types.h>
466acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <sys/syscall.h>
476acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <unistd.h>
486acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak#include <librttest.h>
496acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
501378205b23aad2d399f74f0ab2e97a1cd3f8ecf9subrata_modakpthread_barrier_t barrier;
516acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
526acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakvoid usage(void)
536acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
54b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	rt_help();
55b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	printf("testpi-4 specific options:\n");
566acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
576acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
586acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint parse_args(int c, char *v)
596acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
60b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	int handled = 1;
61b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	switch (c) {
62b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	case 'h':
63b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		usage();
64b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		exit(0);
65b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	default:
66b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		handled = 0;
67b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		break;
68b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	}
69b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	return handled;
706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
726acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakint gettid(void)
736acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
74b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	return syscall(__NR_gettid);
756acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
766acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
77354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaotypedef void *(*entrypoint_t) (void *);
786acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modakpthread_mutex_t *glob_mutex;
7965f7070cb3f67eba009e68413187727f508623e1Subrata Modakstatic pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
8065f7070cb3f67eba009e68413187727f508623e1Subrata Modakstatic pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER;
816acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
82b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modakvoid *func_nonrt(void *arg)
836acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
84b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	struct thread *pthr = (struct thread *)arg;
85bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak	int i, tid = gettid();
86b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
87b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	printf("Thread %d started running with priority %d\n", tid,
88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       pthr->priority);
89b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	pthread_mutex_lock(glob_mutex);
90b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	printf("Thread %d at start pthread pol %d pri %d - Got global lock\n",
91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       tid, pthr->policy, pthr->priority);
9265f7070cb3f67eba009e68413187727f508623e1Subrata Modak
9365f7070cb3f67eba009e68413187727f508623e1Subrata Modak	/* Wait for other RT threads to start up */
94b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	pthread_barrier_wait(&barrier);
95b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
9665f7070cb3f67eba009e68413187727f508623e1Subrata Modak	/* Wait for the high priority noise thread to start and signal us */
9765f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_mutex_lock(&cond_mutex);
9865f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_cond_wait(&cond_var, &cond_mutex);
9965f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_mutex_unlock(&cond_mutex);
10065f7070cb3f67eba009e68413187727f508623e1Subrata Modak
101b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	for (i = 0; i < 10000; i++) {
102354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (i % 100 == 0) {
103b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak			printf("Thread %d loop %d pthread pol %d pri %d\n",
104354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       tid, i, pthr->policy, pthr->priority);
105b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak			fflush(NULL);
106b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		}
107bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak		busy_work_ms(1);
108b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	}
109b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	pthread_mutex_unlock(glob_mutex);
110b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	return NULL;
1116acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
1126acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
113b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modakvoid *func_rt(void *arg)
1146acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
115b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	struct thread *pthr = (struct thread *)arg;
116bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak	int i, tid = gettid();
117b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
118354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	printf("Thread %d started running with prio %d\n", tid, pthr->priority);
119b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	pthread_barrier_wait(&barrier);
120b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	pthread_mutex_lock(glob_mutex);
121b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	printf("Thread %d at start pthread pol %d pri %d - Got global lock\n",
122354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	       tid, pthr->policy, pthr->priority);
123b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
124b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	/* we just use the mutex as something to slow things down,
125b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	 * say who we are and then do nothing for a while.  The aim
126b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	 * of this is to show that high priority threads make more
127b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	 * progress than lower priority threads..
128b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	 */
129b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	for (i = 0; i < 1000; i++) {
130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (i % 100 == 0) {
131b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak			printf("Thread %d loop %d pthread pol %d pri %d\n",
132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       tid, i, pthr->policy, pthr->priority);
133b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak			fflush(NULL);
134b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		}
135bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak		busy_work_ms(1);
136b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	}
137b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	pthread_mutex_unlock(glob_mutex);
138b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	return NULL;
1396acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
1406acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
141b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modakvoid *func_noise(void *arg)
1426acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak{
143b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	struct thread *pthr = (struct thread *)arg;
144bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak	int i, tid = gettid();
145b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	printf("Noise Thread started running with prio %d\n", pthr->priority);
147b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	pthread_barrier_wait(&barrier);
148b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
149354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	/* Give the other threads time to wait on the condition variable. */
15065f7070cb3f67eba009e68413187727f508623e1Subrata Modak	usleep(1000);
15165f7070cb3f67eba009e68413187727f508623e1Subrata Modak
15265f7070cb3f67eba009e68413187727f508623e1Subrata Modak	/* Noise thread begins the test */
15365f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_mutex_lock(&cond_mutex);
15465f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_cond_broadcast(&cond_var);
15565f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_mutex_unlock(&cond_mutex);
15665f7070cb3f67eba009e68413187727f508623e1Subrata Modak
157b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	for (i = 0; i < 10000; i++) {
158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (i % 100 == 0) {
159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			printf("Noise Thread %d loop %d pthread pol %d "
160354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       "pri %d\n", tid, i, pthr->policy,
161354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			       pthr->priority);
162b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak			fflush(NULL);
163b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		}
164bd2dce17303a69463e926bb5a6a955e7890f65f3Subrata Modak		busy_work_ms(1);
165b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	}
166b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	return NULL;
1676acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak}
1686acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak
1696acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak/*
1706acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak * Test pthread creation at different thread priorities.
1716acdc8efa73ceb0c3b515cd34c333d929e8b4273subrata_modak */
172b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modakint main(int argc, char *argv[])
173b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak{
174a21dab25b7ef183d049b31b0d3fed1d48c16dc2bSubrata Modak	int i, retc, nopi = 0;
175b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	cpu_set_t mask;
176b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	CPU_ZERO(&mask);
177b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	CPU_SET(0, &mask);
178b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	setup();
179b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
180b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	rt_init("h", parse_args, argc, argv);
181b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
182b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	retc = pthread_barrier_init(&barrier, NULL, 5);
183b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	if (retc) {
184b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		printf("pthread_barrier_init failed: %s\n", strerror(retc));
185b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		exit(retc);
186b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	}
187b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
188b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	retc = sched_setaffinity(0, sizeof(mask), &mask);
189b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	if (retc < 0) {
190b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		printf("Main Thread: Can't set affinity: %d %s\n", retc,
191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		       strerror(retc));
192b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		exit(-1);
193b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	}
194b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	for (i = 0; i < argc; i++) {
195b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		if (strcmp(argv[i], "nopi") == 0)
196b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak			nopi = 1;
197b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	}
198b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
199b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	printf("Start %s\n", argv[0]);
200b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
201b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	glob_mutex = malloc(sizeof(pthread_mutex_t));
202b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	if (glob_mutex == NULL) {
203b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		printf("Malloc failed\n");
204b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak		exit(errno);
205b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	}
206b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
207a21dab25b7ef183d049b31b0d3fed1d48c16dc2bSubrata Modak	if (!nopi)
208a21dab25b7ef183d049b31b0d3fed1d48c16dc2bSubrata Modak		init_pi_mutex(glob_mutex);
209b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
210b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	create_other_thread(func_nonrt, NULL);
211b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	create_rr_thread(func_rt, NULL, 20);
212b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	create_rr_thread(func_rt, NULL, 30);
213b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	create_rr_thread(func_rt, NULL, 40);
214b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	create_rr_thread(func_noise, NULL, 40);
215b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
216b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	printf("Joining threads\n");
217b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	join_threads();
218b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak	printf("Done\n");
219b4f57c7d26b58f3d80b46340f10a397d21957866Subrata Modak
22065f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_mutex_destroy(glob_mutex);
22165f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_mutex_destroy(&cond_mutex);
22265f7070cb3f67eba009e68413187727f508623e1Subrata Modak	pthread_cond_destroy(&cond_var);
223ef78227f9275d780649e14a8785c6913c18b7462Cyril Hrubis
224ef78227f9275d780649e14a8785c6913c18b7462Cyril Hrubis	return 0;
225ef78227f9275d780649e14a8785c6913c18b7462Cyril Hrubis}
226