diff options
-rw-r--r-- | ChangeLog | 45 | ||||
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | elf/dl-close.c | 58 | ||||
-rw-r--r-- | elf/dl-open.c | 40 | ||||
-rw-r--r-- | fedora/branch.mk | 4 | ||||
-rw-r--r-- | include/features.h | 5 | ||||
-rw-r--r-- | include/link.h | 10 | ||||
-rw-r--r-- | malloc/arena.c | 3 | ||||
-rw-r--r-- | malloc/hooks.c | 11 | ||||
-rw-r--r-- | malloc/malloc.c | 54 | ||||
-rw-r--r-- | nptl/ChangeLog | 16 | ||||
-rw-r--r-- | nptl/TODO | 15 | ||||
-rw-r--r-- | nptl/descr.h | 8 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c | 8 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c | 14 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S | 19 | ||||
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S | 15 | ||||
-rwxr-xr-x | scripts/check-c++-types.sh | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sched_setaffinity.c | 12 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/tst-getcpu.c | 54 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c | 14 | ||||
-rw-r--r-- | version.h | 4 |
23 files changed, 306 insertions, 113 deletions
diff --git a/ChangeLog b/ChangeLog index 6a8b6dd1e3..d23f2efe96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,50 @@ +2007-05-14 Ulrich Drepper <drepper@redhat.com> + + * version.h (VERSION): Define to 6. + * include/features.h (__GLIBC_MINOR__): Likewise. + + * malloc/malloc.c: Use all small bin slots on 64-bit archs. + + * malloc/malloc.c (largebin_index): Really have 32 buckets with 64 + sizes. + +2007-05-13 Ulrich Drepper <drepper@redhat.com> + + * malloc/malloc.c [MALLOC_DEBUG]: Keep track of current maximum + number of mmaps. n_mmaps_max is the target. + * malloc/hooks.c: Likewise. + * malloc/arena.c: Likewise. + +2007-05-12 Andreas Jaeger <aj@suse.de> + + * sysdeps/unix/sysv/linux/tst-getcpu.c: Include <unistd.h> for + getpid. + +2007-05-11 Ulrich Drepper <drepper@redhat.com> + + * elf/dl-close.c (_dl_close_worker): Help gcc to optimize by + adding new variables. + + * elf/dl-open.c (add_to_global): Introduce variable ns to help gcc + optimize. Completely extend global scope array before making the + new entries visible. + 2007-05-10 Ulrich Drepper <drepper@redhat.com> + * sysdeps/unix/sysv/linux/tst-getcpu.c: New file. + * sysdeps/unix/sysv/linux/Makefile [subdir=posix] (tests): Add + tst-getcpu. + + * include/link.h: Move l_version and l_nversion members around to + fill gaps. + + * scripts/check-c++-types.sh: Don't use -fnu89-inline option. + + * sysdeps/unix/sysv/linux/sched_setaffinity.c + (__sched_setaffinity_new): If syscall was successful and + RESET_VGETCPU_CACHE is defined, use it before returning. + * sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c: New file. + * io/sys/stat.h: Make sure struct timespec is defined for __USE_ATFILE. diff --git a/README b/README index 97b3a61e06..7b82d80e97 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This directory contains the version 2.5 release of the GNU C Library. +This directory contains the version 2.6 release of the GNU C Library. The GNU C Library is the standard system C library for all GNU systems, and is an important part of what makes up a GNU system. It provides the @@ -52,7 +52,7 @@ The GNU C Library supports these configurations for using Linux kernels: The code for other CPU configurations supported by volunteers outside of the core glibc maintenance effort is contained in the separate `ports' -add-on. You can find glibc-ports-2.5 distributed separately in the +add-on. You can find glibc-ports-2.6 distributed separately in the same place where you got the main glibc distribution files. Currently these configurations are known to work using the `ports' add-on: diff --git a/elf/dl-close.c b/elf/dl-close.c index df968fe649..e0fe26ad02 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -1,5 +1,5 @@ /* Close a shared object opened by `_dl_open'. - Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1996-2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -107,8 +107,6 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp, void _dl_close_worker (struct link_map *map) { - Lmid_t ns = map->l_ns; - /* One less direct use. */ --map->l_direct_opencount; @@ -131,11 +129,14 @@ _dl_close_worker (struct link_map *map) return; } + Lmid_t nsid = map->l_ns; + struct link_namespaces *ns = &GL(dl_ns)[nsid]; + retry: dl_close_state = pending; bool any_tls = false; - const unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded; + const unsigned int nloaded = ns->_ns_nloaded; char used[nloaded]; char done[nloaded]; struct link_map *maps[nloaded]; @@ -143,7 +144,7 @@ _dl_close_worker (struct link_map *map) /* Run over the list and assign indexes to the link maps and enter them into the MAPS array. */ int idx = 0; - for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next) + for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next) { l->l_idx = idx; maps[idx] = l; @@ -220,11 +221,11 @@ _dl_close_worker (struct link_map *map) } /* Sort the entries. */ - _dl_sort_fini (GL(dl_ns)[ns]._ns_loaded, maps, nloaded, used, ns); + _dl_sort_fini (ns->_ns_loaded, maps, nloaded, used, nsid); /* Call all termination functions at once. */ #ifdef SHARED - bool do_audit = GLRO(dl_naudit) > 0 && !GL(dl_ns)[ns]._ns_loaded->l_auditing; + bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing; #endif bool unload_any = false; unsigned int first_loaded = ~0; @@ -233,7 +234,7 @@ _dl_close_worker (struct link_map *map) struct link_map *imap = maps[i]; /* All elements must be in the same namespace. */ - assert (imap->l_ns == ns); + assert (imap->l_ns == nsid); if (!used[i]) { @@ -248,7 +249,7 @@ _dl_close_worker (struct link_map *map) if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", - imap->l_name, ns); + imap->l_name, nsid); if (imap->l_info[DT_FINI_ARRAY] != NULL) { @@ -334,7 +335,7 @@ _dl_close_worker (struct link_map *map) struct link_map *tmap = (struct link_map *) ((char *) imap->l_scope[cnt] - offsetof (struct link_map, l_searchlist)); - assert (tmap->l_ns == ns); + assert (tmap->l_ns == nsid); if (tmap->l_idx == IDX_STILL_USED) ++remain; else @@ -435,7 +436,7 @@ _dl_close_worker (struct link_map *map) /* Auditing checkpoint: we will start deleting objects. */ if (__builtin_expect (do_audit, 0)) { - struct link_map *head = GL(dl_ns)[ns]._ns_loaded; + struct link_map *head = ns->_ns_loaded; struct audit_ifaces *afct = GLRO(dl_audit); /* Do not call the functions for any auditing object. */ if (head->l_auditing == 0) @@ -452,7 +453,7 @@ _dl_close_worker (struct link_map *map) #endif /* Notify the debugger we are about to remove some loaded objects. */ - struct r_debug *r = _dl_debug_initialize (0, ns); + struct r_debug *r = _dl_debug_initialize (0, nsid); r->r_state = RT_DELETE; _dl_debug_state (); @@ -474,19 +475,18 @@ _dl_close_worker (struct link_map *map) if (__builtin_expect (imap->l_global, 0)) { /* This object is in the global scope list. Remove it. */ - unsigned int cnt = GL(dl_ns)[ns]._ns_main_searchlist->r_nlist; + struct r_scope_elem *ns_msl = ns->_ns_main_searchlist; + unsigned int cnt = ns_msl->r_nlist; do --cnt; - while (GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt] != imap); + while (ns_msl->r_list[cnt] != imap); /* The object was already correctly registered. */ - while (++cnt - < GL(dl_ns)[ns]._ns_main_searchlist->r_nlist) - GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt - 1] - = GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt]; + while (++cnt < ns_msl->r_nlist) + ns_msl->r_list[cnt - 1] = ns_msl->r_list[cnt]; - --GL(dl_ns)[ns]._ns_main_searchlist->r_nlist; + --ns_msl->r_nlist; } /* Remove the object from the dtv slotinfo array if it uses TLS. */ @@ -581,12 +581,12 @@ _dl_close_worker (struct link_map *map) else { #ifdef SHARED - assert (ns != LM_ID_BASE); + assert (nsid != LM_ID_BASE); #endif - GL(dl_ns)[ns]._ns_loaded = imap->l_next; + ns->_ns_loaded = imap->l_next; } - --GL(dl_ns)[ns]._ns_nloaded; + --ns->_ns_nloaded; if (imap->l_next != NULL) imap->l_next->l_prev = imap->l_prev; @@ -648,7 +648,7 @@ _dl_close_worker (struct link_map *map) /* Auditing checkpoint: we have deleted all objects. */ if (__builtin_expect (do_audit, 0)) { - struct link_map *head = GL(dl_ns)[ns]._ns_loaded; + struct link_map *head = ns->_ns_loaded; /* Do not call the functions for any auditing object. */ if (head->l_auditing == 0) { @@ -732,22 +732,22 @@ free_slotinfo (struct dtv_slotinfo_list **elemp) libc_freeres_fn (free_mem) { - for (Lmid_t ns = 0; ns < DL_NNS; ++ns) - if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0 - && (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist + for (Lmid_t nsid = 0; nsid < DL_NNS; ++nsid) + if (__builtin_expect (GL(dl_ns)[nsid]._ns_global_scope_alloc, 0) != 0 + && (GL(dl_ns)[nsid]._ns_main_searchlist->r_nlist // XXX Check whether we need NS-specific initial_searchlist == GLRO(dl_initial_searchlist).r_nlist)) { /* All object dynamically loaded by the program are unloaded. Free the memory allocated for the global scope variable. */ - struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list; + struct link_map **old = GL(dl_ns)[nsid]._ns_main_searchlist->r_list; /* Put the old map in. */ - GL(dl_ns)[ns]._ns_main_searchlist->r_list + GL(dl_ns)[nsid]._ns_main_searchlist->r_list // XXX Check whether we need NS-specific initial_searchlist = GLRO(dl_initial_searchlist).r_list; /* Signal that the original map is used. */ - GL(dl_ns)[ns]._ns_global_scope_alloc = 0; + GL(dl_ns)[nsid]._ns_global_scope_alloc = 0; /* Now free the old map. */ free (old); diff --git a/elf/dl-open.c b/elf/dl-open.c index 259372178b..583878781e 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -1,5 +1,5 @@ /* Load a shared object at runtime, relocate it, and run its initializer. - Copyright (C) 1996-2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1996-2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -97,17 +97,17 @@ add_to_global (struct link_map *new) in an realloc() call. Therefore we allocate a completely new array the first time we have to add something to the locale scope. */ - if (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc == 0) + struct link_namespaces *ns = &GL(dl_ns)[new->l_ns]; + if (ns->_ns_global_scope_alloc == 0) { /* This is the first dynamic object given global scope. */ - GL(dl_ns)[new->l_ns]._ns_global_scope_alloc - = GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add + 8; + ns->_ns_global_scope_alloc + = ns->_ns_main_searchlist->r_nlist + to_add + 8; new_global = (struct link_map **) - malloc (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc - * sizeof (struct link_map *)); + malloc (ns->_ns_global_scope_alloc * sizeof (struct link_map *)); if (new_global == NULL) { - GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0; + ns->_ns_global_scope_alloc = 0; nomem: _dl_signal_error (ENOMEM, new->l_libname->name, NULL, N_("cannot extend global scope")); @@ -115,29 +115,29 @@ add_to_global (struct link_map *new) } /* Copy over the old entries. */ - GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list - = memcpy (new_global, - GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list, - (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + ns->_ns_main_searchlist->r_list + = memcpy (new_global, ns->_ns_main_searchlist->r_list, + (ns->_ns_main_searchlist->r_nlist * sizeof (struct link_map *))); } - else if (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add - > GL(dl_ns)[new->l_ns]._ns_global_scope_alloc) + else if (ns->_ns_main_searchlist->r_nlist + to_add + > ns->_ns_global_scope_alloc) { /* We have to extend the existing array of link maps in the main map. */ new_global = (struct link_map **) - realloc (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list, - ((GL(dl_ns)[new->l_ns]._ns_global_scope_alloc + to_add + 8) + realloc (ns->_ns_main_searchlist->r_list, + ((ns->_ns_global_scope_alloc + to_add + 8) * sizeof (struct link_map *))); if (new_global == NULL) goto nomem; - GL(dl_ns)[new->l_ns]._ns_global_scope_alloc += to_add + 8; - GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list = new_global; + ns->_ns_global_scope_alloc += to_add + 8; + ns->_ns_main_searchlist->r_list = new_global; } /* Now add the new entries. */ + unsigned int new_nlist = ns->_ns_main_searchlist->r_nlist; for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) { struct link_map *map = new->l_searchlist.r_list[cnt]; @@ -145,11 +145,11 @@ add_to_global (struct link_map *new) if (map->l_global == 0) { map->l_global = 1; - GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list[GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist] - = map; - ++GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist; + ns->_ns_main_searchlist->r_list[new_nlist++] = map; } } + atomic_write_barrier (); + ns->_ns_main_searchlist->r_nlist = new_nlist; return 0; } diff --git a/fedora/branch.mk b/fedora/branch.mk index b38bb1790c..f04611d44b 100644 --- a/fedora/branch.mk +++ b/fedora/branch.mk @@ -3,5 +3,5 @@ glibc-branch := fedora glibc-base := HEAD DIST_BRANCH := devel COLLECTION := dist-fc7 -fedora-sync-date := 2007-05-10 23:08 UTC -fedora-sync-tag := fedora-glibc-20070510T2308 +fedora-sync-date := 2007-05-15 20:25 UTC +fedora-sync-tag := fedora-glibc-20070515T2025 diff --git a/include/features.h b/include/features.h index 4eb49a92b1..0fd14d2563 100644 --- a/include/features.h +++ b/include/features.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1991,1992,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1991,1992,1993,1995-2006,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -310,7 +309,7 @@ /* Major and minor version number of the GNU C library package. Use these macros to test for features in specific releases. */ #define __GLIBC__ 2 -#define __GLIBC_MINOR__ 5 +#define __GLIBC_MINOR__ 6 #define __GLIBC_PREREQ(maj, min) \ ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min)) diff --git a/include/link.h b/include/link.h index b45deabf7f..67d70470d1 100644 --- a/include/link.h +++ b/include/link.h @@ -1,6 +1,6 @@ /* Data structure for communication from the run-time dynamic linker for loaded ELF shared objects. - Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc. + Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -141,6 +141,10 @@ struct link_map /* Dependent object that first caused this object to be loaded. */ struct link_map *l_loader; + /* Array with version names. */ + struct r_found_version *l_versions; + unsigned int l_nversions; + /* Symbol hash table. */ Elf_Symndx l_nbuckets; Elf32_Word l_gnu_bitmask_idxbits; @@ -184,10 +188,6 @@ struct link_map unsigned int l_removed:1; /* Nozero if the object cannot be used anymore since it is removed. */ - /* Array with version names. */ - unsigned int l_nversions; - struct r_found_version *l_versions; - /* Collected information about own RPATH directories. */ struct r_search_path_struct l_rpath_dirs; diff --git a/malloc/arena.c b/malloc/arena.c index ce64335567..9e3ff47347 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -370,6 +370,9 @@ ptmalloc_init_minimal (void) mp_.top_pad = DEFAULT_TOP_PAD; #endif mp_.n_mmaps_max = DEFAULT_MMAP_MAX; +#if MALLOC_DEBUG + mp_.n_mmaps_cmax = DEFAULT_MMAP_MAX; +#endif mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD; mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD; mp_.pagesize = malloc_getpagesize; diff --git a/malloc/hooks.c b/malloc/hooks.c index 8346e73453..cde3e18cbd 100644 --- a/malloc/hooks.c +++ b/malloc/hooks.c @@ -1,5 +1,5 @@ /* Malloc implementation for multiple threads without lock contention. - Copyright (C) 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc. + Copyright (C) 2001-2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Wolfram Gloger <wg@malloc.de>, 2001. @@ -507,6 +507,9 @@ struct malloc_save_state { unsigned long trim_threshold; unsigned long top_pad; unsigned int n_mmaps_max; +#if MALLOC_DEBUG + unsigned int n_mmaps_cmax; +#endif unsigned long mmap_threshold; int check_action; unsigned long max_sbrked_mem; @@ -550,6 +553,9 @@ public_gET_STATe(void) ms->trim_threshold = mp_.trim_threshold; ms->top_pad = mp_.top_pad; ms->n_mmaps_max = mp_.n_mmaps_max; +#if MALLOC_DEBUG + ms->n_mmaps_cmax = mp_.n_mmaps_cmax; +#endif ms->mmap_threshold = mp_.mmap_threshold; ms->check_action = check_action; ms->max_sbrked_mem = main_arena.max_system_mem; @@ -621,6 +627,9 @@ public_sET_STATe(Void_t* msptr) mp_.trim_threshold = ms->trim_threshold; mp_.top_pad = ms->top_pad; mp_.n_mmaps_max = ms->n_mmaps_max; +#if MALLOC_DEBUG + mp_.n_mmaps_cmax = ms->n_mmaps_cmax; +#endif mp_.mmap_threshold = ms->mmap_threshold; check_action = ms->check_action; main_arena.max_system_mem = ms->max_sbrked_mem; diff --git a/malloc/malloc.c b/malloc/malloc.c index 8ae941c597..e061db94d6 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -2125,22 +2125,37 @@ typedef struct malloc_chunk* mbinptr; #define NBINS 128 #define NSMALLBINS 64 -#define SMALLBIN_WIDTH 8 -#define MIN_LARGE_SIZE 512 +#define SMALLBIN_WIDTH MALLOC_ALIGNMENT +#define MIN_LARGE_SIZE (NSMALLBINS * SMALLBIN_WIDTH) #define in_smallbin_range(sz) \ ((unsigned long)(sz) < (unsigned long)MIN_LARGE_SIZE) -#define smallbin_index(sz) (((unsigned)(sz)) >> 3) +#define smallbin_index(sz) \ + (SMALLBIN_WIDTH == 16 ? (((unsigned)(sz)) >> 4) : (((unsigned)(sz)) >> 3)) -#define largebin_index(sz) \ -(((((unsigned long)(sz)) >> 6) <= 32)? 56 + (((unsigned long)(sz)) >> 6): \ +#define largebin_index_32(sz) \ +(((((unsigned long)(sz)) >> 6) <= 38)? 56 + (((unsigned long)(sz)) >> 6): \ ((((unsigned long)(sz)) >> 9) <= 20)? 91 + (((unsigned long)(sz)) >> 9): \ ((((unsigned long)(sz)) >> 12) <= 10)? 110 + (((unsigned long)(sz)) >> 12): \ ((((unsigned long)(sz)) >> 15) <= 4)? 119 + (((unsigned long)(sz)) >> 15): \ ((((unsigned long)(sz)) >> 18) <= 2)? 124 + (((unsigned long)(sz)) >> 18): \ 126) +// XXX It remains to be seen whether it is good to keep the widths of +// XXX the buckets the same or whether it should be scaled by a factor +// XXX of two as well. +#define largebin_index_64(sz) \ +(((((unsigned long)(sz)) >> 6) <= 48)? 48 + (((unsigned long)(sz)) >> 6): \ + ((((unsigned long)(sz)) >> 9) <= 20)? 91 + (((unsigned long)(sz)) >> 9): \ + ((((unsigned long)(sz)) >> 12) <= 10)? 110 + (((unsigned long)(sz)) >> 12): \ + ((((unsigned long)(sz)) >> 15) <= 4)? 119 + (((unsigned long)(sz)) >> 15): \ + ((((unsigned long)(sz)) >> 18) <= 2)? 124 + (((unsigned long)(sz)) >> 18): \ + 126) + +#define largebin_index(sz) \ + (SIZE_SZ == 8 ? largebin_index_64 (sz) : largebin_index_32 (sz)) + #define bin_index(sz) \ ((in_smallbin_range(sz)) ? smallbin_index(sz) : largebin_index(sz)) @@ -2343,6 +2358,9 @@ struct malloc_par { /* Memory map support */ int n_mmaps; int n_mmaps_max; +#if MALLOC_DEBUG + int n_mmaps_cmax; +#endif int max_n_mmaps; /* the mmap_threshold is dynamic, until the user sets it manually, at which point we need to disable any @@ -2858,7 +2876,8 @@ static void do_check_malloc_state(mstate av) assert(total <= (unsigned long)(mp_.max_total_mem)); assert(mp_.n_mmaps >= 0); #endif - assert(mp_.n_mmaps <= mp_.n_mmaps_max); + assert(mp_.n_mmaps <= mp_.n_mmaps_cmax); + assert(mp_.n_mmaps_max <= mp_.n_mmaps_cmax); assert(mp_.n_mmaps <= mp_.max_n_mmaps); assert((unsigned long)(av->system_mem) <= @@ -3456,6 +3475,13 @@ munmap_chunk(p) mchunkptr p; } mp_.n_mmaps--; +#if MALLOC_DEBUG + if (mp_.n_mmaps_cmax > mp_.n_mmaps_max) + { + assert (mp_.n_mmaps_cmax == mp_.n_mmaps + 1); + mp_.n_mmaps_cmax = mp_.n_mmaps; + } +#endif mp_.mmapped_mem -= total_size; int ret __attribute__ ((unused)) = munmap((char *)block, total_size); @@ -5371,6 +5397,9 @@ mstate av; size_t n_elements; size_t* sizes; int opts; Void_t* chunks[]; mp_.n_mmaps_max = 0; mem = _int_malloc(av, size); mp_.n_mmaps_max = mmx; /* reset mmap */ +#if MALLOC_DEBUG + mp_.n_mmaps_cmax = mmx; +#endif if (mem == 0) return 0; @@ -5696,8 +5725,17 @@ int mALLOPt(param_number, value) int param_number; int value; res = 0; else #endif - mp_.n_mmaps_max = value; - mp_.no_dyn_threshold = 1; + { +#if MALLOC_DEBUG + if (mp_.n_mmaps <= value) + mp_.n_mmaps_cmax = value; + else + mp_.n_mmaps_cmax = mp_.n_mmaps; +#endif + + mp_.n_mmaps_max = value; + mp_.no_dyn_threshold = 1; + } break; case M_CHECK_ACTION: diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 662c567c8b..0671f4a459 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,19 @@ +2007-05-14 Ulrich Drepper <drepper@redhat.com> + + * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Remove unnecessary + extra cancellation test. + * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise. + +2007-05-10 Ulrich Drepper <drepper@redhat.com> + + * descr.h (struct pthread): Rearrange members to fill hole in + 64-bit layout. + + * sysdeps/unix/sysv/linux/pthread_setaffinity.c + (__pthread_setaffinity_new): If syscall was successful and + RESET_VGETCPU_CACHE is defined, use it before returning. + * sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c: New file. + 2007-05-10 Jakub Jelinek <jakub@redhat.com> [BZ #4455] diff --git a/nptl/TODO b/nptl/TODO index d597176512..70b8fe4f76 100644 --- a/nptl/TODO +++ b/nptl/TODO @@ -14,3 +14,18 @@ syscall needed. - test with threaded process terminating and semadj (?) being applied only after all threads are gone + + + +- semaphore changes: + + - sem_post should only wake one thread and only when the state of + the semaphore changed from 0 to 1 + + this also requires that sem_wait and sem_timedwait don't drop the + post if they get canceled. + + - possibly add counter field. This requires reviving the + differences between old and new semaphose funtions. The old ones + stay as they are now. The new once can use an additional field + wich is the counter for the number of waiters diff --git a/nptl/descr.h b/nptl/descr.h index 321ce85085..00cad1aa83 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -268,6 +268,9 @@ struct pthread | EXITING_BITMASK | CANCEL_RESTMASK | TERMINATED_BITMASK)) \ == (CANCELTYPE_BITMASK | CANCELED_BITMASK)) + /* Flags. Including those copied from the thread attribute. */ + int flags; + /* We allocate one block of references here. This should be enough to avoid allocating any memory dynamically for most applications. */ struct pthread_key_data @@ -321,9 +324,6 @@ struct pthread /* Check whether a thread is detached. */ #define IS_DETACHED(pd) ((pd)->joinid == (pd)) - /* Flags. Including those copied from the thread attribute. */ - int flags; - /* The result of the thread function. */ void *result; diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c b/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c index 3776e26e4b..fa0f46feec 100644 --- a/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c +++ b/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -79,6 +79,12 @@ __pthread_setaffinity_new (pthread_t th, size_t cpusetsize, res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid, cpusetsize, cpuset); + +#ifdef RESET_VGETCPU_CACHE + if (!INTERNAL_SYSCALL_ERROR_P (res, err)) + RESET_VGETCPU_CACHE (); +#endif + return (INTERNAL_SYSCALL_ERROR_P (res, err) ? INTERNAL_SYSCALL_ERRNO (res, err) : 0); diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c new file mode 100644 index 0000000000..640d3044fd --- /dev/null +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c @@ -0,0 +1,14 @@ +#include <tls.h> + +#define RESET_VGETCPU_CACHE() \ + do { \ + asm volatile ("movl %0, %%fs:%P1\n\t" \ + "movl %0, %%fs:%P2" \ + : \ + : "ir" (0), "i" (offsetof (struct pthread, \ + header.vgetcpu_cache[0])), \ + "i" (offsetof (struct pthread, \ + header.vgetcpu_cache[1]))); \ + } while (0) + +#include "../pthread_setaffinity.c" diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S index c44d3f5e77..76a566b988 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -40,12 +40,6 @@ .align 16 cfi_startproc sem_timedwait: - /* First check for cancellation. */ - movl %fs:CANCELHANDLING, %eax - andl $0xfffffff9, %eax - cmpl $8, %eax - je 11f - movl (%rdi), %eax 2: testl %eax, %eax je 1f @@ -160,16 +154,5 @@ sem_timedwait: orl $-1, %eax jmp 10b - cfi_adjust_cfa_offset(-48) - cfi_restore(14) - cfi_restore(13) - cfi_restore(12) - -11: /* Canceled. */ - movq $0xffffffffffffffff, %fs:RESULT - LOCK - orl $0x10, %fs:CANCELHANDLING - movq %fs:CLEANUP_JMP_BUF, %rdi - jmp HIDDEN_JUMPTARGET (__pthread_unwind) cfi_endproc .size sem_timedwait,.-sem_timedwait diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S index 63ecd063ab..5bd78eb944 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -37,12 +37,6 @@ .align 16 cfi_startproc sem_wait: - /* First check for cancellation. */ - movl %fs:CANCELHANDLING, %eax - andl $0xfffffff9, %eax - cmpl $8, %eax - je 4f - pushq %r12 cfi_adjust_cfa_offset(8) cfi_offset(12, -16) @@ -109,12 +103,5 @@ sem_wait: cfi_restore(12) retq - -4: /* Canceled. */ - movq $0xffffffffffffffff, %fs:RESULT - LOCK - orl $0x10, %fs:CANCELHANDLING - movq %fs:CLEANUP_JMP_BUF, %rdi - jmp HIDDEN_JUMPTARGET (__pthread_unwind) cfi_endproc .size sem_wait,.-sem_wait diff --git a/scripts/check-c++-types.sh b/scripts/check-c++-types.sh index b207f12ba4..2864fe9aad 100755 --- a/scripts/check-c++-types.sh +++ b/scripts/check-c++-types.sh @@ -1,5 +1,5 @@ #! /bin/bash -# Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005, 2006, 2007 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -32,7 +32,7 @@ # data=$1 shift -cxx="$*" +cxx=$(echo $* | sed 's/-fgnu89-inline//') while read t; do echo -n "$t:" $cxx -S -xc++ -o - -D_GNU_SOURCE <(cat <<EOF diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 78553b9795..a063b33389 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -113,6 +113,8 @@ ifeq ($(subdir),posix) sysdep_headers += bits/initspin.h sysdep_routines += exit-thread sched_getcpu + +tests += tst-getcpu endif ifeq ($(subdir),inet) diff --git a/sysdeps/unix/sysv/linux/sched_setaffinity.c b/sysdeps/unix/sysv/linux/sched_setaffinity.c index ccd3c8f514..77cde47692 100644 --- a/sysdeps/unix/sysv/linux/sched_setaffinity.c +++ b/sysdeps/unix/sysv/linux/sched_setaffinity.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005, 2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -67,7 +68,14 @@ __sched_setaffinity_new (pid_t pid, size_t cpusetsize, const cpu_set_t *cpuset) return -1; } - return INLINE_SYSCALL (sched_setaffinity, 3, pid, cpusetsize, cpuset); + int result = INLINE_SYSCALL (sched_setaffinity, 3, pid, cpusetsize, cpuset); + +#ifdef RESET_VGETCPU_CACHE + if (result != -1) + RESET_VGETCPU_CACHE (); +#endif + + return result; } versioned_symbol (libc, __sched_setaffinity_new, sched_setaffinity, GLIBC_2_3_4); diff --git a/sysdeps/unix/sysv/linux/tst-getcpu.c b/sysdeps/unix/sysv/linux/tst-getcpu.c new file mode 100644 index 0000000000..bf3cb57dd8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tst-getcpu.c @@ -0,0 +1,54 @@ +#include <errno.h> +#include <stdio.h> +#include <sched.h> +#include <unistd.h> + + +static int +do_test (void) +{ + cpu_set_t cs; + if (sched_getaffinity (getpid (), sizeof (cs), &cs) != 0) + { + printf ("getaffinity failed: %m\n"); + return 1; + } + + int result = 0; + int cpu = 0; + while (CPU_COUNT (&cs) != 0) + { + if (CPU_ISSET (cpu, &cs)) + { + cpu_set_t cs2; + CPU_ZERO (&cs2); + CPU_SET (cpu, &cs2); + if (sched_setaffinity (getpid (), sizeof (cs2), &cs2) != 0) + { + printf ("setaffinity(%d) failed: %m\n", cpu); + result = 1; + } + else + { + int cpu2 = sched_getcpu (); + if (cpu2 == -1 && errno == ENOSYS) + { + puts ("getcpu syscall not implemented"); + return 0; + } + if (cpu2 != cpu) + { + printf ("getcpu results %d not possible\n", cpu2); + result = 1; + } + } + CPU_CLR (cpu, &cs); + } + ++cpu; + } + + return result; +} + +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> diff --git a/sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c b/sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c new file mode 100644 index 0000000000..d1101c56f5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c @@ -0,0 +1,14 @@ +#include <tls.h> + +#define RESET_VGETCPU_CACHE() \ + do { \ + asm volatile ("movl %0, %%fs:%P1\n\t" \ + "movl %0, %%fs:%P2" \ + : \ + : "ir" (0), "i" (offsetof (struct pthread, \ + header.vgetcpu_cache[0])), \ + "i" (offsetof (struct pthread, \ + header.vgetcpu_cache[1]))); \ + } while (0) + +#include "../sched_setaffinity.c" diff --git a/version.h b/version.h index acd0ed11eb..d70070f2a3 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ /* This file just defines the current version number of libc. */ -#define RELEASE "development" -#define VERSION "2.5.90" +#define RELEASE "stable" +#define VERSION "2.6" |