Skip to content

Commit

Permalink
Export of internal Abseil changes
Browse files Browse the repository at this point in the history
--
049ac45508e335c6f010f2d28d71016b9fa65b4e by Derek Mauro <dmauro@google.com>:

Fix librt detection

PiperOrigin-RevId: 280207723

--
6382c3a9fb2643af9dc031f92ca846c4a78e249c by Andy Getzendanner <durandal@google.com>:

Fix Conan builds

Import of #400

PiperOrigin-RevId: 280025424

--
aebcd52b1686ac82663a8d0193b60d0122a43372 by Samuel Benzaquen <sbenza@google.com>:

Enable the assertion in the iterator's operator== and operator!=

PiperOrigin-RevId: 279998951

--
5b61d909e2159ac6fd45e0e456818db1e725ecd1 by Derek Mauro <dmauro@google.com>:

Add best effort support for compiling much of Abseil with MinGW.
This involves disabling ABSL_ATTRIBUTE_WEAK and adding link flags.

A change to CCTZ is still necessary.

Tests were not run yet, but most of them now build.

PiperOrigin-RevId: 279966541

--
4336f8b10cff906e2defdd7d1d449cde4907da5d by Abseil Team <absl-team@google.com>:

Add comments and relax memory orders in base_internal::CallOnceImpl.

Add a comment to document the memory order guarantee if
base_internal::SpinLockWait() is called and returns kOnceDone.

Add a comment for the load/store sequence in base_internal::CallOnceImpl
based on Mike Burrows' explanation.

The atomic load of 'control' in the #ifndef NDEBUG block does not need
std::memory_order_acquire. It can use std::memory_order_relaxed.

The atomic compare_exchange_strong of 'control' does not need
std::memory_order_acquire in the success case. It can use
std::memory_order_relaxed.
PiperOrigin-RevId: 279814155

--
407de3a5e9af957cded54a136ca0468bde620d4d by Abseil Team <absl-team@google.com>:

Added a script to generate abseil.podspec from all BUILD.bazel files automatically.

PiperOrigin-RevId: 279811441

--
26139497d4a363d6c7bc989c554da593e8819a07 by Derek Mauro <dmauro@google.com>:

Add missing copyright and Apache License to //absl/functional/BUILD.bazel

PiperOrigin-RevId: 279795227

--
98ed625b02af6e5834edf52a920d8ca2dab4cd90 by Matt Kulukundis <kfm@google.com>:

Switch the implementation of hashtablez to *only* work on platforms that have a
PER_THREAD_TLS.

The old case is very slow (global mutex) and nobody collects data from that
configuration anyway.

PiperOrigin-RevId: 279775149

--
07225900ef672c005c38f467ad3f92f38d0922b3 by Derek Mauro <dmauro@google.com>:

Remove the minumum glibc version check

PiperOrigin-RevId: 279750412

--
ec09956a951b4f52228ecc81968b8db7ae19ed15 by Derek Mauro <dmauro@google.com>:

CMake only: link with -lrt to support older glibc versions

PiperOrigin-RevId: 279741661

--
97b113fb2e8246f6152c36330ba13793b37154b6 by Xiaoyi Zhang <zhangxy@google.com>:

Internal change.

PiperOrigin-RevId: 279390188

--
ca8f72f2721546cc9b01bd01b2ea144962e6e0c5 by Andy Getzendanner <durandal@google.com>:

Expose PutTwoDigits for internal use within Abseil.

PiperOrigin-RevId: 279374239

--
14c6384cc03bbdfdefd2e4b635f104af5dd7e026 by Derek Mauro <dmauro@google.com>:

Remove log_severity sources from the base target.
They are already compiled as part of a separate library.

PiperOrigin-RevId: 279372619

--
3c5d926c718f8bf394e3bee87b6ba8d94601e0d3 by Abseil Team <absl-team@google.com>:

s/indepdent/independent/g in SimpleAtof's documentation.

PiperOrigin-RevId: 279350836

--
de2c44be8a8edf9efa1fe2007cba3564f3e5b0b8 by Abseil Team <absl-team@google.com>:

Internal change

PiperOrigin-RevId: 279346990

--
2ba078341423fcf6d0ba5ca1831f86570a26e615 by Samuel Benzaquen <sbenza@google.com>:

Add hash support for std::wstring, std::u16string and std::u32string.

PiperOrigin-RevId: 279320672

--
3272d3ffcfa55283a04f90e5868701912da95ef7 by Andy Soffer <asoffer@google.com>:

Removing a bunch of __restricts that amount to no performance differences. One
of these is the cause of #396. In
particular, in one of the Vector128Store functions, restricts on two pointers
that were indeed aliased seems to be the root cause of the issues.

Closes #396

PiperOrigin-RevId: 279318999

--
342f338ab31cc24344d5de8f28cf455bbb629a17 by Jorg Brown <jorg@google.com>:

Support uint128 in SimpleAtoi

PiperOrigin-RevId: 279234038

--
81cb0a04cf2dc4515d303679fc60968712191571 by Derek Mauro <dmauro@google.com>:

Change the check for futex availability to support older Linux systems

PiperOrigin-RevId: 279147079

--
cb4ca4aa4c8d2d710a5d483c56c4ce4f979e14b1 by Abseil Team <absl-team@google.com>:

Add IWYU pragma: export for int128 .inc files.

PiperOrigin-RevId: 279107098

--
b8df86ef610c366729f07326c726f3e34817b4dd by Abseil Team <absl-team@google.com>:

An optimization for Waiter::Post() in the SEM waiter mode.

Like the FUTEX waiter mode, Waiter::Post() only needs to call Poke() if
it incremented the atomic variable from 0.

PiperOrigin-RevId: 279086133
GitOrigin-RevId: 049ac45508e335c6f010f2d28d71016b9fa65b4e
Change-Id: I4c1a4073fff62cb6a1fcb1c104aa7d62dad588c2
  • Loading branch information
Abseil Team authored and suertreus committed Nov 13, 2019
1 parent 85092b4 commit fa8c751
Show file tree
Hide file tree
Showing 26 changed files with 503 additions and 117 deletions.
247 changes: 247 additions & 0 deletions absl/abseil.podspec.gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""This script generates abseil.podspec from all BUILD.bazel files.
This is expected to run on abseil git repository with Bazel 1.0 on Linux.
It recursively analyzes BUILD.bazel files using query command of Bazel to
dump its build rules in XML format. From these rules, it constructs podspec
structure.
"""

import argparse
import collections
import os
import re
import subprocess
import xml.etree.ElementTree

# Template of root podspec.
SPEC_TEMPLATE = """
# This file has been automatically generated from a script.
# Please make modifications to `abseil.podspec.gen.py` instead.
Pod::Spec.new do |s|
s.name = 'abseil'
s.version = '${version}'
s.summary = 'Abseil Common Libraries (C++) from Google'
s.homepage = 'https://abseil.io'
s.license = 'Apache License, Version 2.0'
s.authors = { 'Abseil Team' => 'abseil-io@googlegroups.com' }
s.source = {
:git => 'https://github.com/abseil/abseil-cpp.git',
:tag => '${tag}',
}
s.module_name = 'absl'
s.header_mappings_dir = 'absl'
s.header_dir = 'absl'
s.libraries = 'c++'
s.compiler_flags = '-Wno-everything'
s.pod_target_xcconfig = {
'USER_HEADER_SEARCH_PATHS' => '$(inherited) "$(PODS_TARGET_SRCROOT)"',
'USE_HEADERMAP' => 'NO',
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
}
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.9'
s.tvos.deployment_target = '9.0'
s.watchos.deployment_target = '2.0'
"""

# Limited platforms that abseil supports.
# This is mainly because of sigaltstack unavailable on watchOS.
LIMITED_SUPPORT_PLATFORMS = [
"ios.deployment_target = '7.0'",
"osx.deployment_target = '10.9'",
]

# Custom specification per rule.
CUSTOM_SPEC_MAP = {
"//absl/debugging:failure_signal_handler": LIMITED_SUPPORT_PLATFORMS,
}

# Rule object representing the rule of Bazel BUILD.
Rule = collections.namedtuple(
"Rule", "type name package srcs hdrs textual_hdrs deps visibility testonly")


def get_elem_value(elem, name):
"""Returns the value of XML element with the given name."""
for child in elem:
if child.attrib.get("name") != name:
continue
if child.tag == "string":
return child.attrib.get("value")
if child.tag == "boolean":
return child.attrib.get("value") == "true"
if child.tag == "list":
return [nested_child.attrib.get("value") for nested_child in child]
raise "Cannot recognize tag: " + child.tag
return None


def normalize_paths(paths):
"""Returns the list of normalized path."""
# e.g. ["//absl/strings:dir/header.h"] -> ["absl/strings/dir/header.h"]
return [path.lstrip("/").replace(":", "/") for path in paths]


def parse_rule(elem, package):
"""Returns a rule from bazel XML rule."""
return Rule(
type=elem.attrib["class"],
name=get_elem_value(elem, "name"),
package=package,
srcs=normalize_paths(get_elem_value(elem, "srcs") or []),
hdrs=normalize_paths(get_elem_value(elem, "hdrs") or []),
textual_hdrs=normalize_paths(get_elem_value(elem, "textual_hdrs") or []),
deps=get_elem_value(elem, "deps") or [],
visibility=get_elem_value(elem, "visibility") or [],
testonly=get_elem_value(elem, "testonly") or False)


def read_build(package):
"""Runs bazel query on given package file and returns all cc rules."""
result = subprocess.check_output(
["bazel", "query", package + ":all", "--output", "xml"])
root = xml.etree.ElementTree.fromstring(result)
return [
parse_rule(elem, package)
for elem in root
if elem.tag == "rule" and elem.attrib["class"].startswith("cc_")
]


def collect_rules(root_path):
"""Collects and returns all rules from root path recursively."""
rules = []
for cur, _, _ in os.walk(root_path):
build_path = os.path.join(cur, "BUILD.bazel")
if os.path.exists(build_path):
rules.extend(read_build("//" + cur))
return rules


def relevant_rule(rule):
"""Returns true if a given rule is relevant when generating a podspec."""
return (
# cc_library only (ignore cc_test, cc_binary)
rule.type == "cc_library" and
# ignore empty rule
(rule.hdrs + rule.textual_hdrs + rule.srcs) and
# ignore test-only rule
not rule.testonly)


def get_spec_var(depth):
"""Returns the name of variable for spec with given depth."""
return "s" if depth == 0 else "s{}".format(depth)


def get_spec_name(label):
"""Converts the label of bazel rule to the name of podspec."""
assert label.startswith("//absl/"), "{} doesn't start with //absl/".format(
label)
# e.g. //absl/apple/banana -> abseil/apple/banana
return "abseil/" + label[7:]


def write_podspec(f, rules, args):
"""Writes a podspec from given rules and args."""
rule_dir = build_rule_directory(rules)["abseil"]
# Write root part with given arguments
spec = re.sub(r"\$\{(\w+)\}", lambda x: args[x.group(1)],
SPEC_TEMPLATE).lstrip()
f.write(spec)
# Write all target rules
write_podspec_map(f, rule_dir, 0)
f.write("end\n")


def build_rule_directory(rules):
"""Builds a tree-style rule directory from given rules."""
rule_dir = {}
for rule in rules:
cur = rule_dir
for frag in get_spec_name(rule.package).split("/"):
cur = cur.setdefault(frag, {})
cur[rule.name] = rule
return rule_dir


def write_podspec_map(f, cur_map, depth):
"""Writes podspec from rule map recursively."""
for key, value in sorted(cur_map.items()):
indent = " " * (depth + 1)
f.write("{indent}{var0}.subspec '{key}' do |{var1}|\n".format(
indent=indent,
key=key,
var0=get_spec_var(depth),
var1=get_spec_var(depth + 1)))
if isinstance(value, dict):
write_podspec_map(f, value, depth + 1)
else:
write_podspec_rule(f, value, depth + 1)
f.write("{indent}end\n".format(indent=indent))


def write_podspec_rule(f, rule, depth):
"""Writes podspec from given rule."""
indent = " " * (depth + 1)
spec_var = get_spec_var(depth)
# Puts all files in hdrs, textual_hdrs, and srcs into source_files.
# Since CocoaPods treats header_files a bit differently from bazel,
# this won't generate a header_files field so that all source_files
# are considered as header files.
srcs = sorted(set(rule.hdrs + rule.textual_hdrs + rule.srcs))
write_indented_list(
f, "{indent}{var}.source_files = ".format(indent=indent, var=spec_var),
srcs)
# Writes dependencies of this rule.
for dep in sorted(rule.deps):
name = get_spec_name(dep.replace(":", "/"))
f.write("{indent}{var}.dependency '{dep}'\n".format(
indent=indent, var=spec_var, dep=name))
# Writes custom specification.
custom_spec = CUSTOM_SPEC_MAP.get(rule.package + ":" + rule.name)
if custom_spec:
for spec in custom_spec:
f.write("{indent}{var}.{spec}\n".format(
indent=indent, var=spec_var, spec=spec))


def write_indented_list(f, leading, values):
"""Writes leading values in an indented style."""
f.write(leading)
f.write((",\n" + " " * len(leading)).join("'{}'".format(v) for v in values))
f.write("\n")


def generate(args):
"""Generates a podspec file from all BUILD files under absl directory."""
rules = filter(relevant_rule, collect_rules("absl"))
with open(args.output, "wt") as f:
write_podspec(f, rules, vars(args))


def main():
parser = argparse.ArgumentParser(
description="Generates abseil.podspec from BUILD.bazel")
parser.add_argument(
"-v", "--version", help="The version of podspec", required=True)
parser.add_argument(
"-t",
"--tag",
default=None,
help="The name of git tag (default: version)")
parser.add_argument(
"-o",
"--output",
default="abseil.podspec",
help="The name of output file (default: abseil.podspec)")
args = parser.parse_args()
if args.tag is None:
args.tag = args.version
generate(args)


if __name__ == "__main__":
main()
4 changes: 3 additions & 1 deletion absl/base/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = select({
"//absl:windows": [],
"//absl:windows": [
"-DEFAULTLIB:shlwapi.lib",
],
"//conditions:default": ["-pthread"],
}) + ABSL_DEFAULT_LINKOPTS,
deps = [
Expand Down
8 changes: 6 additions & 2 deletions absl/base/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# limitations under the License.
#

find_library(LIBRT rt)

absl_cc_library(
NAME
atomic_hook
Expand Down Expand Up @@ -163,16 +165,18 @@ absl_cc_library(
"internal/thread_identity.h"
"internal/tsan_mutex_interface.h"
"internal/unscaledcycleclock.h"
"log_severity.h"
SRCS
"internal/cycleclock.cc"
"internal/spinlock.cc"
"internal/sysinfo.cc"
"internal/thread_identity.cc"
"internal/unscaledcycleclock.cc"
"log_severity.cc"
COPTS
${ABSL_DEFAULT_COPTS}
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
$<$<BOOL:${LIBRT}>:${LIBRT}>
$<$<BOOL:${MINGW}>:"shlwapi">
DEPS
absl::atomic_hook
absl::base_internal
Expand Down
6 changes: 4 additions & 2 deletions absl/base/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@
// Weak attributes currently do not work properly in LLVM's Windows backend,
// so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598
// for further information.
#if (ABSL_HAVE_ATTRIBUTE(weak) || \
// The MinGW compiler doesn't complain about the weak attribute until the link
// step, presumably because Windows doesn't use ELF binaries.
#if (ABSL_HAVE_ATTRIBUTE(weak) || \
(defined(__GNUC__) && !defined(__clang__))) && \
!(defined(__llvm__) && defined(_WIN32))
!(defined(__llvm__) && defined(_WIN32)) && !defined(__MINGW32__)
#undef ABSL_ATTRIBUTE_WEAK
#define ABSL_ATTRIBUTE_WEAK __attribute__((weak))
#define ABSL_HAVE_ATTRIBUTE_WEAK 1
Expand Down
13 changes: 11 additions & 2 deletions absl/base/call_once.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void CallOnceImpl(std::atomic<uint32_t>* control,
Args&&... args) {
#ifndef NDEBUG
{
uint32_t old_control = control->load(std::memory_order_acquire);
uint32_t old_control = control->load(std::memory_order_relaxed);
if (old_control != kOnceInit &&
old_control != kOnceRunning &&
old_control != kOnceWaiter &&
Expand All @@ -166,14 +166,23 @@ void CallOnceImpl(std::atomic<uint32_t>* control,
// Must do this before potentially modifying control word's state.
base_internal::SchedulingHelper maybe_disable_scheduling(scheduling_mode);
// Short circuit the simplest case to avoid procedure call overhead.
// The base_internal::SpinLockWait() call returns either kOnceInit or
// kOnceDone. If it returns kOnceDone, it must have loaded the control word
// with std::memory_order_acquire and seen a value of kOnceDone.
uint32_t old_control = kOnceInit;
if (control->compare_exchange_strong(old_control, kOnceRunning,
std::memory_order_acquire,
std::memory_order_relaxed) ||
base_internal::SpinLockWait(control, ABSL_ARRAYSIZE(trans), trans,
scheduling_mode) == kOnceInit) {
base_internal::Invoke(std::forward<Callable>(fn),
std::forward<Args>(args)...);
// The call to SpinLockWake below is an optimization, because the waiter
// in SpinLockWait is waiting with a short timeout. The atomic load/store
// sequence is slightly faster than an atomic exchange:
// old_control = control->exchange(base_internal::kOnceDone,
// std::memory_order_release);
// We opt for a slightly faster case when there are no waiters, in spite
// of longer tail latency when there are waiters.
old_control = control->load(std::memory_order_relaxed);
control->store(base_internal::kOnceDone, std::memory_order_release);
if (old_control == base_internal::kOnceWaiter) {
Expand Down
10 changes: 0 additions & 10 deletions absl/base/policy_checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,6 @@
// Standard Library Check
// -----------------------------------------------------------------------------

// We have chosen glibc 2.12 as the minimum as it was tagged for release
// in May, 2010 and includes some functionality used in Google software
// (for instance pthread_setname_np):
// https://sourceware.org/ml/libc-alpha/2010-05/msg00000.html
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
#if !__GLIBC_PREREQ(2, 12)
#error "Minimum required version of glibc is 2.12."
#endif
#endif

#if defined(_STLPORT_VERSION)
#error "STLPort is not supported."
#endif
Expand Down
Loading

0 comments on commit fa8c751

Please sign in to comment.