/* We are trying to perform a static TLS relocation in MAP, but it was
dynamically loaded. This can only work if there is enough surplus in
the static TLS area already allocated for each running thread. If this
object's TLS segment is too big to fit, we fail. If it fits,
we set MAP->l_tls_offset and return.
This function intentionally does not return any value but signals error
directly, as static TLS should be rare and code handling it should
not be inlined as much as possible. */
int
internal_function
_dl_try_allocate_static_tls (struct link_map *map)
{
/* If we've already used the variable with dynamic access, or if the
alignment requirements are too high, fail. */
if (map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET
|| map->l_tls_align > GL(dl_tls_static_align))
{
fail:
return -1;
}
#if TLS_TCB_AT_TP
size_t freebytes;
size_t n;
size_t blsize;
freebytes = GL(dl_tls_static_size) - GL(dl_tls_static_used);
if (freebytes < TLS_TCB_SIZE)
goto fail;
freebytes -= TLS_TCB_SIZE;
blsize = map->l_tls_blocksize + map->l_tls_firstbyte_offset;
if (freebytes < blsize)
goto fail;
n = (freebytes - blsize) / map->l_tls_align;
size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
- map->l_tls_firstbyte_offset);
map->l_tls_offset = GL(dl_tls_static_used) = offset;
#elif TLS_DTV_AT_TP
size_t used;
size_t check;
size_t offset = roundup (GL(dl_tls_static_used), map->l_tls_align);
used = offset + map->l_tls_blocksize;
check = used;
/* dl_tls_static_used includes the TCB at the beginning. */
if (check > GL(dl_tls_static_size))
goto fail;
map->l_tls_offset = offset;
GL(dl_tls_static_used) = used;
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
/* If the object is not yet relocated we cannot initialize the
static TLS region. Delay it. */
if (map->l_real->l_relocated)
{
#ifdef SHARED
if (__builtin_expect (THREAD_DTV()[0].counter != GL(dl_tls_generation),
0))
/* Update the slot information data for at least the generation of
the DSO we are allocating data for. */
(void) _dl_update_slotinfo (map->l_tls_modid);
#endif
GL(dl_init_static_tls) (map);
}
else
map->l_need_tls_init = 1;
return 0;
}
static int
add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t *ps)
{
struct addrinfo hints, *res, *res0 = NULL;
char servname[10];
struct mx_hostentry *p;
const int count_inc = 10;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
snprintf(servname, sizeof(servname), "%d", port);
switch (getaddrinfo(host, servname, &hints, &res0)) {
case 0:
break;
case EAI_AGAIN:
case EAI_NONAME:
/*
* EAI_NONAME gets returned for:
* SMARTHOST set but DNS server not reachable -> defer
* SMARTHOST set but DNS server returns "host does not exist"
* -> buggy configuration
* -> either defer or bounce would be ok -> defer
* MX entry was returned by DNS server but name doesn't resolve
* -> hopefully transient situation -> defer
* all other DNS problems should have been caught earlier
* in dns_get_mx_list().
*/
goto out;
default:
return(-1);
}
for (res = res0; res != NULL; res = res->ai_next) {
if (*ps + 1 >= roundup(*ps, count_inc)) {
size_t newsz = roundup(*ps + 2, count_inc);
*he = reallocf(*he, newsz * sizeof(**he));
if (*he == NULL)
goto out;
}
p = &(*he)[*ps];
strlcpy(p->host, host, sizeof(p->host));
p->pref = pref;
p->ai = *res;
p->ai.ai_addr = NULL;
bcopy(res->ai_addr, &p->sa, p->ai.ai_addrlen);
getnameinfo((struct sockaddr *)&p->sa, p->ai.ai_addrlen,
p->addr, sizeof(p->addr),
NULL, 0, NI_NUMERICHOST);
(*ps)++;
}
freeaddrinfo(res0);
return (0);
out:
if (res0 != NULL)
freeaddrinfo(res0);
return (1);
}
开发者ID:0mp,项目名称:freebsd,代码行数:65,代码来源:dns.c
示例13: elfreadsyms
static int
elfreadsyms (int fd, Elf32_Ehdr *eh, Elf32_Shdr *shtab, int flags)
{
Elf32_Shdr *sh, *strh, *shstrh, *ksh;
Elf32_Sym *symtab;
Elf32_Ehdr *keh;
char *shstrtab, *strtab, *symend;
int nsym, offs, size, i;
int *symptr;
/* Fix up twirl */
if (bootseg++ > 0) {
fprintf (stderr, "\b + ");
}
/*
* If we are loading symbols to support kernel DDB symbol handling
* make room for an ELF header at _end and after that a section
* header. DDB then finds the symbols using the data put here.
*/
if(flags & KFLAG) {
tablebase = roundup(tablebase, sizeof(long));
symptr = (int *)tablebase;
tablebase += sizeof(int *) * 2;
keh = (Elf32_Ehdr *)tablebase;
tablebase += sizeof(Elf32_Ehdr);
tablebase = roundup(tablebase, sizeof(long));
ksh = (Elf32_Shdr *)tablebase;
tablebase += roundup((sizeof(Elf32_Shdr) * eh->e_shnum), sizeof(long));
memcpy(ksh, shtab, roundup((sizeof(Elf32_Shdr) * eh->e_shnum), sizeof(long)));
sh = ksh;
}
else {
sh = shtab;
}
shstrh = &sh[eh->e_shstrndx];
for (i = 0; i < eh->e_shnum; sh++, i++) {
if (sh->sh_type == SHT_SYMTAB) {
break;
}
}
if (i >= eh->e_shnum) {
return (0);
}
if(flags & KFLAG) {
strh = &ksh[sh->sh_link];
nsym = sh->sh_size / sh->sh_entsize;
offs = sh->sh_offset;
size = sh->sh_size;
fprintf (stderr, "%d syms ", nsym);
} else {
strh = &shtab[sh->sh_link];
nsym = (sh->sh_size / sh->sh_entsize) - sh->sh_info;
offs = sh->sh_offset + (sh->sh_info * sh->sh_entsize);
size = nsym * sh->sh_entsize;
fprintf (stderr, "%d syms ", nsym);
}
/*
* Allocate tables in correct order so the kernel grooks it.
* Then we read them in the order they are in the ELF file.
*/
shstrtab = gettable(shstrh->sh_size, "shstrtab", flags);
strtab = gettable(strh->sh_size, "strtab", flags);
symtab = gettable(size, "symtab", flags);
symend = (char *)symtab + size;
do {
if(shstrh->sh_offset < offs && shstrh->sh_offset < strh->sh_offset) {
#if 0
/*
* We would like to read the shstrtab from the file but since this
* table is located in front of the shtab it is already gone. We can't
* position backwards outside the current segment when using tftp.
* Instead we create the names we need in the string table because
* it can be reconstructed from the info we now have access to.
*/
if (!readtable (shstrh->sh_offset, (void *)shstrtab,
shstrh->sh_size, "shstring", flags)) {
return(0);
}
#else
memset(shstrtab, 0, shstrh->sh_size);
strcpy(shstrtab + shstrh->sh_name, ".shstrtab");
strcpy(shstrtab + strh->sh_name, ".strtab");
strcpy(shstrtab + sh->sh_name, ".symtab");
#endif
shstrh->sh_offset = 0x7fffffff;
}
if (offs < strh->sh_offset && offs < shstrh->sh_offset) {
if (!(readtable(fd, offs, (void *)symtab, size, "sym", flags))) {
return (0);
}
offs = 0x7fffffff;
//.........这里部分代码省略.........
static int clamp_thread(void *arg)
{
int cpunr = (unsigned long)arg;
DEFINE_TIMER(wakeup_timer, noop_timer, 0, 0);
static const struct sched_param param = {
.sched_priority = MAX_USER_RT_PRIO/2,
};
unsigned int count = 0;
unsigned int target_ratio;
set_bit(cpunr, cpu_clamping_mask);
set_freezable();
init_timer_on_stack(&wakeup_timer);
sched_setscheduler(current, SCHED_FIFO, ¶m);
while (true == clamping && !kthread_should_stop() &&
cpu_online(cpunr)) {
int sleeptime;
unsigned long target_jiffies;
unsigned int guard;
unsigned int compensation = 0;
int interval; /* jiffies to sleep for each attempt */
unsigned int duration_jiffies = msecs_to_jiffies(duration);
unsigned int window_size_now;
try_to_freeze();
/*
* make sure user selected ratio does not take effect until
* the next round. adjust target_ratio if user has changed
* target such that we can converge quickly.
*/
target_ratio = set_target_ratio;
guard = 1 + target_ratio/20;
window_size_now = window_size;
count++;
/*
* systems may have different ability to enter package level
* c-states, thus we need to compensate the injected idle ratio
* to achieve the actual target reported by the HW.
*/
compensation = get_compensation(target_ratio);
interval = duration_jiffies*100/(target_ratio+compensation);
/* align idle time */
target_jiffies = roundup(jiffies, interval);
sleeptime = target_jiffies - jiffies;
if (sleeptime <= 0)
sleeptime = 1;
schedule_timeout_interruptible(sleeptime);
/*
* only elected controlling cpu can collect stats and update
* control parameters.
*/
if (cpunr == control_cpu && !(count%window_size_now)) {
should_skip =
powerclamp_adjust_controls(target_ratio,
guard, window_size_now);
smp_mb();
}
if (should_skip)
continue;
target_jiffies = jiffies + duration_jiffies;
mod_timer(&wakeup_timer, target_jiffies);
if (unlikely(local_softirq_pending()))
continue;
/*
* stop tick sched during idle time, interrupts are still
* allowed. thus jiffies are updated properly.
*/
preempt_disable();
/* mwait until target jiffies is reached */
while (time_before(jiffies, target_jiffies)) {
unsigned long ecx = 1;
unsigned long eax = target_mwait;
/*
* REVISIT: may call enter_idle() to notify drivers who
* can save power during cpu idle. same for exit_idle()
*/
local_touch_nmi();
stop_critical_timings();
mwait_idle_with_hints(eax, ecx);
start_critical_timings();
atomic_inc(&idle_wakeup_counter);
}
preempt_enable();
}
del_timer_sync(&wakeup_timer);
clear_bit(cpunr, cpu_clamping_mask);
return 0;
}
/*
* 1 HZ polling while clamping is active, useful for userspace
* to monitor actual idle ratio.
*/
//.........这里部分代码省略.........
请发表评论