0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync/* $Id$ */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync/** @file
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * IPRT - RTThreadGetNativeState, linux implementation.
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync/*
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2010 Oracle Corporation
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync *
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * available from http://www.virtualbox.org. This file is free software;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * General Public License (GPL) as published by the Free Software
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync *
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * The contents of this file may alternatively be used under the terms
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * of the Common Development and Distribution License Version 1.0
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * VirtualBox OSE distribution, in which case the provisions of the
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * CDDL are applicable instead of those of the GPL.
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync *
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * You may elect to license modified versions of this file under the
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync * terms and conditions of either the GPL or the CDDL or both.
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync/*******************************************************************************
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync* Header Files *
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync*******************************************************************************/
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#define LOG_GROUP RTLOGGROUP_PROCESS
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include <iprt/thread.h>
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include "internal/iprt.h"
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include <iprt/assert.h>
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include <iprt/ctype.h>
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include <iprt/err.h>
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include <iprt/string.h>
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include "internal/thread.h"
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include <unistd.h>
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync#include <sys/fcntl.h>
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsyncRTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread)
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync{
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync RTTHREADNATIVESTATE enmRet = RTTHREADNATIVESTATE_INVALID;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync PRTTHREADINT pThread = rtThreadGet(hThread);
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync if (pThread)
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync {
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync enmRet = RTTHREADNATIVESTATE_UNKNOWN;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync char szName[512];
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync RTStrPrintf(szName, sizeof(szName), "/proc/self/task/%u/stat", pThread->tid);
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync int fd = open(szName, O_RDONLY, 0);
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync if (fd >= 0)
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync {
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync ssize_t cch = read(fd, szName, sizeof(szName) - 1);
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync close(fd);
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync if (cch > 0)
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync {
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync szName[cch] = '\0';
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync /* skip the pid, the (comm name) and stop at the status char. */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync const char *psz = szName;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync while ( *psz
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync && ( *psz != ')'
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync || !RT_C_IS_SPACE(psz[1])
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync || !RT_C_IS_ALPHA(psz[2])
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync || !RT_C_IS_SPACE(psz[3])
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync )
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync )
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync psz++;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync if (*psz == ')')
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync {
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync switch (psz[2])
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync {
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync case 'R': /* running */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync enmRet = RTTHREADNATIVESTATE_RUNNING;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync break;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync case 'S': /* sleeping */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync case 'D': /* disk sleeping */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync enmRet = RTTHREADNATIVESTATE_BLOCKED;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync break;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync case 'T': /* stopped or tracking stop */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync enmRet = RTTHREADNATIVESTATE_SUSPENDED;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync break;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync case 'Z': /* zombie */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync case 'X': /* dead */
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync enmRet = RTTHREADNATIVESTATE_TERMINATED;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync break;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync default:
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync AssertMsgFailed(("state=%c\n", psz[2]));
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync enmRet = RTTHREADNATIVESTATE_UNKNOWN;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync break;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync }
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync }
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync else
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync AssertMsgFailed(("stat='%s'\n", szName));
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync }
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync }
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync rtThreadRelease(pThread);
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync }
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync return enmRet;
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync}
0fcf82b2591711fa8980e8f5d9cad1b8f222d6d7vboxsync