GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/gen/errno.c Lines: 1 1 100.0 %
Date: 2017-11-07 Branches: 0 0 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: errno.c,v 1.6 2016/05/07 19:05:22 guenther Exp $ */
2
/* PUBLIC DOMAIN: No Rights Reserved.   Marco S Hyman <marc@snafu.org> */
3
4
#include <tib.h>
5
#include <errno.h>
6
#include <unistd.h>
7
#include "thread_private.h"
8
9
10
#ifdef TCB_HAVE_MD_GET
11
/*
12
 * If there's an MD TCB_GET() macro, then getting the TCB address is
13
 * cheap enough that we can do it even in single-threaded programs,
14
 * so the tc_errnoptr and tc_tcb callbacks will be unused, and __errno()
15
 * can just use TIB_GET().
16
 */
17
int *
18
__errno(void)
19
{
20
951334618
	return (&TIB_GET()->tib_errno);
21
}
22
DEF_STRONG(__errno);
23
24
#else /* ! TCB_HAVE_MD_GET */
25
/*
26
 * Otherwise, getting the TCB address requires the __get_tcb()
27
 * syscall.  Rather than pay that cost for single-threaded programs,
28
 * the syscall stubs will invoke the tc_errnoptr callback to set errno
29
 * and other code will invoke the tc_tcb callback to get the TCB
30
 * for cancelation checks, etc.  The default callbacks will just
31
 * work from the cached location of the initial thread's TCB;
32
 * libpthread can override them to the necessary more expensive
33
 * versions that use __get_tcb().
34
 */
35
36
/* cached pointer to the TCB of the only thread in single-threaded programs */
37
void	*_libc_single_tcb = NULL;
38
39
static inline void *
40
single_threaded_tcb(void)
41
{
42
	if (__predict_false(_libc_single_tcb == NULL))
43
		_libc_single_tcb = TCB_GET();
44
	return (_libc_single_tcb);
45
}
46
47
static int *
48
single_threaded_errnoptr(void)
49
{
50
	return &TCB_TO_TIB(single_threaded_tcb())->tib_errno;
51
}
52
53
/*
54
 * __errno(): just use the callback to get the applicable current method
55
 */
56
int *
57
__errno(void)
58
{
59
	return (_thread_cb.tc_errnoptr());
60
}
61
DEF_STRONG(__errno);
62
63
#endif /* !TCB_HAVE_MD_GET */
64
65
66
struct thread_callbacks _thread_cb =
67
{
68
#ifndef	TCB_HAVE_MD_GET
69
	.tc_errnoptr	= &single_threaded_errnoptr,
70
	.tc_tcb		= &single_threaded_tcb,
71
#endif
72
};