Skip to contentSkip to conversation

Provide system call to get task id

PATCH In review Dave McCracken 6 participants 9 messages Oct 8, 2001

Subsystems (8)
Arm (32-bit) MIPS s390 SuperH +4 more subsystems
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Provide system call to get task id

In the current thread group implementation getpid() returns the thread group leader. There is currently no way for a task in a thread group to find its true pid.

This patch provides a new system call gettid() (get task id), which returns the true pid of the task. This is needed in some multi-threaded apps and libraries.

Dave McCracken

======================================================================
Dave McCracken IBM Linux Base Kernel Team 1-512-838-3059
[email protected] T/L 678-3059

==========

arch/i386/kernel/entry.S +0 -0
@@ -619,6 +619,7 @@
	.long SYMBOL_NAME(sys_madvise)
	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_gettid)
	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */

	.rept NR_syscalls-(.-sys_call_table)/4
arch/alpha/kernel/entry.S +0 -0
@@ -10,7 +10,7 @@
 

#define SIGCHLD 20

-#define NR_SYSCALLS 378
+#define NR_SYSCALLS 379

/*
* These offsets must match with alpha_mv in <asm/machvec.h>.
@@ -1145,3 +1145,4 @@

	.quad sys_mincore			/* 375 */
	.quad sys_pciconfig_iobase
	.quad sys_getdents64

+ .quad sys_gettid

arch/sparc/kernel/systbls.S +0 -0
@@ -165,5 +165,6 @@

.long sunos_nosys, sunos_nosys
/*250*/ .long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
+ .long sys_gettid

#endif

arch/mips/kernel/syscalls.h +0 -0
@@ -235,3 +235,4 @@

SYS(sys_madvise, 3)
SYS(sys_getdents64, 3)
SYS(sys_fcntl64, 3) /* 4220 */
+SYS(sys_gettid, 0)

arch/ppc/kernel/misc.S +0 -0
@@ -1120,6 +1120,7 @@
	.long sys_fcntl64		/* 204 */
	.long sys_madvise		/* 205 */
	.long sys_mincore		/* 206 */
+	.long sys_gettid		/* 207 */
	.rept NR_syscalls-(.-sys_call_table)/4
		.long sys_ni_syscall
	.endr
arch/m68k/kernel/entry.S +0 -0
@@ -646,6 +646,7 @@
	.long SYMBOL_NAME(sys_ni_syscall)
	.long SYMBOL_NAME(sys_ni_syscall)
	.long SYMBOL_NAME(sys_getdents64)	/* 220 */

+ .long SYMBOL_NAME(sys_gettid)

	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
		.long SYMBOL_NAME(sys_ni_syscall)
arch/sparc64/kernel/systbls.S +0 -0
@@ -225,5 +225,6 @@

.word sunos_nosys, sunos_nosys
/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sys_aplib
+ .word sys_gettid

#endif

arch/arm/kernel/calls.S +0 -0
@@ -236,6 +236,7 @@

.long SYMBOL_NAME(sys_mincore)
/* 220 */ .long SYMBOL_NAME(sys_madvise)

		.long	SYMBOL_NAME(sys_fcntl64)

+ .long SYMBOL_NAME(sys_gettid)
__syscall_end:

		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
arch/sh/kernel/entry.S +0 -0
@@ -1298,6 +1298,7 @@
	.long SYMBOL_NAME(sys_madvise)
	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
	.long SYMBOL_NAME(sys_fcntl64)

+ .long SYMBOL_NAME(sys_gettid)

	/*
	 * NOTE!! This doesn't have to be exact - we just have

@@ -1305,7 +1306,7 @@
* entries. Don't panic if you notice that this hasn't
* been shrunk every time we add a new system call. */
- .rept NR_syscalls-221
+ .rept NR_syscalls-222
.long SYMBOL_NAME(sys_ni_syscall)
.endr

arch/mips64/kernel/scall_64.S +0 -0
@@ -347,3 +347,4 @@

PTR sys_mincore
PTR sys_madvise
PTR sys_getdents64
+ PTR sys_gettid

arch/mips64/kernel/scall_o32.S +0 -0
@@ -454,6 +454,7 @@
	sys	sys_madvise	3
	sys	sys_getdents64	3
	sys	sys32_fcntl64	3			/* 4220 */

+ sys sys_gettid 0
.endm

.macro sys function, nargs

arch/s390/kernel/entry.S +0 -0
@@ -559,7 +559,8 @@
        .long  sys_madvise
	.long  sys_getdents64		 /* 220 */
        .long  sys_fcntl64
-	.rept  255-221
+        .long  sys_gettid
+	.rept  255-222

.long sys_ni_syscall
.endr

arch/parisc/kernel/syscall.S +0 -0
@@ -552,6 +552,7 @@
	ENTRY_UHOH(shmctl)		/* 195 */
	ENTRY_SAME(ni_syscall)		/* streams1 */
	ENTRY_SAME(ni_syscall)		/* streams2 */

+ ENTRY_SAME(gettid)

.end

arch/cris/kernel/entry.S +0 -0
@@ -966,6 +966,7 @@
	.long SYMBOL_NAME(sys_madvise)
	.long SYMBOL_NAME(sys_getdents64)       /* 220 */
	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_gettid)
	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */

        /*

@@ -975,7 +976,7 @@
* been shrunk every time we add a new system call. */

- .rept NR_syscalls-222
+ .rept NR_syscalls-223
.long SYMBOL_NAME(sys_ni_syscall)
.endr

arch/s390x/kernel/entry.S +0 -0
@@ -594,7 +594,8 @@
        .long  SYSCALL(sys_madvise,sys32_madvise_wrapper)
	.long  SYSCALL(sys_getdents64,sys32_getdents64_wrapper)/* 220 */
	.long  SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper)
-        .rept  255-221
+	.long  SYSCALL(sys_gettid,sys_gettid)
+        .rept  255-222

.long SYSCALL(sys_ni_syscall,sys_ni_syscall) .endr

include/asm-i386/unistd.h +0 -0
@@ -227,6 +227,7 @@

#define __NR_madvise1 219 /* delete when C lib stub is removed */
#define __NR_getdents64 220
#define __NR_fcntl64 221
+#define __NR_gettid 222

/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */

include/asm-mips/unistd.h +0 -0
@@ -233,11 +233,12 @@

#define __NR_madvise (__NR_Linux + 218)
#define __NR_getdents64 (__NR_Linux + 219)
#define __NR_fcntl64 (__NR_Linux + 220)
+#define __NR_gettid (__NR_Linux + 221)

/*
* Offset of the last Linux flavoured syscall
*/
-#define __NR_Linux_syscalls 220
+#define __NR_Linux_syscalls 221

#ifndef _LANGUAGE_ASSEMBLY

include/asm-alpha/unistd.h +0 -0
@@ -315,6 +315,7 @@

#define __NR_mincore 375
#define __NR_pciconfig_iobase 376
#define __NR_getdents64 377
+#define __NR_gettid 378

#if defined(__GNUC__)

include/asm-m68k/unistd.h +0 -0
@@ -222,6 +222,7 @@

#define __NR_setfsuid32 215
#define __NR_setfsgid32 216
#define __NR_getdents64 220
+#define __NR_gettid 221

/* user-visible error numbers are in the range -1 - -122: see
<asm-m68k/errno.h> */

include/asm-sparc/unistd.h +0 -0
@@ -271,6 +271,7 @@
#define __NR_fdatasync          253
#define __NR_nfsservctl         254
#define __NR_aplib              255

+#define __NR_gettid 256

#define _syscall0(type,name) \
type name(void) \

include/asm-ppc/unistd.h +0 -0
@@ -213,6 +213,7 @@

#define __NR_fcntl64 204
#define __NR_madvise 205
#define __NR_mincore 206
+#define __NR_gettid 207

#define __NR(n) #n

include/asm-sparc64/unistd.h +0 -0
@@ -273,6 +273,7 @@
#define __NR_fdatasync          253
#define __NR_nfsservctl         254
#define __NR_aplib              255

+#define __NR_gettid 256

#define _syscall0(type,name) \
type name(void) \

include/asm-arm/unistd.h +0 -0
@@ -240,6 +240,7 @@

#define __NR_mincore (__NR_SYSCALL_BASE+219)
#define __NR_madvise (__NR_SYSCALL_BASE+220)
#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
+#define __NR_gettid (__NR_SYSCALL_BASE+222)

/*
* The following SWIs are ARM private.

include/asm-sh/unistd.h +0 -0
@@ -231,6 +231,7 @@

#define __NR_madvise 219
#define __NR_getdents64 220
#define __NR_fcntl64 221
+#define __NR_gettid 222

/* user-visible error numbers are in the range -1 - -125: see <asm-sh/errno.h> */

include/asm-ia64/unistd.h +0 -0
@@ -205,6 +205,7 @@

#define __NR_clone2 1213
#define __NR_getdents64 1214
#define __NR_getunwind 1215
+#define __NR_gettid 1216

#if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)

include/asm-mips64/unistd.h +0 -0
@@ -461,11 +461,12 @@

#define __NR_mincore (__NR_Linux + 211)
#define __NR_madvise (__NR_Linux + 212)
#define __NR_getdents64 (__NR_Linux + 213)
+#define __NR_gettid (__NR_Linux + 214)

/*
* Offset of the last Linux flavoured syscall
*/
-#define __NR_Linux_syscalls 213
+#define __NR_Linux_syscalls 214

#ifndef _LANGUAGE_ASSEMBLY

include/asm-s390/unistd.h +0 -0
@@ -209,6 +209,7 @@

#define __NR_mincore 218
#define __NR_madvise 219
#define __NR_getdents64 220
+#define __NR_gettid 221

/* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */

include/asm-parisc/unistd.h +0 -0
@@ -689,8 +689,9 @@
 
#define __NR_getpmsg            (__NR_Linux + 196)      /* some people actually want streams */
#define __NR_putpmsg            (__NR_Linux + 197)      /* some people actually want streams */

+#define __NR_gettid (__NR_Linux + 198)

-#define __NR_Linux_syscalls 197
+#define __NR_Linux_syscalls 198

#define HPUX_GATEWAY_ADDR 0xC0000004
#define LINUX_GATEWAY_ADDR 0x100

include/asm-cris/unistd.h +0 -0
@@ -227,6 +227,7 @@

#define __NR_madvise 219
#define __NR_getdents64 220
#define __NR_fcntl64 221
+#define __NR_gettid 222

/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \

include/asm-s390x/unistd.h +0 -0
@@ -179,6 +179,7 @@
#define __NR_mincore            218
#define __NR_madvise            219
#define __NR_getdents64         220

+#define __NR_gettid 222

/* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */

kernel/timer.c +0 -0
@@ -794,6 +794,11 @@
 

#endif

+asmlinkage long sys_gettid(void)
+{
+ return current->pid;
+}
+
asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)

{
	struct timespec t;
#1 lore raw

arch/i386/kernel/entry.S line 623

Quoted 8 lines · In article <71000000.1002555975@baldur> you wrote:
arch/i386/kernel/entry.S +1 -0
@@ -619,6 +619,7 @@
 	.long SYMBOL_NAME(sys_madvise)
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
 	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_gettid)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */

I think there was a reason why this syscall is marked reserved, could you add it as Nr 224? (223 is reserved in 2.4.11-pre as well).

Christoph

Signature · 1 line
Of course it doesn't work. We've performed a software upgrade.
#2 lore raw
Quoted 6 lines

Review

Quoted 3 lines
(quoted diff) +1 -0
 	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_gettid)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */

I think there was a reason why this syscall is marked reserved, could you add it as Nr 224? (223 is reserved in 2.4.11-pre as well).

Yep - 223 is provisionally the security() syscall for the LSM project

#3 lore raw
In reply to Dave McCracken
Quoted 3 lines

This patch provides a new system call gettid() (get task id), which returns the true pid of the task. This is needed in some multi-threaded apps and libraries.

Really the fix is to back out the stupid getpid hack. The thread group is known by user space and can be managed by user space

#4 lore raw
Quoted 3 lines · Alan Cox

Really the fix is to back out the stupid getpid hack. The thread group is known by user space and can be managed by user space

I agree on a purely technical level, but the same could be said about all the other group ID stuff too, so..

I'll add a gettid(), except I won't be moving reserved system calls around. I didn't even realize I had removed gettid - it was there in the 2.4.0-test kernels that implemented the signal groups, and I meant to only revert the unsafe signals stuff..

Linus

#5 lore raw
Quoted 4 lines

I'll add a gettid(), except I won't be moving reserved system calls around. I didn't even realize I had removed gettid - it was there in the 2.4.0-test kernels that implemented the signal groups, and I meant to only revert the unsafe signals stuff..

Would it make more sense to add a getpid() and make the existing one gettid() to keep compatibility at its sanest ?

#6 lore raw
Quoted 3 lines · Alan Cox

Would it make more sense to add a getpid() and make the existing one gettid() to keep compatibility at its sanest ?

I don't think compatibility is an issue: programs that are (a) threaded and (b) use the new thread group interface and (c) care about tid simply do not exist. For the simple reason that they cannot exist - getpid() was changed at the same time CLONE_THREAD was added.

So the only compatibility worry would be

- people using non-thread-aware libraries together with a CLONE_THREAD core thing - which is possible especially if they have thread wrappers. But if those libraries care about "pid/tid" issues, there's no way that can have well-defined behaviour anyway ;)

- people who have been playing with CLONE_THREAD, and have apps that depend on the "pid is the 'classical' pid, not the thread ID" behaviour. In which case adding a new gettid() is the right thing to do.

Now, I actually seriously doubt either of those are real issues, and it probably doesn't matter what we do. But I'd ratehr have a system call called "getpid()" do what POSIX threads have traditionally done, namely give the ID of the process group ("tpid" in linux kernel-speak), and have "gettid()" give the thread ID ("pid" in linux kernel-speak).

Linus

#7 lore raw
In reply to Alan Cox

In article <[email protected]>,

Quoted 5 lines · Linus Torvalds

Now, I actually seriously doubt either of those are real issues, and it probably doesn't matter what we do. But I'd ratehr have a system call called "getpid()" do what POSIX threads have traditionally done, namely give the ID of the process group ("tpid" in linux kernel-speak), and have "gettid()" give the thread ID ("pid" in linux kernel-speak).

The kernel doesn't have pthread support - glibc emulates it using clone(). Shouldn't glibc then not also be the one to do the getpid() / gettid() switching internally only for applications linked agains libpthread ?

If you want to have thread IDs I think you should go all the way and make thread groups a real entity like sessions and process groups. Setsid() would reset the thread group ID like it now also resets the process group ID. Ditto for setpgrp() I think. A session can contain several process groups which can contain several thread groups.

There should be a way to signal all processes in a thread group- perhaps that should even be the default, a signal to any process in the group should be delivered to all of them. Or perhaps only for SIGSTOP and SIGKILL, all other signals could be delivered to the thread group leader.

Anyway, food for thought.

Mike.

Signature · 1 line
Move sig.
#8 lore raw
In reply to Alan Cox

While we're at it, we should probably be exporting the tgid from /proc/$pid/status.

Index: fs/proc/array.c
===================================================================
RCS file: /inst/cvs/linux/fs/proc/array.c,v
retrieving revision 1.5.2.32

proc/array.c +2 -1
diff -u -r1.5.2.32 array.c
@@ -151,12 +151,13 @@
 	read_lock(&tasklist_lock);
 	buffer += sprintf(buffer,
 		"State:\t%s\n"
+		"Tgid:\t%d\n"
 		"Pid:\t%d\n"
 		"PPid:\t%d\n"
 		"TracerPid:\t%d\n"
 		"Uid:\t%d\t%d\t%d\t%d\n"
 		"Gid:\t%d\t%d\t%d\t%d\n",
-		get_task_state(p),
+		get_task_state(p), p->tgid,
 		p->pid, p->pid ? p->p_opptr->pid : 0, 0,
 		p->uid, p->euid, p->suid, p->fsuid,
 		p->gid, p->egid, p->sgid, p->fsgid);

--
dwmw2