1#!/bin/sh
2#
3# Usage: cd /usr/src/contrib/jemalloc
4#        ./FREEBSD-upgrade <command> [args]
5#
6# At least the following ports are required when importing jemalloc:
7# - devel/autoconf
8# - devel/git
9# - devel/gmake
10# - textproc/docbook-xsl
11# - textproc/libxslt
12#
13# The normal workflow for importing a new release is:
14#
15#   cd /usr/src/contrib/jemalloc
16#
17# Merge local changes that were made since the previous import:
18#
19#   ./FREEBSD-upgrade merge-changes
20#   ./FREEBSD-upgrade rediff
21#
22# Extract latest jemalloc release.
23#
24#   ./FREEBSD-upgrade extract <rev>
25#
26# Fix patch conflicts as necessary, then regenerate diffs to update line
27# offsets:
28#
29#   ./FREEBSD-upgrade rediff
30#   ./FREEBSD-upgrade extract <rev>
31#
32# Do multiple buildworld/installworld rounds.  If problems arise and patches
33# are needed, edit the code in ${work} as necessary, then:
34#
35#   ./FREEBSD-upgrade rediff
36#   ./FREEBSD-upgrade extract <rev>
37#
38# The rediff/extract order is important because rediff saves the local
39# changes, then extract blows away the work tree and re-creates it with the
40# diffs applied.
41#
42# Finally, to clean up:
43#
44#  ./FREEBSD-upgrade clean
45
46set -e
47set -x
48
49if [ ! -x "FREEBSD-upgrade" ] ; then
50  echo "Run from within src/contrib/jemalloc/" >&2
51  exit 1
52fi
53
54if [ "x${JEMALLOC_REPO}" = "x" ] ; then
55  JEMALLOC_REPO=https://github.com/jemalloc/jemalloc.git
56fi
57
58src=`pwd`
59
60jemalloc_tmp="jemalloc.tmp"
61tmpdir="${src}/../${jemalloc_tmp}"
62bare_repo="${tmpdir}/jemalloc_bare.git"
63work="jemalloc_work.git"
64work_repo="${tmpdir}/${work}"
65namespace_repo="${tmpdir}/jemalloc_namespace.git"
66changes="${src}/FREEBSD-changes"
67
68do_fetch() {
69  local rev=$1
70  if [ ! -d "${bare_repo}" ] ; then
71    mkdir -p "${bare_repo}"
72    git clone --bare ${JEMALLOC_REPO} ${bare_repo}
73  fi
74  (
75    cd ${bare_repo}
76    git fetch origin ${rev}
77  )
78}
79
80do_extract_helper() {
81  local rev=$1
82  local repo=$2
83  do_fetch ${rev}
84  rm -rf ${repo}
85  git clone ${bare_repo} ${repo}
86  (
87    cd ${repo}
88    if [ "x${rev}" != "x" ] ; then
89      # Use optional rev argument to check out a revision other than HEAD on
90      # master.
91      git checkout ${rev}
92    fi
93  )
94}
95
96do_autogen() {
97  ./autogen.sh --enable-xmalloc --enable-utrace \
98    --with-malloc-conf=abort_conf:false \
99    --with-xslroot=/usr/local/share/xsl/docbook --with-private-namespace=__ \
100    --with-lg-page-sizes=12,13,14,16
101}
102
103do_extract_diff() {
104  local rev=$1
105  local repo=$2
106  do_extract_helper ${rev} ${repo}
107  (
108    cd ${repo}
109    # Apply diffs before generating files.
110    patch -p1 < "${src}/FREEBSD-diffs"
111    find . -name '*.orig' -delete
112    # Generate files.
113    do_autogen
114    gmake dist
115  )
116}
117
118do_extract_namespace() {
119  local rev=$1
120  local repo=$2
121  do_extract_helper ${rev} ${repo}
122  (
123    cd ${repo}
124    # Generate files.
125    do_autogen
126    gmake include/jemalloc/internal/private_namespace.h
127  )
128}
129
130do_extract() {
131  local rev=$1
132  do_fetch ${rev}
133  do_extract_diff ${rev} ${work_repo}
134  do_extract_namespace ${rev} ${namespace_repo}
135}
136
137do_diff() {
138  (
139    cd ${work_repo}
140    find . -name '*.orig' -delete
141    find . -name '*.rej' -delete
142    git add -A
143    git diff --cached
144  ) > FREEBSD-diffs
145}
146
147command=$1
148shift
149case "${command}" in
150  merge-changes) # Merge local changes that were made since the previous import.
151    rev=`cat VERSION |tr 'g' ' ' |awk '{print $2}'`
152    # Extract code corresponding to most recent import.
153    do_extract ${rev}
154    # Compute local differences to the upstream+patches and apply them.
155    (
156      cd ${tmpdir}
157      diff -ru -X ${src}/FREEBSD-Xlist ${work} ../jemalloc > ${changes} || true
158    )
159    (
160      cd ${work_repo}
161      patch -p1 < ${changes} || true
162      find . -name '*.orig' -delete
163    )
164    # Update diff.
165    do_diff
166    ;;
167  extract) # Extract upstream sources, apply patches, copy to contrib/jemalloc.
168    rev=$1
169    do_extract ${rev}
170    # Delete existing files so that cruft doesn't silently remain.
171    rm -rf ChangeLog COPYING VERSION doc include src
172    # Copy files over.
173    tar cf - -C ${work_repo} -X FREEBSD-Xlist . |tar xvf -
174    internal_dir="include/jemalloc/internal"
175    grep -v ' isthreaded ' \
176      "${namespace_repo}/${internal_dir}/private_namespace.h" \
177      > "${internal_dir}/private_namespace.h"
178    ;;
179  rediff) # Regenerate diffs based on working tree.
180    do_diff
181    ;;
182  clean) # Remove working tree and temporary files.
183    rm -rf ${tmpdir} ${changes}
184    ;;
185  *)
186    echo "Unsupported command: \"${command}\"" >&2
187    exit 1
188    ;;
189esac
190