Home > database >  Can syscall(SYS_gettid) block?
Can syscall(SYS_gettid) block?

Time:12-29

My understanding is that some if not all syscalls can be blocking. Is this a blocking call? I want to obtain a unique thread id in a function that gets called repeatedly and is time-sensitive. I was going to do like so:

//header.h
#define _GNU_SOURCE
#include <sys/syscall.h>
#ifdef SYS_gettid
#define gettid() syscall(SYS_gettid)
#else
#define gettid() 0
#endif
//file.c
#include "header.h"
...
void function()
{
        pid_t thread = gettid();
        //Logic based on thread
        ...
}

Here function will get called repeatedly and cannot block. Perhaps I should use pthread_self() and pthread_equal(t1, t2)? Thanks.

EDIT: I could equally well use either. I understand they do not provide the same return values, but the logic I will perform on the thread id is to compare it to a set of known thread ids to basically figure out who is calling this. I have both the gettid() return value and the pthread_self() reutrn value saved off.

CodePudding user response:

You should use pthread_self, mostly because it's portable and syscall(SYS_gettid) isn't, but also because typical implementations don't need to trap into the kernel at all. For instance, on the machine where I'm typing this, there is a special hardware register called tpidr_el0 that stores a pointer to thread-specific data, and so pthread_self can be just three instructions, with no privilege level change required:

0000000000077870 <pthread_self>:
   77870:       d53bd040        mrs     x0, tpidr_el0
   77874:       d11e4000        sub     x0, x0, #0x790
   77878:       d65f03c0        ret

To be fair, a system call on this architecture is also just a handful of instructions, e.g.

00000000000a67c0 <getpid>:
   a67c0:       d503245f        bti     c
   a67c4:       d2801588        mov     x8, #0xac
   a67c8:       d4000001        svc     #0x0
   a67cc:       d65f03c0        ret 

but an assembly dump of the syscall stub does not show the hundreds or even thousands of cycles worth of costs hiding behind that svc instruction. If you're doing something frequent and time-sensitive, not trapping into the kernel can be a huge win.

I'd also recommend you think about reorganizing your code so that work comes in bigger batches and you don't need to ask "what thread am I on?" so often. Operations not done at all are always fastest.

  • Related