f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync/* $Id$ */
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync/** @file
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * IPRT - Threads (Part 2), Ring-0 Driver, Linux.
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync */
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2012 Oracle Corporation
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync *
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync * available from http://www.virtualbox.org. This file is free software;
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * The contents of this file may alternatively be used under the terms
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * of the Common Development and Distribution License Version 1.0
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution, in which case the provisions of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * CDDL are applicable instead of those of the GPL.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * You may elect to license modified versions of this file under the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * terms and conditions of either the GPL or the CDDL or both.
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync */
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync/*******************************************************************************
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync* Header Files *
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync*******************************************************************************/
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync#include "the-linux-kernel.h"
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync#include "internal/iprt.h"
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync
7d6e0aa02bf89fa403a13d5eac18a18b5a79893fvboxsync#include <iprt/assert.h>
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync#include <iprt/thread.h>
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync#include <iprt/err.h>
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync#include "internal/thread.h"
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync
6473a6585394a0255de9936152f2fd35d068b347vboxsync
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsyncRTDECL(RTTHREAD) RTThreadSelf(void)
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync{
7d6e0aa02bf89fa403a13d5eac18a18b5a79893fvboxsync return rtThreadGetByNative((RTNATIVETHREAD)current);
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync}
f4db180328f833f9fc9cb07a1a4a0bc948a47afevboxsync
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsyncDECLHIDDEN(int) rtThreadNativeInit(void)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync{
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync return VINF_SUCCESS;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync}
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsyncDECLHIDDEN(int) rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync{
c750a78e76a4f82628fdbfb6fb7cf6fd0647dfd3vboxsync#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync /* See comment near MAX_RT_PRIO in linux/sched.h for details on
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync sched_priority. */
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync int iSchedClass = SCHED_NORMAL;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync struct sched_param Param = { .sched_priority = MAX_PRIO - 1 };
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync switch (enmType)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync {
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync case RTTHREADTYPE_INFREQUENT_POLLER:
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync Param.sched_priority = MAX_RT_PRIO + 5;
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync break;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync case RTTHREADTYPE_EMULATION:
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync Param.sched_priority = MAX_RT_PRIO + 4;
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync break;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync case RTTHREADTYPE_DEFAULT:
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync Param.sched_priority = MAX_RT_PRIO + 3;
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync break;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync case RTTHREADTYPE_MSG_PUMP:
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync Param.sched_priority = MAX_RT_PRIO + 2;
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync break;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync case RTTHREADTYPE_IO:
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync iSchedClass = SCHED_FIFO;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync Param.sched_priority = MAX_RT_PRIO - 1;
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync break;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync case RTTHREADTYPE_TIMER:
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync iSchedClass = SCHED_FIFO;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync Param.sched_priority = 1; /* not 0 just in case */
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync break;
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync default:
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync AssertMsgFailed(("enmType=%d\n", enmType));
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync return VERR_INVALID_PARAMETER;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync }
da41353d6837bbc94e31da46f0698be45c106305vboxsync
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync sched_setscheduler(current, iSchedClass, &Param);
da41353d6837bbc94e31da46f0698be45c106305vboxsync#endif
e1cda3b0b3faa83df2fe0bf69e6938a6e7c4cb20vboxsync
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync return VINF_SUCCESS;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync}
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsyncDECLHIDDEN(int) rtThreadNativeAdopt(PRTTHREADINT pThread)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync{
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync return VERR_NOT_IMPLEMENTED;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync}
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
9ce74631b48301919057befb1e781c40cd7ecd73vboxsyncDECLHIDDEN(void) rtThreadNativeWaitKludge(PRTTHREADINT pThread)
9ce74631b48301919057befb1e781c40cd7ecd73vboxsync{
9ce74631b48301919057befb1e781c40cd7ecd73vboxsync /** @todo fix RTThreadWait/RTR0Term race on linux. */
9ce74631b48301919057befb1e781c40cd7ecd73vboxsync RTThreadSleep(1); NOREF(pThread);
9ce74631b48301919057befb1e781c40cd7ecd73vboxsync}
9ce74631b48301919057befb1e781c40cd7ecd73vboxsync
9ce74631b48301919057befb1e781c40cd7ecd73vboxsync
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsyncDECLHIDDEN(void) rtThreadNativeDestroy(PRTTHREADINT pThread)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync{
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync NOREF(pThread);
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync}
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 4)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync/**
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync * Native kernel thread wrapper function.
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync *
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync * This will forward to rtThreadMain and do termination upon return.
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync *
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync * @param pvArg Pointer to the argument package.
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync */
7995839c0b791ae2334df998d34dbccac12b3b41vboxsyncstatic int rtThreadNativeMain(void *pvArg)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync{
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync PRTTHREADINT pThread = (PRTTHREADINT)pvArg;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync rtThreadMain(pThread, (RTNATIVETHREAD)current, &pThread->szName[0]);
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync return 0;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync}
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync#endif
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsyncDECLHIDDEN(int) rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync{
1838cd1287a6f1ae0ee0609c41c69034413d5667vboxsync#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 4)
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync struct task_struct *NativeThread;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync RT_ASSERT_PREEMPTIBLE();
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
6a009dc020683987d94eddf63e0c6ef9a402810dvboxsync NativeThread = kthread_run(rtThreadNativeMain, pThreadInt, "iprt-%s", pThreadInt->szName);
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync if (IS_ERR(NativeThread))
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync return VERR_GENERAL_FAILURE;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync *pNativeThread = (RTNATIVETHREAD)NativeThread;
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync return VINF_SUCCESS;
1838cd1287a6f1ae0ee0609c41c69034413d5667vboxsync#else
1838cd1287a6f1ae0ee0609c41c69034413d5667vboxsync return VERR_NOT_IMPLEMENTED;
1838cd1287a6f1ae0ee0609c41c69034413d5667vboxsync#endif
7995839c0b791ae2334df998d34dbccac12b3b41vboxsync}
cb12b2c2d9bdfd913e4823c4780c55b6182d8d37vboxsync