Compare commits

...

230 Commits

Author SHA1 Message Date
jaspreetsachdev
b3493bcf55 Merge pull request #538 from Telecominfraproject/v2.9.0-rc4
V2.9.0 rc4
2023-03-27 09:44:32 -04:00
Jaspreet Sachdev
2b767fb84f Merge remote-tracking branch 'origin/main' into v2.9.0 2023-03-23 12:59:06 -04:00
Piotr Dymacz
560e9f326d mcu: fix host support for multi-slot UART based MCUs
In case of MCU with multiple firmware slots support, change of active
slot requires reset. This obviously results in MCU entering the serial
recovery mode in bootloader, with 5 sec timeout, which in case of UART
based MCUs isn't automatically detected and handled in the same way as
USB based devices (hotplug).

Starting host side support script when the MCU is waiting for MCUmgr
commands during recovery is wrong. This fixes the problem by requesting
UART based MCU to boot the firmware after active slot change followed by
reset. While at it, change also how single slot type MCUs are handled
during upgrade (always request reset after the upgrade).

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-23 08:06:42 +01:00
John Crispin
3da1530926 ratelimit: SSIDs with spaces failed to be configured
Fixes: WIFI-12421
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-23 07:39:11 +01:00
Arif Alam
abcf6dd1fd ipq807x: fix mac address assignment
Signed-off-by: Arif Alam <arif.alam@netexperience.com>
2023-03-21 07:57:13 +01:00
Chaitanya Kiran Godavarthi
2bcedafe0d ipa807x: generate an ath11k-macs file on eap104
Signed-off-by: Chaitanya Kiran Godavarthi <chaitanya.kiran@netexperience.com>
2023-03-21 06:23:39 +01:00
jaspreetsachdev
71fc375a72 Merge pull request #534 from Telecominfraproject/v2.9.0-rc3
V2.9.0 rc3
2023-03-20 12:54:55 -04:00
Jaspreet Sachdev
95bfa265ee Merge remote-tracking branch 'origin/main' into v2.9.0 2023-03-20 12:54:09 -04:00
Piotr Dymacz
c0cf066900 mcu-firmware: include host support for 'hci_uart' firmware
This includes shell script for host side support of the 'hci_uart' MCU
firmware type. The script calls 'btattach' with matching tty interface
and baud rate as arguments, resulting in new Bluetooth HCI controller
registration in the system. Both UART and USB interfaces are supported.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-20 08:26:50 +01:00
Piotr Dymacz
6462efd6bc mcu: execute host side support script for firmware type
This adds support for executing a host side support script per firmware
type (in our case, full MCU firmware name is a combination of two terms:
'version__type', e.g. 'zephyr-v3.3.x__hci_uart') which currently runs on
the MCU. Additionally, support for calling the init script with 'stop'
argument is included.

The host side support scripts will be placed in '/etc/mcu.d/' and should
have executable flag set and be named after the firmware type, with 'sh'
extension (e.g. 'hci_uart.sh'). This solution assumes also that PID of a
running, related service will be stored in '/var/run/mcu.SN.pid' where
'SN' is the associated MCU serial number.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-20 08:26:50 +01:00
Piotr Dymacz
0bce7dc7a4 mcu-firmware: update 'zephyr-main' to 'cf50a3c570bb' (2023-03-10)
Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-20 08:26:50 +01:00
Piotr Dymacz
a3f0fb23b7 mcu-firmware: add support for host side support packages
In case of some of the MCU firmware types, additional setup on the host
side is required before the target application can be used. Example of
such a requirement is a BLE HCI controller on UART bus (firmware type:
'hci_uart') which, before can be registered in system, needs to be
attached to Bluetooth stack (with e.g. 'btattach').

This includes code for generating hidden packages under 'mcu-firmware'
with all the files required for host side support (stored in directory
with the same name as firmware type, under local 'files' directory),
for a selected MCU firmware. For example, below tree:

  ./feeds/mcu/mcu-firmware/files/hci_uart/etc/...

would result in creation of new package 'zephyr-hci_uart-host-support',
included in dependencies lists for all MCU firmware versions of the
'hci_uart' type, with everything from '.../files/hci_uart/'.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-20 08:26:50 +01:00
Piotr Dymacz
b9d20e083c mcu: simplify and fix 'mcu.sh' and 'mcu.hotplug' scripts
This reduces amount of helper functions and fixes also global variables
handle inside 'mcu.sh' and 'mcu.hotplug' shell scripts. While at it,
provide additional debug information when fetching images list and
system information.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-20 08:26:50 +01:00
Piotr Dymacz
725899248a mcu: update MCU if firmware hash doesn't match
This includes simple upgrade (downgrade) capability in the MCU support
package. If hash of firmware installed on the MCU doesn't match the one
available on host's local file system, it will get upgraded.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-20 08:26:50 +01:00
John Crispin
c8685f2352 ucentral-schema: update to latest HEAD
caac3f1 add support for secondary radius server

Fixes: WIFI-11979
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-20 08:26:35 +01:00
John Crispin
7d10d77e35 udevmand: update to latest HEAD
979aca4 mac addresses were never flushed

Fixes: WIFI-11973
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-16 17:08:59 +01:00
John Crispin
96c391eaac ucentral-event: fix captive portal rate-limiting
Fixes: WIFI-12305
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-16 17:08:14 +01:00
John Crispin
c700795895 ipq807x: add cig_wf660a to the CI workflow
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-16 08:30:28 +01:00
John Crispin
8bcb4c2063 ucentral-schema: update to latest HEAD
59c8214 hostapd parses psk-files in reverse order

Fixes: WIFI-12383
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-15 18:23:28 +01:00
jaspreetsachdev
fce075bd2c Merge pull request #532 from Telecominfraproject/v2.9.0-rc2
V2.9.0 rc2
2023-03-15 13:00:26 -04:00
John Crispin
ea95356ebd rtty: improve patch indenting
Newer version of GCC complained about inconsistent indenting.

Signed-off-by: John Crispin <john@phrozen.org>
2023-03-15 09:56:09 +01:00
Piotr Dymacz
8111566f35 feeds: ucentral: include BlueZ 5.66
Copy 'bluez' package from OpenWrt's packages master branch to 'ucentral'
feed so that we can use latest version and add custom, local changes.

Keep this within 'ucentral' feeds directory to override version provided
by community based 'packages' feed from OpenWrt 21.02.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-14 15:53:43 +01:00
John Crispin
c952b34858 ucentral-schema: update to latest HEAD
54453a6 cmd_script: custom scripts with no uri failed to send the stdout to the server

Fixes: WIFI-12358
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-14 14:52:23 +01:00
John Crispin
792e3a8a2e rtty: throttle the amount of data being pushed to the server
The socket died when too much data was sent too fast

Fixes: WIFI-12334
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-14 14:41:08 +01:00
John Crispin
ae75067938 ucentral-schema: default to 32 STA max assoc if the driver does not report a valid value
Fixes: WIFI-12355
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-13 15:03:24 +01:00
John Crispin
81b66ad44b dnsmasq: fix handling of option 38
Fixes: WIFI-12260
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-13 11:55:28 +01:00
John Crispin
e193250291 ucentral-schema: update to latest HEAD
5e08879 add additional event types

Signed-off-by: John Crispin <john@phrozen.org>
2023-03-13 07:49:54 +01:00
Piotr Dymacz
dc0dae6284 mcu: select host dependencies based on MCU firmware type
In case of some types of MCU firmware, additional tools, daemons, kernel
drivers, etc. are required on the host side. For example, for Bluetooth
HCI controller, at least kernel module and BlueZ should be included.

This adds a simple recipe which generates dependencies list per firmware
type/name and for existing 'hci_usb' and 'hci_uart', selects 3 packages:
'bluez-daemon', 'kmod-bluetooth' and 'kmod-crypto-user'.

Kernel crypto interface in user space has to be also included because
the BlueZ isn't able to create static address for LE-only controller
without it, which results in no registration of new BT interface:

  bluetoothd[668]: src/adapter.c:get_static_addr() Failed to open crypto
  bluetoothd[668]: No Bluetooth address for index 0

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-10 12:11:06 +01:00
John Crispin
7c535de60d ucentral-schema: update to latest HEAD
204341f state: add port_id and port_desc to lldp state

Fixes: WIFI-11975
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-09 16:40:58 +01:00
John Crispin
26192989cd ipq807x: add CIG WF196 BDF
split the image into 2 SKUs for CA/US.

Fixes: WIFI-12357
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-09 15:14:36 +01:00
John Crispin
317aaadcbd ucentral-schema: update to latest HEAD
0f40765 turn telemetry and realtime filter into an enum

Signed-off-by: John Crispin <john@phrozen.org>
2023-03-08 17:35:43 +01:00
Satya-sc
c670733ea5 ucentral-event: added support to queue the events when there is no ucentral client is running and send those once it is available
Signed-off-by: Satya-sc <Satya@shasta.cloud>
2023-03-08 17:20:21 +01:00
John Crispin
f92617f24a ipq807x: add zephyr specific profiles
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-08 17:18:53 +01:00
Piotr Dymacz
337a68cf1d mcu: ipq807x: add support for CIG WF-196
This includes default configuration for the on-board Nordic nRF52833 MCU
in CIG WF-196. A Zephyr based sample 'hci_uart' firmware is selected.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
e09633fc2a ipq807x: add Zephyr HCI UART MCU firmware to CIG WF-196
Include Zephyr v3.3.x based Bluetooth LE HCI UART firmware package in
default packages list for the CIG WF-196. This brings initial support
for the on-board nRF52833 MCU.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
d838391850 profiles: cig_wf196: include 'mcu' feed
Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
d59e58b794 mcu: ipq807x: add support for EdgeCore EAP102
This includes default configuration for the on-board Nordic nRF52840 MCU
in EdgeCore EAP102. A Zephyr based sample 'hci_usb' firmware is selected.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
ee7bf9671a ipq807x: add Zephyr HCI USB MCU firmware to EdgeCore EAP102
Include Zephyr v3.3.x based Bluetooth LE HCI USB firmware package in
default packages list for the EdgeCore EAP102. This brings initial
support for the on-board nRF52840 MCU.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
c4f0f367bc profiles: edgecore_eap102: include 'mcu' feed
Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
5f649ea1f4 mcu-firmware: include firmware based on latest Zephyr
This adds Zephyr firmware builds from custom git branch based on the
latest's upstream branch name 'main': 'main__mcu-on-wifi-boards'.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
397c6df34a feeds: mcu: introduce 'mcu-firmware' package
The new 'mcu-firmware' package will provide binary firmware dedicated
for MCU embedded on Wi-Fi boards (and also standalone, e.g. USB based),
supported by the OpenWrt/OpenWiFi projects. Currently, only Zephyr RTOS
based sample firmware ('BLE HCI controller' and 'hello world') files are
provided, for Wi-Fi boards and one standalone development module, listed
below:

- CIG WF-196 (Nordic nRF52833, UART bus)
- EdgeCore EAP102 (Nordic nRF52840, USB bus)
- Nordic nRF52840 Dongle (Nordic nRF52840, USB bus)

Different firmware types planned in future include Nordic's nRF Connect
SDK, OpenThread and others.

The Zephyr based firmware comes from a custom fork available in GitLab:
'https://gitlab.com/pepe2k/zephyr' (firmware in this package were built
from a v3.3.0 release based branch 'zephyr-v3.3.x__mcu-on-wifi-boards').

MCU firmware from this package is compatible only with OpenWrt/OpenWiFi
generic MCU support stack which, among others, assumes availability of
compatible bootloader (MCUboot is currently the only one supported) and
e.g. multiple firmware slots. MCUboot fork development takes part in git
repository hosted in GitLab: 'https://gitlab.com/pepe2k/mcuboot/'.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
7a37e9bf0b mcu: support default configuration with uci-defaults
This adds support for creating initial MCU configuration with use of
'uci-defaults' in a same was as for example 'uboot-envtools' package.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
e4ed881dd7 mcu: support OpenWiFi with uCentral
On device running OpenWiFi with uCentral, additional copy of the initial
UCI configuration will be generated in '/etc/config-shadow/'. As part of
the MCU configuration is done during runtime, after the 'config-shadow'
is created, we should update it as well to keep everything in sync.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
9aff26b7fb mcu: provide example UCI configuration file
Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
5603442a37 feeds: mcu: introduce 'mcu' package
This introduces new package 'mcu' which is a collection of shell based
scripts used as glue code for generic MCU configuration and management.

The scripts are responsible for communicating with embedded MCU running
compatible MCUboot bootloader version over MCUmgr/SMP protocol.
The communication is realized based on usage of the introduced earlier
dedicated CLI tool called 'umcumgr.

The most important function of this package is a simple MCU's firmware
management (checking firmware available in the MCU's internal flash,
uploading new and selecting active on multi-firmware slot capable MCU).

This solution requires MCU running modified version of MCUboot,
available in GitLab: https://gitlab.com/pepe2k/mcuboot

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Piotr Dymacz
8a86ae3b7d feeds: add mcu feed with 'umcumgr' package
The 'umcumgr' is a simple command line tool for MCU firmware management
over MCUmgr/SMP protocol. It will be used together with MCUboot running
on the on-board (or external, e.g. in form of a dongle) MCU.

While at it, add also dedicated 'mcu.yml' profile file.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-07 11:08:39 +01:00
Ken
9997af10a5 CIG WF-660A : Add WF-660a support [patch 3]
Fixed caldata.bin can NOT be generated with EMMC issue.
2023-03-06 10:41:39 +01:00
John Crispin
5fec90d4ca uspot: fix userurl and allow cleartext password
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-06 09:37:17 +01:00
Piotr Dymacz
f1a56edd09 ipq807x: backport some additional fixes for Bluetooth
This backports more fixes for the Bluetooth subsystem from 4.9.
They were found missing during some initial Bluetooth LE testing.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-02 16:43:05 +01:00
Piotr Dymacz
3f03cfa7c4 ipq807x: backport fix for Bluetooth LE-only HCI controllers
This backports an essential fix for Bluetooth LE-only HCI devices from
kernel 4.9: 39385cb5f327 ("Bluetooth: Fix using the correct source
address type").

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-03-02 16:43:05 +01:00
John Crispin
f34db0bb24 ucentral-schema: update to latest HEAD
5517c1c wifiscan: add additional options to the periodic scan feature

Fixes: WIFI-11993
Signed-off-by: John Crispin <john@phrozen.org>
2023-03-01 17:36:38 +01:00
John Crispin
94d154c628 qca-ssdk: reduce log noise
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-28 16:08:59 +01:00
John Crispin
071962440e ucentral-schema: update to latest HEAD
5287f72 fix wifiscan channel

Fixes: WIFI-11993
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-28 12:21:17 +01:00
John Crispin
5171b52570 hostapd: do not use ubus return codes as auth/assoc errors
Fixes: WIFI-12330
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-27 13:06:32 +01:00
John Crispin
fb282e2aff qca-ssdk: fix UE Roaming between vlans
Fixes: WIFI-11886
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-27 11:52:40 +01:00
John Crispin
5013b9c7fe ipq807x: update WF196 BDF files
Fixes: WIFI-12333
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-24 15:14:50 +01:00
John Crispin
0e2fcfcb95 ucentral-schema: update to latest HEAD
86dc187 the developer mode indication should be in the top level of the capa dictionary
f4aca9b indicate secure-rtty by default

Signed-off-by: John Crispin <john@phrozen.org>
2023-02-24 15:08:32 +01:00
John Crispin
a7ea6ef398 ucentral-event: fix ubus notification and band detect
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-24 15:06:56 +01:00
John Crispin
b4a2291dce ucentral-event: fix boot detection
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-23 11:35:49 +01:00
John Crispin
9348c426e5 ipq807x: fixup yuncore fap650 support
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-23 09:21:12 +01:00
John Crispin
678c4db8f0 ucentral-schema: update to latest HEAD
35cf7bf add more verbose error code to the script command

Signed-off-by: John Crispin <john@phrozen.org>
2023-02-22 15:21:29 +01:00
John Crispin
e979df64d1 ucentral-schema: update to latest HEAD
2ee157f fix health.uc: the events patch left a stray sprintf( breaking compile
ac9e8cf capabilities: add developer mode info to restrictions

Signed-off-by: John Crispin <john@phrozen.org>
2023-02-22 10:57:41 +01:00
Ken
43fa167f14 ipq807x: Add WF-660a support
Fixes: WIFI-12280
Signed-off-by: Ken <xshi@actiontec.com>
2023-02-22 10:03:05 +01:00
John Crispin
2a8858a3a2 uspot: fix an exception in the idle timeout handler
Fixes: WIFI-12282
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-22 09:41:48 +01:00
John Crispin
977d16557a ucentral-event: do not reset rate limit for captive clients
Fixes: WIFI-12305
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-21 15:56:19 +01:00
Satya-sc
3db254c306 ucentral-event: add unit boot-up event 2023-02-20 15:40:30 +01:00
John Crispin
9274c3a719 rtty: enable mTLS support
Fixes: WIFI-10516
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-20 15:40:30 +01:00
John Crispin
993ff2624e ucentral-event: add wired events
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-20 15:40:30 +01:00
John Crispin
60f6565d18 ucentral-event: make the ssh event payload a dictionary
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-20 10:41:14 +01:00
John Crispin
924d30af74 ucentral-event: add bssid to wifi events
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-20 10:40:08 +01:00
John Crispin
c55d19c3c5 ucentral-event: fix polled telemetry stream
Fixes: WIFI-12341
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-20 10:35:53 +01:00
John Crispin
9221c3e7e7 ucentral-schema: update to latest HEAD
bf8c384 properly stream state in telemetry mode

Fixes: WIFI-12314
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-20 10:33:03 +01:00
John Crispin
eb862cf2d2 ucentral-client: update to latest HEAD
2917158 ubus fix dump all telemetry

Fixes: WIFI-12314
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-20 10:32:19 +01:00
John Crispin
1e3cef1a26 mac80211: backport 230-get_txpower.patch
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-15 15:46:39 +01:00
Piotr Dymacz
50fd49fd3d ipq807x: eap102: keep MCU disabled by default
This would simplify MCU setup after bootup.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-02-15 15:21:45 +01:00
Piotr Dymacz
8e8a763485 ipq807x: eap102: export more USB related pins
This exports USB related pins in sysfs using 'gpio-export' as:
- usb-rear-power
- usb-side-power
- usb-hub-enable (renamed from 'usb-enable')

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-02-15 15:21:45 +01:00
Piotr Dymacz
ab47566e82 ipq807x: eap102: add more pin configs for USB and MCU
This adds few more pin configs for USB (rear and side ports power) and
MCU (reserved pin, apparently used by device vendor for DTM enable).

While at it, align labels and nodes names with staging branch.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-02-15 15:21:45 +01:00
Piotr Dymacz
e9a834c205 ipq807x: wf196: keep MCU disabled by default
This would simplify MCU setup after bootup.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-02-15 15:21:45 +01:00
Piotr Dymacz
6dc524e67b ipq807x: wf196: export MCU reset pin
This exports MCU reset pin as 'mcu-enable' in sysfs with 'gpio-export'.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-02-15 15:21:45 +01:00
Piotr Dymacz
b61b3aa06f ipq807x: wf196: add pin config for MCU reset
This adds config for nRF52833 MCU reset pin on the CIG WF-196.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-02-15 15:21:45 +01:00
Piotr Dymacz
b9d43eb897 ipq807x: tidy up CIG WF-196 DTS file
This change focuses on the I/O related cleanups for the CIG WF-196 DTS
file. Most of the removed definitions come from QCA reference files and
should have been adjusted for a custom board. List of changes:

1. Drop 'btcoex' pinctrl mux define
   WF-196 includes nRF52833 MCU which doesn't have dedicated PTA coex
   hardware interface (see [1] for software based solution in Nordic's
   nRF Connect SDK). Based on the real hardware research, defined pins
   from 'btcoex' mux aren't routed to nRF52833 MCU.

2. Drop 'spi_3' pinctrl mux define
   Defined label isn't used as reference in any other node and defined
   GPIOs most likely aren't used as well.

3. Drop GPIO 46 and 47 from hsuart pinctrl mux define
   It turned out that only UART TX and RX lines are routed between the
   main SOC (IPQ8072A) and the MCU (nRF52833).

While at it, fix also some broken indentation and redundant new lines.

[1] https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrfxlib/mpsl/doc/bluetooth_coex.html

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2023-02-15 15:21:45 +01:00
John Crispin
c069ba71cc ucentral-schema: update to latest HEAD
8c71638 fix listing mesh interfaces inside state
c3f6981 sysupgrade: GW sends FWsignature and not signature
94543ee state: cleanup and document the data model
6056d32 state: add [ avg, max ] cpu thermal sensor
900ce67 add phy temperature to state messages

Signed-off-by: John Crispin <john@phrozen.org>
2023-02-13 17:15:08 +01:00
John Crispin
df01a9acc0 ucentral-event: fix rtnl support
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-13 17:13:37 +01:00
Felix Fietkau
e0aa0eec98 ucode: add refcount fixes for rtnl/nl80211
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2023-02-13 15:24:52 +01:00
Tanya Singh
2a145ba46a WIFI-12182: Support Edgecore OAP100e
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2023-02-13 09:13:57 +01:00
John Crispin
9f34e57df8 ucentral-event: fix typo in events.json
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-08 09:04:30 +01:00
John Crispin
9c8affad09 ucode: backport rtnl notifications
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-08 08:43:31 +01:00
John Crispin
cd76797336 ucentral-schema: update to latest HEAD
17e7a3e fix lldp_description

Fixes: WIFI-12269
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-08 08:42:21 +01:00
John Crispin
feb26f21fd ucentral-event: add wifi-scan service
Fixes: WIFI-11993
Signed-off-by: John Crispin <john@phrozen.org>
2023-02-06 11:52:46 +01:00
Tanya Singh
5ff23ce3cf busybox: Fix Zero touch provisioning with DHCP option 138
Fixes: WIFI-12260
Signed-off-by: Tanya Singh <tanya_singh@accton.com>
2023-02-06 07:47:17 +01:00
Ravi Vaishnav
cacb8a23dd hostapd: Code for secondary RADIUS
Signed-off-by: Ravi Vaishnav <ravi.vaishnav@netexperience.com>
2023-02-05 09:41:55 +01:00
John Crispin
f5604d42f6 upgs: add package to default package selection
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 15:55:21 +01:00
John Crispin
8f74933b37 ucentral-schema: update to latest HEAD
f4f2e69 add cig_sha256

Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 14:32:15 +01:00
Venkat Chimata
2d92eeab07 openssl is needed to verify the command signatures 1. Enable openssl in AP firmware 2. Copy /certificates/sign_pubkey.pem into /etc/ucentral at boot time
Signed-off-by: Venkat Chimata <venkata@shasta.cloud>
2023-01-27 14:29:54 +01:00
John Crispin
c44ab8b4e6 ugps: update to latest HEAD
Fixes: WIFI-12238
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 14:25:41 +01:00
John Crispin
d3ad594940 ucentral-schema: update to latest HEAD
242a1a1 gps: add support to the data model

Fixes: WIFI-12238
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 13:41:58 +01:00
John Crispin
8f53da4f79 hostapd: make radius rate-limit work with new event listener framework
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
1cc9673e8c disable none active services
Fixes: WIFI-12237
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
Ravi Vaishnav
258e484d5f uboot-envtools: Fix syntax on number of sectors
ProblemStatement: On EAP104, "fw_setenv" fails with the error "MTD erase error on /dev/mtd10: Invalid argument"
RootCause: uboot-envtools expects hex format for the number of sectors while the config file (/etc/fw_env.config) contains a decimal number format for the number of sectors. This leads to out-of-boundary size calculation within the function "environment_end()".
Solution: Update the scripts to write a hex value instead of a decimal value in the config file.

Reference for the expected format from the config file: Please check the function "get_config" in the file "fw_env.c", where the function uses sscanf to read the parameters from the config file.

Fixes: WIFI-12189
Signed-off-by: Ravi Vaishnav <ravi.vaishnav@netexperience.com>
2023-01-27 12:18:37 +01:00
John Crispin
7edbe99599 ucentral-schema: update to latest HEAD
cd97d41 make sure that restricted country code errors get propagated

Fixes: WIFI-12001
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
fbcfddfbdc initial events support
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
0e75b82eb6 uspot: allow adding IPs to the walled-garden
Fixes: WIFI-12032
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
492db67f64 base-files: sysupgrade: always imply -n if -f is not provided
This ensures that no random config giles get carried over.

Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
6129f525d5 udevstats: add new package
This package uses eBPF to do traffic accounting ont he WAN port

Fixes: WIFI-12183
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
Oleksandr Mazur
2ec381534e ucentral-client: health: remove redundant check for zero value
config_get is issued with a default (120) parameter, which makes a check for 0
a redundant.
It can be safely removed, as the check for "[ "$interval" -eq 0 ]" is
always non-zero.

Fixes 396e2bd06c ("ucentral-client: cleanup health parameter")

Tested on virtual Wlan-AP img: no syntax error occured.

Signed-off-by: Oleksandr Mazur <cahbua@gmail.com>
2023-01-27 12:18:37 +01:00
John Crispin
29d6d9f1ea ucentral-schema: update to latest HEAD
47b470f make captive portal radius-gw-proxy aware

Fixes: WIFI-11705
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
a530af9354 uspot: fix endless STOP frames and add radius-gw-proxy
Fixes: WIFI-12044
Fixes: WIFI-11705
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
e42fd1e3a4 ucentral-client: update to latest HEAD
568a84a do not enforce CN validation when in self-signed mode

Fixes: WIFI-12099
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
30cfc34e1c opennds: drop package
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
0737a706ec ubpf: drop feed
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
b3589c92dc p4: drop feed
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
0f40cb8e77 ucentral-schema: update to latest HEAD
7f77f02 state: add [ avg, max ] cpu thermal sensor
e635ab8 add phy temperature to state messages

Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
a051edcd00 ucentral-client: remove sysupgrade preserved config
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
18b19c92be ucentral-wifi: deprecate package
Fixes: WIFI-11926
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
a2eabf35e3 ucentral-schema: update to latest HEAD
9dc66d7 fix listing mesh interfaces inside state
ad84690 only set port counter if they are available

Fixes: WIFI-11994
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
Johann Hoffmann
0dfe43f1e6 Add patches/x86 directory to config.yml
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2023-01-27 12:18:37 +01:00
John Crispin
20cda84f47 netifd: allow disabling unicast_to_multicast conversion on bridged wifi
Fixes: WIFI-11550
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
0228173d53 uspot: add mac-auth support
Fixes: WIFI-11895
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-27 12:18:37 +01:00
John Crispin
0db604ad1e Revert "ucentral-schema: update to latest HEAD"
This reverts commit e8bd819e39.
2023-01-16 16:46:48 +01:00
John Crispin
c53d342b6a uspot: fix exception during rediret
Fixes: WIFI-11995
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-16 14:56:17 +01:00
John Crispin
42e77e6f5a ipq807x: fix MAC assignment on WF188n
Fixes: WIFI-12090
Signed-off-by: John Crispin <john@phrozen.org>
2023-01-16 12:57:15 +01:00
John Crispin
e8bd819e39 ucentral-schema: update to latest HEAD
ec657b5 improve stability of reading counters

Signed-off-by: John Crispin <john@phrozen.org>
2023-01-13 14:09:25 +01:00
John Crispin
0c03b63c0f ucentral-schema: update to latest HEAD
ad84690 only set port counter if they are available

Signed-off-by: John Crispin <john@phrozen.org>
2023-01-12 06:02:39 +01:00
jaspreetsachdev
5ed2f1d964 Merge pull request #509 from Telecominfraproject/v2.8.0-rc4
V2.8.0 rc4
2022-12-20 10:16:06 -05:00
Jaspreet Sachdev
515793450e Merge branch 'main' into v2.8.0 2022-12-20 10:14:56 -05:00
John Crispin
541e9b0b4f ucentral-schema: update to latest HEAD
4278dfb gre: add dont fragment flag

Signed-off-by: John Crispin <john@phrozen.org>
2022-12-20 11:00:42 +01:00
jaspreetsachdev
24611df4c6 Merge pull request #508 from Telecominfraproject/v2.8.0-rc3
V2.8.0 rc3
2022-12-19 17:47:11 -05:00
Jaspreet Sachdev
083010d43c Merge branch 'main' into v2.8.0 2022-12-19 13:38:29 -05:00
John Crispin
f9b46fd6b0 ucentral-schema: update to latest HEAD
39dad34 wireguard: fix reload after reboot

Fixes: WIFI-12002
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-19 13:02:46 +01:00
John Crispin
74eb6f96ab atfpolicy: reduce ubus_wait timeout to 2s
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-19 13:01:49 +01:00
John Crispin
4967fcd2be hostapd: improve multi CoA support
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-18 15:25:27 +01:00
John Crispin
e973110de7 ath11k: fix mac assignment on cig wf196
Fixes: WIFI-11976
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-17 10:43:04 +01:00
John Crispin
a62503328b .github/workflows: add cig,wf194c4
Fixes: WIFI-11983
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-16 16:15:47 +01:00
John Crispin
e42051d3a9 hostapd: add dynamic_own_ip support
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-15 12:03:31 +01:00
John Crispin
e5336b7351 ucentral-schema: update to latest HEAD
b539203 include APVLAN associations inside state messages

Fixes: WIFI-11861
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-14 17:09:46 +01:00
John Crispin
5469af35f1 ucentral-schema: update to latest HEAD
6049cd7 various state improvements

Fixes: WIFI-11967
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-14 11:53:51 +01:00
John Crispin
8c9cd8f9d2 ratelimit: fix syntax error during parsing of wlanX-Y
Fixes: WIFI-11965
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-13 16:50:58 +01:00
John Crispin
8b3ac5ea36 uspot: purge pending flows during flush
Fixes: WIFI-11908
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-12 11:46:09 +01:00
John Crispin
c230825486 uspot: do not send accounting off upon logoff
Fixes: WIFI-11907
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-12 11:45:57 +01:00
John Crispin
e8b0f5da60 ucentral-schema: update to latest HEAD
53e3bb4 radio.channel should not be an array

Signed-off-by: John Crispin <john@phrozen.org>
2022-12-12 10:43:34 +01:00
John Crispin
bc45e11824 ucentral-schema: update to latest HEAD
e336aa4 add username to captive state

Fixes: WIFI-11896
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-12 08:22:56 +01:00
John Crispin
d6b3e97c34 ucentral-schema: update to latest HEAD
195ed80 fix multicast to unicast conversion on wifi

Fixes: WIFI-11550
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-12 07:44:48 +01:00
jaspreetsachdev
d35a12b4f4 Merge pull request #506 from Telecominfraproject/v2.8.0-rc2
V2.8.0 rc2
2022-12-09 13:33:12 -05:00
John Crispin
a42f103500 .github/workflows/: add yuncore fap640 to CI builds
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-08 18:14:44 +01:00
John Crispin
dc2a48c515 ucentral-schema: update to latest HEAD
f3c9972 state: add ssid counters
0329b38 state: make the tid-stats opt-in

Fixes: WIFI-11234
Fixes: WIFI-11928
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-08 18:09:20 +01:00
John Crispin
db617e23f0 ipq807x: do no keep uboot-env config during sysupgrade
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-08 15:31:30 +01:00
John Crispin
71189b1b74 ramips: add yuncore fap640 support
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-08 15:31:13 +01:00
John Crispin
5567de89e6 ipq807x: add yuncore fap650
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-08 10:12:54 +01:00
John Crispin
5430d79f53 .github/workflows/: add yuncore devices to CI
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-08 07:45:19 +01:00
John Crispin
9d82d88a0c ucentral-schema: update to latest HEAD
084fa1a use ucode handler to get channel survey
870a719 improve DFS channel restrictions

Signed-off-by: John Crispin <john@phrozen.org>
2022-12-07 17:48:18 +01:00
John Crispin
0e264203de luci-mod-ucentral: add diagnostic download button
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-07 17:47:33 +01:00
John Crispin
469443da2a profiles: fix indio image paths
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-07 12:03:04 +01:00
John Crispin
692958d2fd uspot: fix idle-timeout handling
Fixes: WIFI-11208
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-07 11:55:20 +01:00
Kishan Shukla
e65fa74071 ucentral-schema: add gre6 example config
Signed-off by: Kishan Shukla <kishan.shukla@hfcl.com>
2022-12-05 18:49:29 +01:00
Sohail Ahmad
fb64d45c39 From: Sohail Ahmad <sohail@indionetworks.com> Date: Mon Dec 5 02:58:36 2022 +0000 Subject: [PATCH] dnsmasq: enabled EDNS configuration options- CPE ID and subnet
Signed-off-by: Sohail Ahmad <sohail@indionetworks.com>
2022-12-05 11:45:06 +01:00
John Crispin
71e5c8f441 ucentral-schema: update to latest HEAD
c6ba7ce add diagnostic script support
5d70069 cmd_script: add an additional return json when upload was triggered

Signed-off-by: John Crispin <john@phrozen.org>
2022-12-05 11:13:46 +01:00
John Crispin
8e34f6653c .github/workflows/: add Indio's 11ax 2x2 models (indoor and outdoor) targets
Signed-off-by: Sohail Ahmad <sohail@indionetworks.com>
2022-12-02 14:45:06 +01:00
Rick Sommerville
bee060b9bb udhcpsnoop: snoop clients in GRE tunnel
Fixes WIFI-11710

Signed-off-by: Rick Sommerville <rick.sommerville@netexperience.com>
2022-12-02 14:16:01 +01:00
Arif Alam
e3e94fe520 base-files: make EAP104 switch ports configurable
Fixes WIFI-11709

Signed-off-by: Arif Alam <arif.alam@netexperience.com>
2022-12-02 14:14:41 +01:00
John Crispin
237c090cb4 uspot: add max octet support
Signed-off-by: John Crispin <john@phrozen.org>
2022-12-02 14:06:43 +01:00
John Crispin
74ea7a7a1e ucentral-schema: update to latest HEAD
efd60c9 add maximum_clients_ignore_probe support

Signed-off-by: John Crispin <john@phrozen.org>
2022-11-29 14:30:54 +01:00
John Crispin
330dbd49e6 uspot: properly set the ssid inside a UEs state
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-29 14:30:54 +01:00
John Crispin
a84b047061 ucode: fix a memory corruption
the uloop binding was not closing the uloop epoll fd correcttl when forking.

Signed-off-by: John Crispin <john@phrozen.org>
2022-11-29 14:30:54 +01:00
John Crispin
3795060bf2 uspot: properly terminate Acct when /logoff happens
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-29 14:30:54 +01:00
Johann Hoffmann
e61ab97815 .github/: Patch workflows with regard to deprecated Github actions commands (#502)
* Update checkout action version and replace set-output command
* Put whole echo statement in double quotes
* Replace set-output commands in action as well

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-11-29 14:30:34 +01:00
Piotr Dymacz
0162828df8 ipq807x: eap102: export MCU and USB reset pins
This exports MCU and USB reset pins in sysfs using 'gpio-export' as
'mcu-enable' and 'usb-enable'.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2022-11-23 14:55:03 +01:00
Piotr Dymacz
73cfef1203 ipq807x: eap102: add pin configs for USB and MCU reset
This adds configuration for reset pins connected with nRF52840 MCU and
the GL850G USB HUB on the EdgeCore EAP102.

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2022-11-23 14:54:53 +01:00
Piotr Dymacz
3eb6360054 ipq807x: tidy up EdgeCore EAP102 DTS file
This change focuses on the I/O related cleanups for the EdgeCore EAP102
DTS file. Most of the removed definitions come from QCA reference files
and should have been adjusted for a custom board. List of changes:

1. Drop 'btcoex' pinctrl mux define
   EAP102 includes nRF52840 MCU which doesn't have dedicated PTA coex
   hardware interface (see [1] for software based solution in Nordic's
   nRF Connect SDK). Based on the real hardware research, defined pins
   from 'btcoex' mux aren't routed to nRF52840 MCU.

2. Drop 'hsuart' pinctrl mux define and 'serial_blsp2' node
   Only one UART interface is used on the EAP102.

3. Drop 'usb_mux_sel' pinctrl mux
   Defined label isn't use as reference in any other node and defined
   GPIO most likely isn't used as well.

4. Disable 'pcie0' and remove 'pcie0' pinctrl mux
   EAP102 doesn't use of any of the IPQ8071A PCIe buses.

[1] https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrfxlib/mpsl/doc/bluetooth_coex.html

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2022-11-23 14:54:49 +01:00
Piotr Dymacz
47e4bc585a ipq807x: add named gpio exports
Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2022-11-23 14:54:12 +01:00
John Crispin
3746722a4d uspot: redirect to UAM server upon /logoff
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 13:34:31 +01:00
John Crispin
5828971cfe uspot: add support for propagating the Class VAP (25)
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 09:00:38 +01:00
John Crispin
dd911cbf21 uncentral-schema: update to latest HEAD
74fc62b captive: add /logout as a valid logoff path
18f7d08 captive: block remaining non-auth traffic in NAT mode
eb0c25c add signature verification wrapper
ef06d00 Add Support for EOGREv6

Fixes: WIFI-10887
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 09:00:38 +01:00
John Crispin
f167553348 spotfilter: do not flush ip addresses upon logoff
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 09:00:38 +01:00
John Crispin
d483c55c14 uspot: allow /logout in addition to /logoff
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 09:00:38 +01:00
John Crispin
d9815c0f62 radius-gw-proxy: fix possible memory corruption
Fixes: WIFI-10964
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 09:00:38 +01:00
John Crispin
daadf043d8 spotfilter: fix idle detection
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 09:00:38 +01:00
John Crispin
1a56d5820d ratelimit: improve hotplug trigger
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 09:00:38 +01:00
John Crispin
8e2f2fcce3 hostapd: add dynamic_probe_resp support
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-23 09:00:38 +01:00
John Crispin
fc5a841563 ucentral-schema: update to latest HEAD
c72603f wifi.station: code was incorrectly reporting MCS value inside NSS field

Fixes: WIFI-11599
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 16:05:36 +01:00
John Crispin
d511a338df uspot: add userurl to uam redirect parameters
Fixes: WIFI-11539
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 10:44:14 +01:00
John Crispin
a3d348b664 ipq807x: add initial support for MUXI AP3220L
Hardware:
* SoC: Qcom IPQ5018
* RAM: 512MB
* Flash: 4MB Nor + 128MB Nand
* Ethernet: 2x GbE
* WLAN: 2x2 2.4GHz 574Mbps(builtin) + 2x2 5GHz 2400Mbps(qcn6122)
* BT: BT5.1(builtin) / nrf52840(option)
* LEDS: 1x power, 1x 2G, 1x 5G
* Buttons: 1x reset
* USB: 1x 2.0(Type-A)
* Power: DC 12V/2A, PoE 48V/0.6A
* UART: 1x RJ45

Flash instruction under U-Boot:
tftpboot 0x44000000 openwrt-ipq807x-muxi_ap3220l-squashfs-nand-factory.bin
imxtract 0x44000000 ubi
flash rootfs
reset

Signed-off-by: angliu-muxi <ang.liu@muxi-connect.com>
2022-11-14 09:21:06 +01:00
Kishan
b48506b156 ip807x: HFCL WiFi6 ION4X and ION4X_2 target addition
Fixes: WIFI-11576
Signed-off by: Kishan Shukla <kishan.shukla@hfcl.com>
2022-11-14 08:19:36 +01:00
Isaev Ruslan
17bb88b67a ipq807x: wifi-ax/ath11-firmware/Makefile yuncore ax840 fix This define recipe for yuncore ax840 device to copy firmware to the correct location.
Signed-off-by: Isaev Ruslan <legale.legale@gmail.com>
2022-11-14 07:47:20 +01:00
John Crispin
578a616b00 ipq807x: ipq6018 based boards caldata size fix
This fixes size of the caldata for ipq60xx based boards and moves the
YunCore AX840 to correct case block (the board is IPQ60xx based, so
the driver looks for ath11k/IPQ6018/hw1.0/caldata.bin,
not ath11k/IPQ8074/hw2.0/caldata.bin). Without this fix, the driver
isn't able to fetch caldata:
[ 16.792551] ath11k c000000.wifi: qmi failed to load CAL data file:caldata.bin

Signed-off-by: Isaev Ruslan <legale.legale@gmail.com>
2022-11-14 07:47:20 +01:00
Piotr Dymacz
93f603e27c base-files: fix foreign sysupgrade detection
Backups are gzipped, include the missing 'z' parameter in 'tar' call.
While at it, make 'grep' call quiet (add 'q' parameter).

Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
2022-11-14 07:47:20 +01:00
John Crispin
09b513550c ucentral-schema: update to latest HEAD
b4b8e19 fix wifi unicast conversion
83761f9 fix dtim-period handling

Fixes: WIFI-11550
Fixes: WIFI-11546
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
5e451461cf central-client: update to latest HEAD
5f69da7 send restricted=1 on locked units

Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
fd33396acb ucentral-schema: update to latest HEAD
129d75a add final-redirect-rul for cpative portal support

Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
3bdfa68ff5 dnsmasq: ignore dhcp events on spotfilter-ifb
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
3dbc070f2c uspot: add final-redirect-url
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
b48e5eb057 ucentral-schema: add ASB bundle.uc
Fixes: WIFI-10967
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
3501bd9c11 ucentral-schema: update to latest HEAD
a509308 rssi thresholds are iface and not bss options

Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
70635ac911 ucentral-schema: update to latest HEAD
85698d2 move health_check settings tp the metric deictionary

Fixes: WIFI-11262
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
f9a00b7ebd ucentral-schema: update to latest HEAD
9968cb6 cmd_trace: limit maximum file size to 25% of free mem

Fixes: WIFI-11224
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
5bec28b7e5 ucentral-client: update to latest HEAD
6e774f6 upload: delete files after the upload completed

Fixes: WIFI-11224
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
Venkat Chimata
e41818470f Updating the board files for Liteon WPX8324.
Signed-off-by: Venkat Chimata <venkata@shasta.cloud>
2022-11-14 07:47:20 +01:00
John Crispin
a31422d3d7 ucentral-schema: update to latest HEAD
f941f47 healthcheck: set 60s as the minimum interval
85495ab wifi.iface was not converting 6G channels correctly

Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
bea3d2c4f8 usteer2: add new package
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
4c4cb58027 ucentral-schema: update to latest HEAD
8d4384b add session-timeout to captive support
516829a add client kick threshold support
5a5085b add uci_section to wifi uci

Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
4312a42b62 ucentral-client: update to latest HEAD
e39e9c2 add wildcard CN validation

Fixes: WIFI-10419
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
011e5b6e1a ucentral-schema: update to latest HEAD
0856cd5 add support for wifi mac acl

Signed-off-by: John Crispin <john@phrozen.org>
2022-11-14 07:47:20 +01:00
John Crispin
8233c10569 .github: add wallys_dr6018_v4 to the build pipeline
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-04 11:20:07 +01:00
John Crispin
fb73d889ed udevmand: update to latest HEAD
3d2b67b use u64 when reporting interface counters

Fixes: WIFI-11235
Signed-off-by: John Crispin <john@phrozen.org>
2022-11-02 16:34:38 +01:00
John Crispin
80bfb8671d spotfilter: fix sta detection when multiple ifaces are tracked
Fixes: WIFI-11272
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-29 08:56:04 +02:00
John Crispin
521df1a142 mac80211-ax: add NL80211_EXT_FEATURE_CAN_REPLACE_PTK0
Rekeying PTK for STA 2e:54:0a:55:25:c6 but driver can't safely do that.
Rekeying PTK for STA 48:26:2c:3e:b0:f4 but driver can't safely do that.
ath11k c000000.wifi: failed to flush transmit queue 0

Fixes: WIFI-11004
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-28 16:32:53 +02:00
John Crispin
72a75b72ac ipq807x: properly assign macs on wf196
Fixes: WIFI-10939
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-28 16:32:42 +02:00
jaspreetsachdev
c22dce10d3 Merge pull request #486 from elludraon/readme
Update README.md
2022-10-20 15:24:47 -04:00
Jeffrey Han
8eb801a0cc Update README.md
Signed-off-by: Jeffrey Han <39203126+elludraon@users.noreply.github.com>
2022-10-19 17:04:14 -07:00
jaspreetsachdev
6eaef7adad Merge pull request #484 from Telecominfraproject/2.7.1-fixes-from-next
2.7.1 fixes from next
2022-10-17 15:41:09 -04:00
John Crispin
0272d4bcad hostapd: AAA WISPr rates are sent as mbit
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-17 15:35:20 -04:00
John Crispin
41c64e9978 spotfilter: fix a use-after-free
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-17 15:35:20 -04:00
John Crispin
9c2f0a098d uspot: dns_state was not getting reset correctly when flushing a client
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-17 15:35:20 -04:00
John Crispin
0bb8d0dcc0 uspot: Session-Timeout AVP was not correctly honoured
Fixes: WIFI-10663
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-17 15:35:19 -04:00
John Crispin
a542660072 uspot: idle-timeout failed for non radius backed clients
Fixes: WIIF-11208
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-17 15:35:19 -04:00
John Crispin
8ee15d0053 uspot: fix unreolved variable in mac-format handler
Fixes: WIFI-11204
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-17 15:35:19 -04:00
John Crispin
311515867c uspot: add ssid to called-station-id
Signed-off-by: John Crispin <john@phrozen.org>
2022-10-17 15:35:19 -04:00
jaspreetsachdev
16bbcddd40 Merge branch 'main' of github.com:Telecominfraproject/wlan-ap 2022-10-17 14:24:06 -04:00
jaspreetsachdev
ca26d347eb Merge branch 'main' of github.com:Telecominfraproject/wlan-ap 2022-09-29 21:53:47 -04:00
Sohail Ahmad
9eeefa2fbf ipq807x: Support for Indio WiFi6 AP -indoor and outdoor models based on IPQ6000
Fixes: WIFI-10802
Signed-off-by: Sohail Ahmad <sohail.ahmad@wifi-soft.com>
2022-09-26 18:00:41 +02:00
Felix Fietkau
c33705ca60 qosify: update to the latest version
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2022-09-26 15:00:33 +02:00
Arif Alam
ba41e6773b ipq807x: Fix EAP104 upgrade
Signed-off-by: Arif Alam <arif.alam@netexperience.com>
2022-09-23 17:19:01 +02:00
John Crispin
8ebf884436 spotfilter: add a maissing v5.4 kernel backport
fixes an off-by-one bug in the validator

Signed-off-by: John Crispin <john@phrozen.org>
2022-09-23 17:19:01 +02:00
John Crispin
7d4353caf0 ucentral-client: update to latest HEAD
update wifi-scan timeout to 120s

Signed-off-by: John Crispin <john@phrozen.org>
2022-09-23 17:19:01 +02:00
John Crispin
fa6220a615 ucentral-schema: update to latest HEAD
55b8272 add support for overriding country codes

Signed-off-by: John Crispin <john@phrozen.org>
2022-09-22 15:14:05 +02:00
Felix Fietkau
26517bb6ae qosify: update to the latest version
fixes classification on linux 4.4

Signed-off-by: Felix Fietkau <nbd@nbd.name>
2022-09-22 07:47:21 +02:00
Felix Fietkau
ea4c4b3fe5 wifi-ax: backport mac80211 WME classification fix
Signed-off-by: Felix Fietkau <nbd@nbd.name>
2022-09-22 07:47:01 +02:00
John Crispin
00f273000e mac80211: fix multiple bssid mac addresses
Fixes: WIFI-10596
Signed-off-by: John Crispin <john@phrozen.org>
2022-09-21 09:45:05 +02:00
Jaspreet Sachdev
6014d3a04d .github/workflows: Removed deprecated targets
Signed-off-by: Jaspreet Sachdev <jaspreetsachdev@fb.com>
2022-09-20 08:56:55 +02:00
John Crispin
08f082acfe uspot: fix a typo causing config to not load correctly
Signed-off-by: John Crispin <john@phrozen.org>
2022-09-19 09:19:01 +02:00
Simon Kinane
12e5efcda4 uspot: Improve HTML for captive portal UI 2022-09-19 09:19:01 +02:00
341 changed files with 13865 additions and 53764 deletions

View File

@@ -15,7 +15,7 @@ runs:
id: import_snapshot
shell: bash
run: |
echo ::set-output name=import_task_id::$(aws ec2 import-snapshot --description '${{ inputs.firmware_image_name }}' --disk-container 'Format=raw,UserBucket={S3Bucket=${{ inputs.firmware_image_s3_bucket }},S3Key=${{ inputs.firmware_image_name }}}' | jq -r '.ImportTaskId')
echo "import_task_id=$(aws ec2 import-snapshot --description '${{ inputs.firmware_image_name }}' --disk-container 'Format=raw,UserBucket={S3Bucket=${{ inputs.firmware_image_s3_bucket }},S3Key=${{ inputs.firmware_image_name }}}' | jq -r '.ImportTaskId')" >> $GITHUB_OUTPUT
- name: Wait for import task to complete and get snapshot ID
id: get_snapshot_id
@@ -26,7 +26,7 @@ runs:
IMPORT_TASK_STATUS=$(aws ec2 describe-import-snapshot-tasks --import-task-ids ${{ steps.import_snapshot.outputs.import_task_id }} | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.Status')
echo "Import task status is $IMPORT_TASK_STATUS, waiting for completion."
done
echo ::set-output name=id::$(aws ec2 describe-import-snapshot-tasks --import-task-ids ${{ steps.import_snapshot.outputs.import_task_id }} | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.SnapshotId')
echo "id=$(aws ec2 describe-import-snapshot-tasks --import-task-ids ${{ steps.import_snapshot.outputs.import_task_id }} | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.SnapshotId')" >> $GITHUB_OUTPUT
- name: Tag snapshot with image name
shell: bash

View File

@@ -21,10 +21,10 @@ jobs:
strategy:
fail-fast: false
matrix:
target: ['actiontec_web7200', 'cig_wf188n', 'cig_wf196', 'cig_wf610d', 'cig_wf808', 'cybertan_eww622-a1', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'liteon_wpx8324', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'edgecore_spw2ac1200-lan-poe', 'hfcl_ion4', 'hfcl_ion4xe', 'hfcl_ion4xi', 'indio_um-305ac', 'indio_um-305ax', 'indio_um-325ac', 'indio_um-510ac-v3', 'indio_um-550ac', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'meshpp_s618_cp03', 'meshpp_s618_cp01', 'udaya_a5-id2', 'wallys_dr40x9', 'wallys_dr6018', 'x64_vm' ]
target: ['actiontec_web7200', 'cig_wf188n', 'cig_wf194c4', 'cig_wf196-us', 'cig_wf196-ca', 'cig_wf610d', 'cig_wf660a', 'cig_wf808', 'cybertan_eww622-a1', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'liteon_wpx8324', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'edgecore_spw2ac1200-lan-poe', 'hfcl_ion4', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'indio_um-305ac', 'indio_um-305ax', 'indio_um-325ac', 'indio_um-510ac-v3', 'indio_um-550ac', 'indio_um-310ax-v1', 'indio_um-510axp-v1', 'indio_um-510axm-v1', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'meshpp_s618_cp03', 'meshpp_s618_cp01', 'udaya_a5-id2', 'wallys_dr40x9', 'wallys_dr6018', 'wallys_dr6018_v4', 'x64_vm', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650' ]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build image for ${{ matrix.target }}
id: build
@@ -72,7 +72,7 @@ jobs:
[ -f openwrt/tmp/image-file ] && aws s3api put-object-tagging --bucket "$AWS_S3_BUCKET_NAME" --key "$JSON_NAME" --tagging "{\"TagSet\":[{\"Key\":\"release\",\"Value\":\"$IS_RELEASE\"}]}"
if [ ${{ matrix.target }} == 'x64_vm' ]; then
echo ::set-output name=x64_vm_image_name::"$(echo $IMG_NAME)"
echo "x64_vm_image_name=$(echo $IMG_NAME)" >> $GITHUB_OUTPUT
fi
trigger-testing:
@@ -93,7 +93,7 @@ jobs:
needs: build
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Use create-ami-from-image composite action
uses: ./.github/actions/create-ami-from-image

View File

@@ -22,7 +22,7 @@ jobs:
target: ['x64_vm']
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build image for ${{ matrix.target }}
id: build
@@ -70,14 +70,14 @@ jobs:
[ -f openwrt/tmp/image-file ] && aws s3api put-object-tagging --bucket "$AWS_S3_BUCKET_NAME" --key "$JSON_NAME" --tagging "{\"TagSet\":[{\"Key\":\"release\",\"Value\":\"$IS_RELEASE\"}]}"
if [[ ${{ matrix.target }} == 'x64_vm' ]]; then
echo ::set-output name=x64_vm_image_name::"$(echo $IMG_NAME)"
echo "x64_vm_image_name=$(echo $IMG_NAME)" >> $GITHUB_OUTPUT
fi
create-x64_vm-ami:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: WIFI-7206-add-workflow-to-build-virtual-ap-image

View File

@@ -1,20 +1,83 @@
# Setting up your build machine
# OpenWiFi AP NOS
Requires a recent linux installation. Older systems without python 3.7 will have trouble. See this link for details: https://openwrt.org/docs/guide-developer/quickstart-build-images
OpenWrt-based access point network operating system (AP NOS) for TIP OpenWiFi.
Read more at [openwifi.tip.build](https://openwifi.tip.build/).
Install build packages: sudo apt install build-essential libncurses5-dev gawk git libssl-dev gettext zlib1g-dev swig unzip time rsync python3 python3-setuptools python3-yaml.
## Building
# Doing a native build on Linux
First we need to clone and setup our tree. This will result in an openwrt/.
### Setting up your build machine
Building requires a recent Linux installation. Older systems without Python 3.7
will have trouble. See this guide for details:
https://openwrt.org/docs/guide-developer/toolchain/beginners-build-guide
Install build packages on Debian/Ubuntu (or see above guide for other systems):
```
./setup.py --setup
sudo apt install build-essential libncurses5-dev gawk git libssl-dev gettext zlib1g-dev swig unzip time rsync python3 python3-setuptools python3-yaml
```
Next we need to select the profile and base package selection. This setup will install the feeds, packages and generate the .config file.
### Doing a native build on Linux
Use `./build.sh <target>`, or follow the manual steps below:
1. Clone and set up the tree. This will create an `openwrt/` directory.
```shell
./setup.py --setup # for subsequent builds, use --rebase instead
```
2. Select the profile and base package selection. This setup will install the
feeds and packages and generate the `.config` file.
```shell
cd openwrt
./scripts/gen_config.py linksys_ea8300
```
Finally we can build the tree.
```
make -j X V=s
3. Build the tree (replace `-j 8` with the number of cores to use).
```shell
make -j 8 V=s
```
### Build output
The build results are located in the `openwrt/bin/` directory:
| Type | Path |
| ---------------- | ---------------------------------------------------- |
| Firmware images | `openwrt/bin/targets/<target>/<subtarget>/` |
| Kernel modules | `openwrt/bin/targets/<target>/<subtarget>/packages/` |
| Package binaries | `openwrt/bin/packages/<platform>/<feed>/` |
## Developer Notes
### Branching model
- `main` - Stable dev branch
- `next` - Integration branch
- `staging-*` - Feature/bug branches
- `release/v#.#.#` - Release branches (*major.minor.patch*)
### Repository structure
Build files:
- `Makefile` - Calls Docker environment per target
- `dock-run.sh` - Dockerized build environment
- `docker/Dockerfile` - Dockerfile for build image
- `build.sh` - Build script
- `setup.py` - Clone and set up the tree
- `config.yml` - Specifies OpenWrt version and patches to apply
Directories:
- `feeds/` - OpenWiFi feeds
- `patches/` - OpenWiFi patches applied during builds
- `profiles/` - Per-target kernel configs, packages, and feeds
- [wifi-ax](profiles/wifi-ax.yml): Wi-Fi AX packages
- [ucentral-ap](profiles/ucentral-ap.yml): uCentral packages
- [x64_vm](profiles/x64_vm.yml): x86-64 VM image
### uCentral packages
AP-NOS packages implementing the uCentral protocol include the following
repositories (refer to the [ucentral](feeds/ucentral/) feed for a full list):
- ucentral-client: https://github.com/Telecominfraproject/wlan-ucentral-client
- ucentral-schema: https://github.com/Telecominfraproject/wlan-ucentral-schema
- ucentral-wifi: https://github.com/blogic/ucentral-wifi

View File

@@ -14,3 +14,4 @@ patch_folders:
- patches/ipq807x
- patches/rtkmipsel
- patches/rest
- patches/x86

View File

@@ -40,6 +40,8 @@ liteon,wpx8324)
ucidef_set_led_netdev "wan" "wan" "blue:uplink" "eth0"
;;
hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe)
ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wifi5" "phy0tpt"
ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wifi2" "phy1tpt"
@@ -48,6 +50,11 @@ glinet,ax1800|\
glinet,axt1800)
ucidef_set_led_netdev "wan" "WAN" "blue:wan" "eth0" "tx rx link"
;;
yuncore,fap650|\
muxi,ap3220l)
ucidef_set_led_wlan "wlan2g" "WLAN2G" "green:wifi2" "phy0tpt"
ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wifi5" "phy1tpt"
;;
esac
board_config_flush

View File

@@ -13,6 +13,8 @@ qcom_setup_interfaces()
case $board in
hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe)
ucidef_set_interface_wan "eth0 eth1"
ucidef_set_interface_lan ""
@@ -49,14 +51,21 @@ qcom_setup_interfaces()
ucidef_set_interface_wan "eth0"
;;
edgecore,eap102|\
edgecore,eap104|\
liteon,wpx8324|\
wallys,dr6018|\
cig,wf188n|\
cig,wf196)
cig,wf196|\
muxi,ap3220l)
ucidef_set_interface_lan "eth1"
ucidef_set_interface_wan "eth0"
;;
cig,wf660a)
ucidef_set_interface_lan "eth0"
;;
yuncore,fap650)
ucidef_set_interface_lan "eth3 eth2 eth1 eth0"
ucidef_set_interface_wan "eth4"
;;
qcom,ipq807x-hk14)
ucidef_set_interface_lan "eth0 eth1 eth2 eth3"
ucidef_set_interface_wan "eth4"
@@ -76,6 +85,12 @@ qcom_setup_interfaces()
ucidef_add_switch_attr "switch1" "enable" "false"
ucidef_add_switch_attr "switch1" "reset" "true"
;;
edgecore,eap104)
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
ucidef_set_interface_wan "eth0"
ucidef_add_switch "switch1" \
"6@eth1" "1:lan1" "2:lan2" "3:lan3" "4:lan4"
;;
esac
}
@@ -84,14 +99,32 @@ qcom_setup_macs()
local board="$1"
case $board in
cig,wf188n|\
cig,wf194c|\
cig,wf194c4|\
cig,wf196)
mac=$(grep BaseMacAddress= /dev/mtd14 | cut -dx -f2)
cig,wf194c4)
mtd=$(find_mtd_chardev "0:APPSBLENV")
[ -z "$mtd" ] && return;
mac=$(grep BaseMacAddress= $mtd | cut -dx -f2)
[ -z "$mac" ] && return;
wan_mac=$(macaddr_canonicalize $mac)
lan_mac=$(macaddr_add "$wan_mac" 1)
ucidef_set_network_device_mac eth0 $lan_mac
ucidef_set_network_device_mac eth1 $wan_mac
ip link set eth0 address $lan_mac
ip link set eth1 address $wan_mac
ucidef_set_label_macaddr $wan_mac
;;
cig,wf196)
mtd=$(find_mtd_chardev "0:APPSBLENV")
[ -z "$mtd" ] && return;
mac=$(grep BaseMacAddress= $mtd | cut -dx -f2)
[ -z "$mac" ] && return;
wan_mac=$(macaddr_canonicalize $mac)
lan_mac=$(macaddr_add "$wan_mac" 1)
ucidef_set_network_device_mac eth1 $lan_mac
ucidef_set_network_device_mac eth0 $wan_mac
ip link set eth0 address $wan_mac
ip link set eth1 address $lan_mac
ucidef_set_label_macaddr $wan_mac
;;
cybertan,eww622-a1)
@@ -110,6 +143,18 @@ qcom_setup_macs()
wan_mac=$(cat /sys/class/net/eth1/address)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
yuncore,fap650)
wan_mac=$(cat /sys/class/net/eth4/address)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
muxi,ap3220l)
wan_mac=$(mtd_get_mac_binary 0:Product_Info 0x5b)
lan_mac=$(macaddr_add "$wan_mac" 1)
ucidef_set_network_device_mac eth0 $wan_mac
ucidef_set_network_device_mac eth1 $lan_mac
ip link set eth0 address $wan_mac
ip link set eth1 address $lan_mac
;;
*)
wan_mac=$(cat /sys/class/net/eth0/address)
lan_mac=$(macaddr_add "$wan_mac" 1)

View File

@@ -70,6 +70,9 @@ caldata_extract() {
local mtd
mtd=$(find_mtd_chardev $part)
if [ -z "$mtd" ]; then
mtd=/dev/$(echo $(find_mmc_part $part) | sed 's/^.\{5\}//')
fi
[ -n "$mtd" ] || caldata_die "no mtd device found for partition $part"
dd if=$mtd of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
@@ -93,7 +96,6 @@ case "$FIRMWARE" in
qcom,ipq807x-hk14|\
tplink,ex227|\
tplink,ex447|\
yuncore,ax840|\
sercomm,wallaby)
caldata_extract "0:ART" 0x1000 0x20000
;;
@@ -103,8 +105,11 @@ case "$FIRMWARE" in
case "$board" in
cig,wf188|\
cig,wf188n|\
cig,wf660a|\
edgecore,eap101|\
hfcl,ion4xi|\
hfcl,ion4x_2|\
hfcl,ion4x|\
hfcl,ion4xe|\
wallys,dr6018|\
wallys,dr6018-v4|\
@@ -114,6 +119,8 @@ case "$FIRMWARE" in
qcom,ipq6018-cp01|\
xiaomi,ax1800|\
glinet,ax1800|\
yuncore,ax840|\
yuncore,fap650|\
plasmacloud,pax1800-v1|\
plasmacloud,pax1800-v2)
caldata_extract "0:ART" 0x1000 0x20000
@@ -126,6 +133,7 @@ ath11k/IPQ5018/hw1.0/caldata.bin)
edgecore,eap104|\
liteon,wpx8324|\
motorola,q14|\
muxi,ap3220l|\
qcom,ipq5018-mp03.1)
caldata_extract "0:ART" 0x1000 0x20000
;;
@@ -145,6 +153,9 @@ ath11k/qcn6122/hw1.0/caldata_2.bin)
liteon,wpx8324)
caldata_extract "0:ART" 0x4c000 0x20000
;;
muxi,ap3220l)
caldata_extract "0:ART" 0x26800 0x20000
;;
esac
;;
ath11k/QCN9074/hw1.0/caldata_1.bin)
@@ -169,6 +180,8 @@ ath11k/QCN9074/hw1.0/caldata_2.bin)
ath11k-macs)
case "$board" in
hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe)
ath11k_generate_macs_ion4x
;;
@@ -177,15 +190,18 @@ ath11k-macs)
;;
yuncore,ax840|\
edgecore,eap102|\
edgecore,eap104|\
edgecore,eap106|\
indio,um-310ax-v1|\
indio,um-510axp-v1|\
indio,um-510axm-v1|\
cig,wf660a|\
cig,wf188n)
ath11k_generate_macs
;;
cig,wf194c|\
cig,wf194c)
cig,wf194c4|\
cig,wf196)
ath11k_generate_macs_wf194
;;
plasmacloud,pax1800-v1|\

View File

@@ -1,3 +1,3 @@
#!/bin/sh
mac=$(cat /etc/board.json | jsonfilter -e '@["network-device"]["'$DEVICENAME'"]'.macaddr)
mac=$(cat /etc/board.json | jsonfilter -e '@["network_device"]["'$DEVICENAME'"]'.macaddr)
[ -n "$mac" ] && ip link set $DEVICENAME address $mac

View File

@@ -50,6 +50,22 @@ do_flash_emmc() {
tar Oxf $tar_file ${board_dir}/$part | dd of=${emmcblock}
}
emmc_do_upgrade_cig() {
local tar_file="$1"
local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
board_dir=${board_dir%/}
do_flash_emmc $tar_file '0:HLOS_1' $board_dir kernel
do_flash_emmc $tar_file 'rootfs_1' $board_dir root
local emmcblock="$(find_mmc_part "rootfs_data")"
if [ -e "$emmcblock" ]; then
mkfs.ext4 -F "$emmcblock"
fi
}
emmc_do_upgrade() {
local tar_file="$1"
@@ -69,6 +85,7 @@ platform_check_image() {
board=$(board_name)
case $board in
cig,wf188|\
cig,wf660a|\
cig,wf188n|\
cig,wf194c|\
cig,wf194c4|\
@@ -87,13 +104,18 @@ platform_check_image() {
liteon,wpx8324|\
edgecore,eap106|\
hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe|\
muxi,ap3220l|\
plasmacloud,pax1800-v1|\
plasmacloud,pax1800-v2|\
tplink,ex227|\
tplink,ex447|\
yuncore,ax840|\
yuncore,fap650|\
motorola,q14|\
muxi,ap3220l|\
qcom,ipq6018-cp01|\
qcom,ipq807x-hk01|\
qcom,ipq807x-hk14|\
@@ -114,6 +136,9 @@ platform_do_upgrade() {
cig,wf188)
qca_do_upgrade $1
;;
cig,wf660a)
emmc_do_upgrade_cig $1
;;
motorola,q14)
emmc_do_upgrade $1
;;
@@ -134,6 +159,7 @@ platform_do_upgrade() {
wallys,dr6018|\
wallys,dr6018-v4|\
yuncore,ax840|\
yuncore,fap650|\
tplink,ex447|\
tplink,ex227|\
meshpp,s618-cp03|\
@@ -141,6 +167,8 @@ platform_do_upgrade() {
nand_upgrade_tar "$1"
;;
hfcl,ion4xi|\
hfcl,ion4x|\
hfcl,ion4x_2|\
hfcl,ion4xe)
if grep -q rootfs_1 /proc/cmdline; then
CI_UBIPART="rootfs"

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq5018-muxi-ap3220l.dts"
/ {
pmuv8: pmu {
compatible = "arm,cortex-a7-pmu";
};
};

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq6018-cig-wf660a.dts"
#include "qcom-ipq6018.dtsi"

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq6018-hfcl-ion4x.dts"
#include "qcom-ipq6018.dtsi"

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq6018-hfcl-ion4x_2.dts"
#include "qcom-ipq6018.dtsi"

View File

@@ -0,0 +1,18 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "../../../arm64/boot/dts/qcom/qcom-ipq6018-yuncore-fap650.dts"
#include "qcom-ipq6018.dtsi"

View File

@@ -0,0 +1,891 @@
/dts-v1/;
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq5018.dtsi"
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
model = "MUXI AP3220L";
compatible = "muxi,ap3220l", "qcom,ipq5018-mp03.5-c1", "qcom,ipq5018";
interrupt-parent = <&intc>;
aliases {
serial0 = &blsp1_uart1;
serial1 = &blsp1_uart2;
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
led-boot = &led_power;
led-failsafe = &led_power;
led-running = &led_power;
led-upgrade = &led_power;
};
chosen {
bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
#ifdef __IPQ_MEM_PROFILE_256_MB__
bootargs-append = " swiotlb=1";
#else
bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif
stdout-path = "serial0";
};
reserved-memory {
#ifdef __IPQ_MEM_PROFILE_256_MB__
/* 256 MB Profile
* +==========+==============+=========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +----------+--------------+-------------------------+
* | NSS | 0x40000000 | 8MB |
* +----------+--------------+-------------------------+
* | Linux | 0x40800000 | Depends on total memory |
* +----------+--------------+-------------------------+
* | uboot | 0x4A600000 | 4MB |
* +----------+--------------+-------------------------+
* | SBL | 0x4AA00000 | 1MB |
* +----------+--------------+-------------------------+
* | smem | 0x4AB00000 | 1MB |
* +----------+--------------+-------------------------+
* | TZ | 0x4AC00000 | 4MB |
* +----------+--------------+-------------------------+
* | Q6 | | |
* | code/ | 0x4B000000 | 20MB |
* | data | | |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | data | 0x4C400000 | 13MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | M3 Dump | 0x4D100000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | QDSS | 0x4D200000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | data | 0x4D300000 | 15MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | M3 Dump | 0x4E200000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | QDSS | 0x4E300000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | data | 0x4E400000 | 15MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | M3 Dump | 0x4F300000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | QDSS | 0x4F400000 | 1MB |
* +----------+--------------+-------------------------+
* | |
* | Rest of the memory for Linux |
* | |
* +===================================================+
*/
q6_mem_regions: q6_mem_regions@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x4500000>;
};
q6_code_data: q6_code_data@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x1400000>;
};
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
no-map;
reg = <0x0 0x4C400000 0x0 0xD00000>;
};
m3_dump: m3_dump@4D100000 {
no-map;
reg = <0x0 0x4D100000 0x0 0x100000>;
};
q6_etr_region: q6_etr_dump@4D200000 {
no-map;
reg = <0x0 0x4D200000 0x0 0x100000>;
};
q6_qcn6122_data1: q6_qcn6122_data1@4D300000 {
no-map;
reg = <0x0 0x4D300000 0x0 0xF00000>;
};
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E200000 {
no-map;
reg = <0x0 0x4E200000 0x0 0x100000>;
};
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E300000 {
no-map;
reg = <0x0 0x4E300000 0x0 0x100000>;
};
q6_qcn6122_data2: q6_qcn6122_data2@4E400000 {
no-map;
reg = <0x0 0x4E400000 0x0 0xF00000>;
};
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4F300000 {
no-map;
reg = <0x0 0x4F300000 0x0 0x100000>;
};
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4F400000 {
no-map;
reg = <0x0 0x4F400000 0x0 0x100000>;
};
#else
/* 512MB/1GB Profiles
* +==========+==============+=========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +----------+--------------+-------------------------+
* | NSS | 0x40000000 | 16MB |
* +----------+--------------+-------------------------+
* | Linux | 0x41000000 | Depends on total memory |
* +----------+--------------+-------------------------+
* | uboot | 0x4A600000 | 4MB |
* +----------+--------------+-------------------------+
* | SBL | 0x4AA00000 | 1MB |
* +----------+--------------+-------------------------+
* | smem | 0x4AB00000 | 1MB |
* +----------+--------------+-------------------------+
* | TZ | 0x4AC00000 | 4MB |
* +----------+--------------+-------------------------+
* | Q6 | | |
* | code/ | 0x4B000000 | 20MB |
* | data | | |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | data | 0x4C400000 | 14MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | M3 Dump | 0x4D200000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | QDSS | 0x4D300000 | 1MB |
* +----------+--------------+-------------------------+
* | IPQ5018 | | |
* | Caldb | 0x4D400000 | 2MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | data | 0x4D600000 | 16MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | M3 Dump | 0x4E600000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | QDSS | 0x4E700000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_1| | |
* | Caldb | 0x4E800000 | 5MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | data | 0x4ED00000 | 16MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | M3 Dump | 0x4FD00000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | QDSS | 0x4FE00000 | 1MB |
* +----------+--------------+-------------------------+
* | QCN6122_2| | |
* | Caldb | 0x4FF00000 | 5MB |
* +----------+--------------+-------------------------+
* | |
* | Rest of the memory for Linux |
* | |
* +===================================================+
*/
q6_mem_regions: q6_mem_regions@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 0x5400000>;
};
q6_code_data: q6_code_data@4B000000 {
no-map;
reg = <0x0 0x4B000000 0x0 01400000>;
};
q6_ipq5018_data: q6_ipq5018_data@4C400000 {
no-map;
reg = <0x0 0x4C400000 0x0 0xE00000>;
};
m3_dump: m3_dump@4D200000 {
no-map;
reg = <0x0 0x4D200000 0x0 0x100000>;
};
q6_etr_region: q6_etr_dump@4D300000 {
no-map;
reg = <0x0 0x4D300000 0x0 0x100000>;
};
q6_caldb_region: q6_caldb_region@4D400000 {
no-map;
reg = <0x0 0x4D400000 0x0 0x200000>;
};
q6_qcn6122_data1: q6_qcn6122_data1@4D600000 {
no-map;
reg = <0x0 0x4D600000 0x0 0x1000000>;
};
m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E600000 {
no-map;
reg = <0x0 0x4E600000 0x0 0x100000>;
};
q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E700000 {
no-map;
reg = <0x0 0x4E700000 0x0 0x100000>;
};
q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4E800000 {
no-map;
reg = <0x0 0x4E800000 0x0 0x500000>;
};
q6_qcn6122_data2: q6_qcn6122_data2@4E900000 {
no-map;
reg = <0x0 0x4ED00000 0x0 0x1000000>;
};
m3_dump_qcn6122_2: m3_dump_qcn6122_2@4FD00000 {
no-map;
reg = <0x0 0x4FD00000 0x0 0x100000>;
};
q6_qcn6122_etr_2: q6_qcn6122_etr_2@4FE00000 {
no-map;
reg = <0x0 0x4FE00000 0x0 0x100000>;
};
q6_qcn6122_caldb_2: q6_qcn6122_caldb_2@4FF00000 {
no-map;
reg = <0x0 0x4FF00000 0x0 0x500000>;
};
#endif
};
soc {
blsp1_uart1: serial@78af000 {
pinctrl-0 = <&blsp0_uart_pins>;
pinctrl-names = "default";
status = "okay";
};
blsp1_uart2: serial@78b0000 {
pinctrl-0 = <&blsp1_uart_pins>;
pinctrl-names = "default";
status = "disabled";
};
qpic_bam: dma@7984000{
status = "ok";
};
nand: qpic-nand@79b0000 {
pinctrl-0 = <&qspi_nand_pins>;
pinctrl-names = "default";
status = "ok";
};
spi_0: spi@78b5000 { /* BLSP1 QUP0 */
pinctrl-0 = <&blsp0_spi_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
mdio0: mdio@88000 {
status = "ok";
ethernet-phy@0 {
reg = <7>;
};
};
mdio1: mdio@90000 {
status = "ok";
pinctrl-0 = <&mdio1_pins &phy_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 39 0>;
ethernet-phy@0 {
reg = <0>;
};
ethernet-phy@1 {
reg = <1>;
};
ethernet-phy@2 {
reg = <2>;
};
ethernet-phy@3 {
reg = <3>;
};
};
ess-instance {
num_devices = <0x2>;
ess-switch@0x39c00000 {
compatible = "qcom,ess-switch-ipq50xx";
device_id = <0>;
switch_mac_mode = <0xf>; /* mac mode for uniphy instance*/
cmnblk_clk = "internal_96MHz"; /* cmnblk clk*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <7>;
};
port@1 {
port_id = <2>;
forced-speed = <1000>;
forced-duplex = <1>;
};
};
/*
led_source@0 {
source = <0>;
mode = "normal";
speed = "all";
blink_en = "enable";
active = "high";
};
*/
};
ess-switch1@1 {
compatible = "qcom,ess-switch-qca83xx";
device_id = <1>;
switch_access_mode = "mdio";
mdio-bus = <&mdio1>;
reset_gpio = <0x27>;
switch_cpu_bmp = <0x40>; /* cpu port bitmap */
switch_lan_bmp = <0x1e>; /* lan port bitmap */
switch_wan_bmp = <0x0>; /* wan port bitmap */
qca,ar8327-initvals = <
0x00004 0x7600000 /* PAD0_MODE */
0x00008 0x1000000 /* PAD5_MODE */
0x0000c 0x80 /* PAD6_MODE */
0x00010 0x2613a0 /* PORT6 FORCE MODE*/
0x000e4 0xaa545 /* MAC_POWER_SEL */
0x000e0 0xc74164de /* SGMII_CTRL */
0x0007c 0x4e /* PORT0_STATUS */
0x00094 0x4e /* PORT6_STATUS */
>;
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <0>;
};
port@1 {
port_id = <2>;
phy_address = <1>;
};
port@2 {
port_id = <3>;
phy_address = <2>;
};
port@3 {
port_id = <4>;
phy_address = <3>;
};
};
};
};
ess-uniphy@98000 {
status = "disabled";
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,id = <1>;
reg = <0x39C00000 0x10000>;
interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
qcom,mactype = <2>;
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <7>;
mdio-bus = <&mdio0>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>;
clock-names = "nss-snoc-gmac-axi-clk";
qcom,id = <2>;
reg = <0x39D00000 0x10000>;
interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
qcom,mactype = <2>;
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <3>;
mdio-bus = <&mdio1>;
local-mac-address = [000000000000];
phy-mode = "sgmii";
};
qcom,test@0 {
status = "ok";
};
};
thermal-zones {
status = "ok";
};
};
&tlmm {
//pinctrl-0 = <&phy_led_pins>;
pinctrl-names = "default";
blsp0_uart_pins: uart_pins {
blsp0_uart_rx_tx {
pins = "gpio20", "gpio21";
function = "blsp0_uart0";
bias-disable;
};
};
blsp1_uart_pins: blsp1_uart_pins {
blsp1_uart_rx_tx {
pins = "gpio23", "gpio25";
function = "blsp1_uart2";
bias-disable;
};
};
blsp0_spi_pins: blsp0_spi_pins {
mux {
pins = "gpio10", "gpio11", "gpio12", "gpio13";
function = "blsp0_spi";
drive-strength = <2>;
bias-disable;
};
};
qspi_nand_pins: qspi_nand_pins {
qspi_clock {
pins = "gpio9";
function = "qspi_clk";
drive-strength = <8>;
bias-disable;
};
qspi_cs {
pins = "gpio8";
function = "qspi_cs";
drive-strength = <8>;
bias-disable;
};
qspi_data_0 {
pins = "gpio7";
function = "qspi0";
drive-strength = <8>;
bias-disable;
};
qspi_data_1 {
pins = "gpio6";
function = "qspi1";
drive-strength = <8>;
bias-disable;
};
qspi_data_2 {
pins = "gpio5";
function = "qspi2";
drive-strength = <8>;
bias-disable;
};
qspi_data_3 {
pins = "gpio4";
function = "qspi3";
drive-strength = <8>;
bias-disable;
};
};
phy_pins: phy_pins {
phy_intr {
pins = "gpio29";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
bias-disable;
};
phy_reset {
pins = "gpio39";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
output-low;
};
};
mdio1_pins: mdio_pinmux {
mux_0 {
pins = "gpio36";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio37";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
};
phy_led_pins: phy_led_pins {
gephy_led_pin {
//pins = "gpio46";
function = "led0";
drive-strength = <8>;
bias-pull-down;
};
};
button_pins: button_pins {
reset_button {
pins = "gpio32";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
led_pins: led_pins {
led_pwr {
pins = "gpio26";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio31";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_5g {
pins = "gpio33";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
&soc {
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button@1 {
label = "reset_button";
linux,code = <KEY_RESTART>;
gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&led_pins>;
pinctrl-names = "default";
led_power: led_pwr {
label = "green:led_pwr";
gpios = <&tlmm 26 GPIO_ACTIVE_HIGH>;
default-state = "on";
linux,default-trigger = "led_pwr";
};
led_2g {
label = "green:wifi2";
gpio = <&tlmm 33 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
led_5g {
label = "green:wifi5";
gpio = <&tlmm 31 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
};
};
&usb3 {
status = "ok";
device-power-gpio = <&tlmm 30 1>;
};
&eud {
status = "ok";
};
&pcie_x1 {
status = "disabled";
perst-gpio = <&tlmm 18 1>;
};
&pcie_x2 {
status = "disabled";
perst-gpio = <&tlmm 15 1>;
};
&dwc_0 {
/delete-property/ #phy-cells;
/delete-property/ phys;
/delete-property/ phy-names;
};
&hs_m31phy_0 {
status = "ok";
};
&pcie_x1phy {
status = "disabled";
};
&pcie_x2phy {
status = "disabled";
};
&pcie_x1_rp {
status = "disabled";
mhi_0: qcom,mhi@0 {
reg = <0 0 0 0 0 >;
};
};
&pcie_x2_rp {
status = "disabled";
mhi_1: qcom,mhi@1 {
reg = <0 0 0 0 0 >;
};
};
&qfprom {
status = "ok";
};
&tsens {
status = "ok";
};
&qcom_q6v5_wcss {
qcom,multipd_arch;
memory-region = <&q6_mem_regions>;
qcom,share_bootargs;
qcom,bootargs_smem = <507>;
boot-args = <0x2 0x4 0x2 0xF 0x0 0x0>;
/* IPQ5018 */
q6v5_wcss_userpd1 {
m3_firmware = "IPQ5018/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 8 0>,
<&wcss_smp2p_in 9 0>,
<&wcss_smp2p_in 12 0>,
<&wcss_smp2p_in 11 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 8>,
<&wcss_smp2p_out 9>,
<&wcss_smp2p_out 10>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <1>;
qca,auto-restart;
qca,int_radio;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
<&q6_etr_region>;
#else
memory-region = <&q6_ipq5018_data>, <&m3_dump>,
<&q6_etr_region>, <&q6_caldb_region>;
#endif
};
/* QCN6122 6G */
q6v5_wcss_userpd2 {
m3_firmware = "qcn6122/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 16 0>,
<&wcss_smp2p_in 17 0>,
<&wcss_smp2p_in 20 0>,
<&wcss_smp2p_in 19 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 16>,
<&wcss_smp2p_out 17>,
<&wcss_smp2p_out 18>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <2>;
qca,auto-restart;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
<&q6_qcn6122_etr_1>;
#else
memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>,
<&q6_qcn6122_etr_1>, <&q6_qcn6122_caldb_1>;
#endif
};
/* QCN6122 5G */
q6v5_wcss_userpd3 {
m3_firmware = "qcn6122/m3_fw.mdt";
interrupts-extended = <&wcss_smp2p_in 24 0>,
<&wcss_smp2p_in 25 0>,
<&wcss_smp2p_in 28 0>,
<&wcss_smp2p_in 27 0>;
interrupt-names ="fatal",
"ready",
"spawn_ack",
"stop-ack";
qcom,smem-states = <&wcss_smp2p_out 24>,
<&wcss_smp2p_out 25>,
<&wcss_smp2p_out 26>;
qcom,smem-state-names = "shutdown",
"stop",
"spawn";
qca,asid = <3>;
qca,auto-restart;
#ifdef __IPQ_MEM_PROFILE_256_MB__
memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>,
<&q6_qcn6122_etr_2>;
#else
memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>,
<&q6_qcn6122_etr_2>, <&q6_qcn6122_caldb_2>;
#endif
};
};
&qgic_msi_0 {
status = "ok";
};
&qgic_msi_1 {
status = "ok";
};
&wifi0 {
/* IPQ5018 */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x24>;
qcom,bdf-addr = <0x4C400000 0x4C400000 0x4C400000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4D400000 0x4D400000 0 0 0>;
#else
qcom,caldb-addr = <0x4D400000>;
m3-dump-addr = <0x4D200000>;
#endif
qcom,caldb-size = <0x200000>;
status = "ok";
};
&wifi1 {
/* QCN6122 6G */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd2";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x60>;
qcom,bdf-addr = <0x4D600000 0x4D600000 0x4D300000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4E800000 0x4E800000 0 0 0>;
#else
qcom,caldb-addr = <0x4E800000>;
m3-dump-addr = <0x4E600000>;
#endif
qcom,caldb-size = <0x500000>;
status = "disabled";
};
&wifi2 {
/* QCN6122 5G */
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd3";
#ifdef __IPQ_MEM_PROFILE_256_MB__
qcom,tgt-mem-mode = <2>;
#else
qcom,tgt-mem-mode = <1>;
#endif
qcom,board_id = <0x60>;
qcom,bdf-addr = <0x4ED00000 0x4ED00000 0x4E400000 0x0 0x0>;
#ifdef __CNSS2__
qcom,caldb-addr = <0x4FF00000 0x4FF00000 0 0 0>;
#else
qcom,caldb-addr = <0x4FF00000>;
m3-dump-addr = <0x4FD00000>;
#endif
qcom,caldb-size = <0x500000>;
status = "ok";
};

View File

@@ -0,0 +1,590 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq6018.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
compatible = "cig,wf660a", "qcom,ipq6018-cp01", "qcom,ipq6018";
interrupt-parent = <&intc>;
qcom,msm-id = <0x192 0x0>, <0x193 0x0>;
aliases {
serial0 = &blsp1_uart3;
serial1 = &blsp1_uart2;
sdhc1 = &sdhc_1;
/*
* Aliases as required by u-boot
* to patch MAC addresses
*/
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
ethernet2 = "/soc/dp3";
ethernet3 = "/soc/dp4";
ethernet4 = "/soc/dp5";
};
chosen {
bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
#ifdef __IPQ_MEM_PROFILE_256_MB__
bootargs-append = " swiotlb=1";
#else
bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif
};
};
&tlmm {
pinctrl-0 = <&sd_ldo_pins>;
pinctrl-names = "default";
uart_pins: uart_pins {
mux {
pins = "gpio44", "gpio45";
function = "blsp2_uart";
drive-strength = <8>;
bias-pull-down;
};
};
sd_ldo_pins: sd_ldo_pins {
mux {
pins = "gpio66";
function = "gpio";
drive-strength = <2>;
bias-disable;
output-low;
};
};
spi_0_pins: spi_0_pins {
mux {
pins = "gpio38", "gpio39", "gpio40", "gpio41";
function = "blsp0_spi";
drive-strength = <8>;
bias-pull-down;
};
};
spi_1_pins: spi_1_pins {
mux {
pins = "gpio69", "gpio71", "gpio72";
function = "blsp1_spi";
drive-strength = <8>;
bias-pull-down;
};
spi_cs {
pins = "gpio70";
function = "blsp1_spi";
drive-strength = <8>;
bias-disable;
};
quartz_interrupt {
pins = "gpio78";
function = "gpio";
input;
bias-disable;
};
quartz_reset {
pins = "gpio79";
function = "gpio";
output-low;
bias-disable;
};
};
qpic_pins: qpic_pins {
data_0 {
pins = "gpio15";
function = "qpic_pad0";
drive-strength = <8>;
bias-pull-down;
};
data_1 {
pins = "gpio12";
function = "qpic_pad1";
drive-strength = <8>;
bias-pull-down;
};
data_2 {
pins = "gpio13";
function = "qpic_pad2";
drive-strength = <8>;
bias-pull-down;
};
data_3 {
pins = "gpio14";
function = "qpic_pad3";
drive-strength = <8>;
bias-pull-down;
};
data_4 {
pins = "gpio5";
function = "qpic_pad4";
drive-strength = <8>;
bias-pull-down;
};
data_5 {
pins = "gpio6";
function = "qpic_pad5";
drive-strength = <8>;
bias-pull-down;
};
data_6 {
pins = "gpio7";
function = "qpic_pad6";
drive-strength = <8>;
bias-pull-down;
};
data_7 {
pins = "gpio8";
function = "qpic_pad7";
drive-strength = <8>;
bias-pull-down;
};
qpic_pad {
pins = "gpio1", "gpio3", "gpio4",
"gpio10", "gpio11", "gpio17";
function = "qpic_pad";
drive-strength = <8>;
bias-pull-down;
};
};
sd_pins: sd_pins {
mux {
pins = "gpio62";
function = "sd_card";
drive-strength = <8>;
bias-pull-up;
};
};
extcon_usb_pins: extcon_usb_pins {
mux {
pins = "gpio26";
function = "gpio";
drive-strength = <2>;
bias-pull-down;
};
};
button_pins: button_pins {
wps_button {
pins = "gpio9";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
reset_button {
pins = "gpio19";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
mdio_pins: mdio_pinmux {
mux_0 {
pins = "gpio64";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio65";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
mux_2 {
pins = "gpio75";
function = "gpio";
bias-pull-up;
};
mux_3 {
pins = "gpio77";
function = "gpio";
bias-pull-up;
};
};
leds_pins: leds_pins {
led_5g {
pins = "gpio35";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio37";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_usb0 {
pins = "gpio50";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
hsuart_pins: hsuart_pins {
mux {
pins = "gpio71", "gpio72";
function = "blsp1_uart";
drive-strength = <8>;
bias-disable;
};
};
btcoex_pins: btcoex_pins {
mux_0 {
pins = "gpio51";
function = "pta1_1";
drive-strength = <6>;
bias-pull-down;
};
mux_1 {
pins = "gpio53";
function = "pta1_0";
drive-strength = <6>;
bias-pull-down;
};
mux_2 {
pins = "gpio52";
function = "pta1_2";
drive-strength = <6>;
bias-pull-down;
};
};
pwm_pins: pwm_pinmux {
mux_1 {
pins = "gpio22";
function = "pwm02";
drive-strength = <8>;
};
mux_2 {
pins = "gpio23";
function = "pwm12";
drive-strength = <8>;
};
mux_3 {
pins = "gpio24";
function = "pwm22";
drive-strength = <8>;
};
};
};
&soc {
pwm {
pinctrl-0 = <&pwm_pins>;
pinctrl-names = "default";
used-pwm-indices = <1>, <1>, <1>, <0>;
status = "ok";
};
extcon_usb: extcon_usb {
pinctrl-0 = <&extcon_usb_pins>;
pinctrl-names = "default";
id-gpio = <&tlmm 26 GPIO_ACTIVE_LOW>;
status = "ok";
};
mdio: mdio@90000 {
pinctrl-0 = <&mdio_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 75 0 &tlmm 77 1>;
status = "ok";
phy0: ethernet-phy@0 {
reg = <0>;
};
phy1: ethernet-phy@1 {
reg = <1>;
};
phy2: ethernet-phy@2 {
reg = <2>;
};
phy3: ethernet-phy@3 {
reg = <3>;
};
phy4: ethernet-phy@4 {
reg = <0x1c>;
};
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <1>;
reg = <0x3a001000 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <0>;
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <2>;
reg = <0x3a001200 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <1>;
phy-mode = "sgmii";
};
dp3 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <3>;
reg = <0x3a001400 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <2>;
phy-mode = "sgmii";
};
dp4 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <4>;
reg = <0x3a001600 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <3>;
phy-mode = "sgmii";
};
dp5 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <5>;
reg = <0x3a001800 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <28>;
phy-mode = "sgmii";
};
nss-macsec0 {
compatible = "qcom,nss-macsec";
phy_addr = <0x1c>;
phy_access_mode = <0>;
mdiobus = <&mdio>;
};
ess-switch@3a000000 {
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x1e>; /* lan port bitmap */
switch_wan_bmp = <0x20>; /* wan port bitmap */
switch_inner_bmp = <0xc0>; /*inner port bitmap*/
switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <0>;
};
port@1 {
port_id = <2>;
phy_address = <1>;
};
port@2 {
port_id = <3>;
phy_address = <2>;
};
port@3 {
port_id = <4>;
phy_address = <3>;
};
port@4 {
port_id = <5>;
phy_address = <0x1c>;
port_mac_sel = "QGMAC_PORT";
};
};
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
wps {
label = "wps";
linux,code = <KEY_WPS_BUTTON>;
gpios = <&tlmm 9 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
reset {
label = "reset";
linux,code = <KEY_POWER>;
gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led@35 {
label = "led_5g";
gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "led_5g";
default-state = "off";
};
led@37 {
label = "led_2g";
gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "led_2g";
default-state = "off";
};
led@50 {
label = "led_usb0";
gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "usb-host";
default-state = "off";
};
};
i2c_4: i2c@78b9000 {
compatible = "qcom,i2c-qup-v2.2.1";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x78b9000 0x600>;
interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP1_AHB_CLK>,<&gcc GCC_BLSP1_QUP5_I2C_APPS_CLK>;
clock-names = "iface", "core";
clock-frequency = <100000>;
dmas = <&blsp_dma 21>, <&blsp_dma 20>;
dma-names = "rx", "tx";
status = "disabled";
};
};
&blsp1_uart3 {
pinctrl-0 = <&uart_pins>;
pinctrl-names = "default";
status = "ok";
};
&spi_0 {
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
&blsp1_uart2 {
pinctrl-0 = <&hsuart_pins>;
pinctrl-names = "default";
status = "ok";
};
&spi_1 { /* BLSP1 QUP1 */
pinctrl-0 = <&spi_1_pins>;
pinctrl-names = "default";
cs-select = <0>;
quartz-reset-gpio = <&tlmm 79 1>;
status = "disabled";
spidev1: spi@1 {
compatible = "qca,spidev";
reg = <0>;
spi-max-frequency = <24000000>;
};
};
&qpic_bam {
status = "ok";
};
&nand {
pinctrl-0 = <&qpic_pins>;
pinctrl-names = "default";
status = "disable";
};
&ssphy_0 {
status = "ok";
};
&qusb_phy_0 {
status = "ok";
};
&qusb_phy_1 {
status = "ok";
};
&usb2 {
status = "ok";
};
&usb3 {
status = "ok";
};
&nss_crypto {
status = "ok";
};
&pcie_phy {
status = "ok";
};
&pcie0 {
#if defined(__CNSS2__)
status = "ok";
#endif
};
&qpic_lcd {
status = "ok";
};
&qpic_lcd_panel {
status = "ok";
};

View File

@@ -0,0 +1,120 @@
/dts-v1/;
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq6018-cig-wf660a-cp01.dtsi"
#include "qcom-ipq6018-rpm-regulator.dtsi"
#include "qcom-ipq6018-cpr-regulator.dtsi"
#include "qcom-ipq6018-cp-cpu.dtsi"
/ {
model = "Cigtech WF-660a";
/*
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 139MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | TZ App | 0x49B00000 | 6MB |
* +--------+--------------+-------------------------+
*
* From the available 145 MB for Linux in the first 256 MB,
* we are reserving 6 MB for TZAPP.
*
* Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
* for memory layout.
*/
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
reserved-memory {
tzapp:tzapp@49B00000 { /* TZAPPS */
no-map;
reg = <0x0 0x49B00000 0x0 0x00600000>;
};
};
#endif
};
&tlmm {
i2c_0_pins: i2c_0_pins {
mux {
pins = "gpio69", "gpio70";
function = "blsp1_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
i2c_1_pins: i2c_1_pins {
mux {
pins = "gpio42", "gpio43";
function = "blsp2_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
i2c_4_pins: i2c_4_pins {
mux {
pins = "gpio55", "gpio56";
function = "blsp4_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
};
&i2c_0 {
pinctrl-0 = <&i2c_0_pins>;
pinctrl-names = "default";
status = "ok";
};
&i2c_1 {
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
status = "ok";
};
&i2c_4 {
pinctrl-0 = <&i2c_4_pins>;
pinctrl-names = "default";
status = "ok";
};
&sdhc_1 {
status = "ok";
};
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
&qseecom {
mem-start = <0x49B00000>;
mem-size = <0x600000>;
status = "ok";
};
#endif

View File

@@ -0,0 +1,155 @@
/dts-v1/;
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq6018-cp01-hfcl.dtsi"
#include "qcom-ipq6018-rpm-regulator.dtsi"
#include "qcom-ipq6018-cpr-regulator.dtsi"
#include "qcom-ipq6018-cp-cpu.dtsi"
/ {
model = "HFCL ION4X";
compatible = "hfcl,ion4x", "qcom,ipq6018-cp01", "qcom,ipq6018";
/*
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 139MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | TZ App | 0x49B00000 | 6MB |
* +--------+--------------+-------------------------+
*
* From the available 145 MB for Linux in the first 256 MB,
* we are reserving 6 MB for TZAPP.
*
* Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
* for memory layout.
*/
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
reserved-memory {
tzapp:tzapp@49B00000 { /* TZAPPS */
no-map;
reg = <0x0 0x49B00000 0x0 0x00600000>;
};
};
#endif
};
&tlmm {
i2c_1_pins: i2c_1_pins {
mux {
pins = "gpio42", "gpio43";
function = "blsp2_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
i2c_2_pins: i2c_2_pins {
mux {
pins = "gpio55", "gpio56";
function = "blsp4_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
};
&i2c_1 {
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
status = "ok";
lm75@48 {
compatible = "lm75";
reg = <0x48>;
status = "okay";
};
};
&i2c_2 {
pinctrl-0 = <&i2c_2_pins>;
pinctrl-names = "default";
status = "ok";
};
&sdhc_2 {
pinctrl-0 = <&sd_pins>;
pinctrl-names = "default";
cd-gpios = <&tlmm 62 1>;
sd-ldo-gpios = <&tlmm 66 0>;
vqmmc-supply = <&ipq6018_l2_corner>;
status = "ok";
};
&soc {
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led@60 {
label = "blue:wifi5";
gpios = <&tlmm 60 GPIO_ACTIVE_LOW>;
linux,default-trigger = "led_5g";
default-state = "off";
};
led@61 {
label = "blue:wifi2";
gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
linux,default-trigger = "led_2g";
default-state = "off";
};
};
};
&tlmm {
leds_pins: leds_pins {
led_5g {
pins = "gpio60";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio61";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
&qseecom {
mem-start = <0x49B00000>;
mem-size = <0x600000>;
status = "ok";
};
#endif

View File

@@ -0,0 +1,155 @@
/dts-v1/;
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq6018-cp01-hfcl.dtsi"
#include "qcom-ipq6018-rpm-regulator.dtsi"
#include "qcom-ipq6018-cpr-regulator.dtsi"
#include "qcom-ipq6018-cp-cpu.dtsi"
/ {
model = "HFCL ION4X_2";
compatible = "hfcl,ion4x_2", "qcom,ipq6018-cp01", "qcom,ipq6018";
/*
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 139MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | TZ App | 0x49B00000 | 6MB |
* +--------+--------------+-------------------------+
*
* From the available 145 MB for Linux in the first 256 MB,
* we are reserving 6 MB for TZAPP.
*
* Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
* for memory layout.
*/
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
reserved-memory {
tzapp:tzapp@49B00000 { /* TZAPPS */
no-map;
reg = <0x0 0x49B00000 0x0 0x00600000>;
};
};
#endif
};
&tlmm {
i2c_1_pins: i2c_1_pins {
mux {
pins = "gpio42", "gpio43";
function = "blsp2_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
i2c_2_pins: i2c_2_pins {
mux {
pins = "gpio55", "gpio56";
function = "blsp4_i2c";
drive-strength = <8>;
bias-pull-down;
};
};
};
&i2c_1 {
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
status = "ok";
lm75@48 {
compatible = "lm75";
reg = <0x48>;
status = "okay";
};
};
&i2c_2 {
pinctrl-0 = <&i2c_2_pins>;
pinctrl-names = "default";
status = "ok";
};
&sdhc_2 {
pinctrl-0 = <&sd_pins>;
pinctrl-names = "default";
cd-gpios = <&tlmm 62 1>;
sd-ldo-gpios = <&tlmm 66 0>;
vqmmc-supply = <&ipq6018_l2_corner>;
status = "ok";
};
&soc {
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led@60 {
label = "blue:wifi5";
gpios = <&tlmm 60 GPIO_ACTIVE_LOW>;
linux,default-trigger = "led_5g";
default-state = "off";
};
led@61 {
label = "blue:wifi2";
gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
linux,default-trigger = "led_2g";
default-state = "off";
};
};
};
&tlmm {
leds_pins: leds_pins {
led_5g {
pins = "gpio60";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio61";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
&qseecom {
mem-start = <0x49B00000>;
mem-size = <0x600000>;
status = "ok";
};
#endif

View File

@@ -0,0 +1,423 @@
/dts-v1/;
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "qcom-ipq6018.dtsi"
#include "qcom-ipq6018-rpm-regulator.dtsi"
#include "qcom-ipq6018-cpr-regulator.dtsi"
#include "qcom-ipq6018-cp-cpu.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
model = "Yuncore FAP650";
compatible = "yuncore,fap650", "qcom,ipq6018-cp03", "qcom,ipq6018";
interrupt-parent = <&intc>;
qcom,msm-id = <0x1A5 0x0>;
aliases {
/*
* Aliases as required by u-boot
* to patch MAC addresses
*/
ethernet0 = "/soc/dp5";
ethernet1 = "/soc/dp4";
ethernet2 = "/soc/dp3";
ethernet3 = "/soc/dp2";
ethernet4 = "/soc/dp1";
led-boot = &led_power;
led-failsafe = &led_power;
led-running = &led_power;
led-upgrade = &led_power;
};
chosen {
bootargs = "console=ttyMSM0,115200,n8 rw init=/init";
#ifdef __IPQ_MEM_PROFILE_256_MB__
bootargs-append = " swiotlb=1";
#else
bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif
};
/*
* +=========+==============+========================+
* | | | |
* | Region | Start Offset | Size |
* | | | |
* +--------+--------------+-------------------------+
* | | | |
* | | | |
* | | | |
* | | | |
* | Linux | 0x41000000 | 139MB |
* | | | |
* | | | |
* | | | |
* +--------+--------------+-------------------------+
* | TZ App | 0x49B00000 | 6MB |
* +--------+--------------+-------------------------+
*
* From the available 145 MB for Linux in the first 256 MB,
* we are reserving 6 MB for TZAPP.
*
* Refer arch/arm64/boot/dts/qcom/qcom-ipq6018-memory.dtsi
* for memory layout.
*/
/* TZAPP is enabled only in default memory profile */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
reserved-memory {
tzapp:tzapp@49B00000 { /* TZAPPS */
no-map;
reg = <0x0 0x49B00000 0x0 0x00600000>;
};
};
#endif
};
&tlmm {
uart_pins: uart_pins {
mux {
pins = "gpio44", "gpio45";
function = "blsp2_uart";
drive-strength = <8>;
bias-pull-down;
};
};
spi_0_pins: spi_0_pins {
mux {
pins = "gpio38", "gpio39", "gpio40", "gpio41";
function = "blsp0_spi";
drive-strength = <8>;
bias-pull-down;
};
};
qpic_pins: qpic_pins {
data_0 {
pins = "gpio15";
function = "qpic_pad0";
drive-strength = <8>;
bias-pull-down;
};
data_1 {
pins = "gpio12";
function = "qpic_pad1";
drive-strength = <8>;
bias-pull-down;
};
data_2 {
pins = "gpio13";
function = "qpic_pad2";
drive-strength = <8>;
bias-pull-down;
};
data_3 {
pins = "gpio14";
function = "qpic_pad3";
drive-strength = <8>;
bias-pull-down;
};
data_4 {
pins = "gpio5";
function = "qpic_pad4";
drive-strength = <8>;
bias-pull-down;
};
data_5 {
pins = "gpio6";
function = "qpic_pad5";
drive-strength = <8>;
bias-pull-down;
};
data_6 {
pins = "gpio7";
function = "qpic_pad6";
drive-strength = <8>;
bias-pull-down;
};
data_7 {
pins = "gpio8";
function = "qpic_pad7";
drive-strength = <8>;
bias-pull-down;
};
qpic_pad {
pins = "gpio1", "gpio3", "gpio4",
"gpio10", "gpio11", "gpio17";
function = "qpic_pad";
drive-strength = <8>;
bias-pull-down;
};
};
button_pins: button_pins {
wps_button {
pins = "gpio19";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
mdio_pins: mdio_pinmux {
mux_0 {
pins = "gpio64";
function = "mdc";
drive-strength = <8>;
bias-pull-up;
};
mux_1 {
pins = "gpio65";
function = "mdio";
drive-strength = <8>;
bias-pull-up;
};
mux_2 {
pins = "gpio75";
function = "gpio";
bias-pull-up;
};
};
leds_pins: leds_pins {
led_sys {
pins = "gpio32";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_5g {
pins = "gpio35";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
led_2g {
pins = "gpio37";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
};
&soc {
mdio@90000 {
pinctrl-0 = <&mdio_pins>;
pinctrl-names = "default";
phy-reset-gpio = <&tlmm 75 0>;
status = "ok";
phy0: ethernet-phy@0 {
reg = <0>;
};
phy1: ethernet-phy@1 {
reg = <1>;
};
phy2: ethernet-phy@2 {
reg = <2>;
};
phy3: ethernet-phy@3 {
reg = <3>;
};
phy4: ethernet-phy@4 {
reg = <4>;
};
};
ess-switch@3a000000 {
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x1e>; /* lan port bitmap */
switch_wan_bmp = <0x20>; /* wan port bitmap */
switch_inner_bmp = <0xc0>; /*inner port bitmap*/
switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xff>; /* mac mode for uniphy instance1*/
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
qcom,port_phyinfo {
port@3 {
port_id = <3>;
phy_address = <4>;
};
port@4 {
port_id = <4>;
phy_address = <3>;
};
};
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <1>;
reg = <0x3a001000 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <0>;
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <2>;
reg = <0x3a001200 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <1>;
phy-mode = "sgmii";
};
dp3 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <3>;
reg = <0x3a001400 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <2>;
phy-mode = "sgmii";
};
dp4 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <4>;
reg = <0x3a001600 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <3>;
phy-mode = "sgmii";
};
dp5 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <5>;
reg = <0x3a001800 0x200>;
qcom,mactype = <0>;
local-mac-address = [000000000000];
qcom,link-poll = <1>;
qcom,phy-mdio-addr = <4>;
phy-mode = "sgmii";
};
leds {
compatible = "gpio-leds";
pinctrl-0 = <&leds_pins>;
pinctrl-names = "default";
led_power: led@32 {
label = "green:power";
gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
led@35 {
label = "green:wifi5";
gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
led@37 {
label = "green:wifi2";
gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
wps {
label = "reset";
linux,code = <KEY_RESTART>;
gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
};
&blsp1_uart3 {
pinctrl-0 = <&uart_pins>;
pinctrl-names = "default";
status = "ok";
};
&spi_0 {
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
compatible = "n25q128a11";
linux,modalias = "m25p80", "n25q128a11";
spi-max-frequency = <50000000>;
use-default-sizes;
};
};
&qpic_bam {
status = "ok";
};
&nand {
pinctrl-0 = <&qpic_pins>;
pinctrl-names = "default";
status = "ok";
};
&ssphy_0 {
status = "ok";
};
&qusb_phy_0 {
status = "ok";
};
&usb3 {
status = "ok";
};
&nss_crypto {
status = "ok";
};
/* TZAPP is enabled in default memory profile only */
#if !defined(__IPQ_MEM_PROFILE_256_MB__) && !defined(__IPQ_MEM_PROFILE_512_MB__)
&qseecom {
mem-start = <0x49B00000>;
mem-size = <0x600000>;
status = "ok";
};
#endif

View File

@@ -50,25 +50,78 @@
bootargs-append = " swiotlb=1 coherent_pool=2M";
#endif
};
gpio-export {
compatible = "gpio-export";
#size-cells = <0>;
mcu-enable {
gpio-export,name = "mcu-enable";
gpio-export,output = <0>;
gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
};
usb-hub-enable {
gpio-export,name = "usb-hub-enable";
gpio-export,output = <1>;
gpios = <&tlmm 55 GPIO_ACTIVE_HIGH>;
};
usb-rear-power {
gpio-export,name = "usb-rear-power";
gpio-export,output = <1>;
gpios = <&tlmm 29 GPIO_ACTIVE_HIGH>;
};
usb-side-power {
gpio-export,name = "usb-side-power";
gpio-export,output = <1>;
gpios = <&tlmm 30 GPIO_ACTIVE_HIGH>;
};
};
};
&tlmm {
pinctrl-0 = <&btcoex_pins>;
pinctrl-0 = <&mcu_rst &mcu_rsv &usb_rear_pwr &usb_side_pwr &usb_hub_rst>;
pinctrl-names = "default";
btcoex_pins: btcoex_pins {
mux_0 {
pins = "gpio64";
function = "pta1_1";
drive-strength = <6>;
bias-pull-down;
};
mux_1 {
pins = "gpio65";
function = "pta1_2";
drive-strength = <6>;
bias-pull-down;
};
mcu_rst: mcu_rst_pins {
pins = "gpio54";
function = "gpio";
drive-strength = <8>;
bias-disable;
output-low;
};
mcu_rsv: mcu_rsv_pins {
pins = "gpio56";
function = "gpio";
drive-strength = <8>;
bias-disable;
};
usb_rear_pwr: usb_rear_pwr_pins {
pins = "gpio29";
function = "gpio";
drive-strength = <8>;
bias-disable;
output-high;
};
usb_side_pwr: usb_side_pwr_pins {
pins = "gpio30";
function = "gpio";
drive-strength = <8>;
bias-disable;
output-high;
};
usb_hub_rst: usb_hub_rst_pins {
pins = "gpio55";
function = "gpio";
drive-strength = <8>;
bias-disable;
output-high;
};
mdio_pins: mdio_pinmux {
@@ -172,17 +225,7 @@
};
};
hsuart_pins: hsuart_pins {
mux {
pins = "gpio49";
function = "blsp2_uart";
drive-strength = <8>;
bias-disable;
};
};
button_pins: button_pins {
reset_button {
pins = "gpio66";
function = "gpio";
@@ -220,31 +263,6 @@
bias-pull-down;
};
};
usb_mux_sel_pins: usb_mux_pins {
mux {
pins = "gpio27";
function = "gpio";
drive-strength = <8>;
bias-pull-down;
};
};
pcie0_pins: pcie_pins {
pcie0_rst {
pins = "gpio58";
function = "pcie0_rst";
drive-strength = <8>;
bias-pull-down;
};
pcie0_wake {
pins = "gpio59";
function = "pcie0_wake";
drive-strength = <8>;
bias-pull-down;
};
};
};
&soc {
@@ -733,12 +751,6 @@
};
};
&serial_blsp2 {
pinctrl-0 = <&hsuart_pins>;
pinctrl-names = "default";
status = "ok";
};
&nss0 {
qcom,low-frequency = <187200000>;
qcom,mid-frequency = <748800000>;
@@ -812,7 +824,7 @@
};
&pcie0 {
status = "ok";
status = "disabled";
};
&pcie1 {

View File

@@ -55,6 +55,17 @@
#endif
};
gpio-export {
compatible = "gpio-export";
#size-cells = <0>;
mcu-enable {
gpio-export,name = "mcu-enable";
gpio-export,output = <0>;
gpios = <&tlmm 34 GPIO_ACTIVE_HIGH>;
};
};
reserved-memory {
/* No Pine attach in 256M profile */
#if !defined(__IPQ_MEM_PROFILE_256_MB__)
@@ -155,28 +166,15 @@
};
&tlmm {
pinctrl-0 = <&btcoex_pins>;
pinctrl-0 = <&mcu_rst>;
pinctrl-names = "default";
btcoex_pins: btcoex_pins {
mux_0 {
pins = "gpio64";
function = "pta1_1";
drive-strength = <6>;
bias-pull-down;
};
mux_1 {
pins = "gpio65";
function = "pta1_2";
drive-strength = <6>;
bias-pull-down;
};
mux_2 {
pins = "gpio66";
function = "pta1_0";
drive-strength = <6>;
bias-pull-down;
};
mcu_rst: mcu_rst_pins {
pins = "gpio34";
function = "gpio";
drive-strength = <8>;
bias-disable;
output-low;
};
mdio_pins: mdio_pinmux {
@@ -207,14 +205,15 @@
bias-disable;
};
};
i2c_5_pins: i2c_5_pinmux {
mux {
pins = "gpio0", "gpio2";
function = "blsp5_i2c";
drive-strength = <8>;
bias-disable;
};
};
mux {
pins = "gpio0", "gpio2";
function = "blsp5_i2c";
drive-strength = <8>;
bias-disable;
};
};
spi_0_pins: spi_0_pins {
mux {
@@ -225,33 +224,6 @@
};
};
spi_3_pins: spi_3_pins {
mux {
pins = "gpio50", "gpio52", "gpio53";
function = "blsp3_spi";
drive-strength = <8>;
bias-disable;
};
spi_cs {
pins = "gpio22";
function = "blsp3_spi2";
drive-strength = <8>;
bias-disable;
};
quartz_interrupt {
pins = "gpio47";
function = "gpio";
input;
bias-disable;
};
quartz_reset {
pins = "gpio21";
function = "gpio";
output-low;
bias-disable;
};
};
qpic_pins: qpic_pins {
data_0 {
pins = "gpio15";
@@ -312,7 +284,7 @@
hsuart_pins: hsuart_pins {
mux {
pins = "gpio46", "gpio47", "gpio48", "gpio49";
pins = "gpio48", "gpio49";
function = "blsp2_uart";
drive-strength = <8>;
bias-disable;
@@ -320,7 +292,6 @@
};
button_pins: button_pins {
wps_button {
pins = "gpio67";
function = "gpio";
@@ -366,24 +337,24 @@
bias-pull-down;
};
};
pwm_pins: pwm_pinmux {
mux_1 {
pins = "gpio25";
function = "pwm02";
drive-strength = <8>;
};
mux_2 {
pins = "gpio26";
function = "pwm12";
drive-strength = <8>;
};
mux_3 {
pins = "gpio27";
function = "pwm22";
drive-strength = <8>;
};
};
pwm_pins: pwm_pinmux {
mux_1 {
pins = "gpio25";
function = "pwm02";
drive-strength = <8>;
};
mux_2 {
pins = "gpio26";
function = "pwm12";
drive-strength = <8>;
};
mux_3 {
pins = "gpio27";
function = "pwm22";
drive-strength = <8>;
};
};
};
&soc {

View File

@@ -27,6 +27,15 @@ define Device/liteon_wpx8324
endef
TARGET_DEVICES += liteon_wpx8324
define Device/muxi_ap3220l
DEVICE_TITLE := MUXI AP3220L
DEVICE_DTS := qcom-ipq5018-muxi-ap3220l
SUPPORTED_DEVICES := muxi,ap3220l
DEVICE_PACKAGES := ath11k-wifi-muxi-ap3220l ath11k-firmware-ipq50xx-spruce ath11k-firmware-qcn6122
DEVICE_DTS_CONFIG := config@mp03.5-c1
endef
TARGET_DEVICES += muxi_ap3220l
define Device/motorola_q14
DEVICE_TITLE := Motorola Q14
DEVICE_DTS := qcom-ipq5018-q14

View File

@@ -2,6 +2,17 @@ KERNEL_LOADADDR := 0x41008000
DEVICE_VARS += CE_TYPE
define Device/cig_wf660a
DEVICE_TITLE := Cigtech WF-660a
DEVICE_DTS := qcom-ipq6018-cig-wf660a
SUPPORTED_DEVICES := cig,wf660a
DEVICE_DTS_CONFIG := config@cp01-c1
DEVICE_PACKAGES := ath11k-wifi-cig-wf660a uboot-env uboot-envtools
IMAGES := sysupgrade.tar mmc-factory.bin
IMAGE/mmc-factory.bin := append-ubi | qsdk-ipq-factory-mmc
endef
TARGET_DEVICES += cig_wf660a
define Device/cig_wf188n
DEVICE_TITLE := Cigtech WF-188n
DEVICE_DTS := qcom-ipq6018-cig-wf188n
@@ -20,6 +31,24 @@ define Device/hfcl_ion4xe
endef
TARGET_DEVICES += hfcl_ion4xe
define Device/hfcl_ion4x
DEVICE_TITLE := HFCL ION4X
DEVICE_DTS := qcom-ipq6018-hfcl-ion4x
DEVICE_DTS_CONFIG := config@cp01-c1
SUPPORTED_DEVICES := hfcl,ion4x
DEVICE_PACKAGES := ath11k-wifi-qcom-ipq6018 uboot-envtools
endef
TARGET_DEVICES += hfcl_ion4x
define Device/hfcl_ion4x_2
DEVICE_TITLE := HFCL ION4X_2
DEVICE_DTS := qcom-ipq6018-hfcl-ion4x_2
DEVICE_DTS_CONFIG := config@cp01-c1
SUPPORTED_DEVICES := hfcl,ion4x_2
DEVICE_PACKAGES := ath11k-wifi-qcom-ipq6018 uboot-envtools
endef
TARGET_DEVICES += hfcl_ion4x_2
define Device/hfcl_ion4xi
DEVICE_TITLE := HFCL ION4Xi
DEVICE_DTS := qcom-ipq6018-hfcl-ion4xi
@@ -167,3 +196,13 @@ define Device/meshpp_s618_cp01
DEVICE_PACKAGES := ath11k-wifi-meshpp-s618 -kmod-usb-dwc3-of-simple kmod-usb-dwc3-qcom kmod-usb3
endef
TARGET_DEVICES += meshpp_s618_cp01
define Device/yuncore_fap650
DEVICE_TITLE := YunCore FAP 650
DEVICE_DTS := qcom-ipq6018-yuncore-fap650
SUPPORTED_DEVICES := yuncore,fap650
DEVICE_DTS_CONFIG := config@cp03-c1
DEVICE_PACKAGES := ath11k-wifi-yuncore-fap650
endef
TARGET_DEVICES += yuncore_fap650

View File

@@ -36,24 +36,39 @@ define Device/cig_wf194c4
endef
TARGET_DEVICES += cig_wf194c4
define Device/cig_wf196
DEVICE_TITLE := CIG WF196
define Device/cig_wf196_us
DEVICE_TITLE := CIG WF196 (US)
DEVICE_DTS := qcom-ipq807x-wf196
DEVICE_DTS_CONFIG=config@hk14
SUPPORTED_DEVICES := cig,wf196
BLOCKSIZE := 256k
PAGESIZE := 4096
DEVICE_PACKAGES := ath11k-wifi-cig-wf196 aq-fw-download uboot-envtools kmod-usb3 kmod-usb2 \
ath11k-firmware-qcn9000 ath11k-wifi-cig-wf196_6g
DEVICE_PACKAGES := ath11k-wifi-cig-wf196-us aq-fw-download uboot-envtools kmod-usb3 kmod-usb2 \
ath11k-firmware-qcn9000 ath11k-wifi-cig-wf196_6g-us \
zephyr-v3.3.x-hci_uart-cig_wf196_nrf52833
endef
TARGET_DEVICES += cig_wf196
TARGET_DEVICES += cig_wf196_us
define Device/cig_wf196_ca
DEVICE_TITLE := CIG WF196 (CA)
DEVICE_DTS := qcom-ipq807x-wf196
DEVICE_DTS_CONFIG=config@hk14
SUPPORTED_DEVICES := cig,wf196
BLOCKSIZE := 256k
PAGESIZE := 4096
DEVICE_PACKAGES := ath11k-wifi-cig-wf196-ca aq-fw-download uboot-envtools kmod-usb3 kmod-usb2 \
ath11k-firmware-qcn9000 ath11k-wifi-cig-wf196_6g-ca \
zephyr-v3.3.x-hci_uart-cig_wf196_nrf52833
endef
TARGET_DEVICES += cig_wf196_ca
define Device/edgecore_eap102
DEVICE_TITLE := Edgecore EAP102
DEVICE_DTS := qcom-ipq807x-eap102
DEVICE_DTS_CONFIG=config@ac02
SUPPORTED_DEVICES := edgecore,eap102
DEVICE_PACKAGES := ath11k-wifi-edgecore-eap102 kmod-usb2 kmod-usb3 uboot-envtools
DEVICE_PACKAGES := ath11k-wifi-edgecore-eap102 kmod-usb2 kmod-usb3 uboot-envtools \
zephyr-v3.3.x-hci_usb-edgecore_eap102_nrf52840
endef
TARGET_DEVICES += edgecore_eap102

View File

@@ -0,0 +1,162 @@
From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 12 Aug 2014 20:49:27 +0200
Subject: [PATCH 30/36] GPIO: add named gpio exports
Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -23,6 +23,8 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>
#include <linux/gpio/machine.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
#include "gpiolib.h"
@@ -450,3 +452,72 @@ void of_gpiochip_remove(struct gpio_chip
gpiochip_remove_pin_ranges(chip);
of_node_put(chip->of_node);
}
+
+#ifdef CONFIG_GPIO_SYSFS
+
+static struct of_device_id gpio_export_ids[] = {
+ { .compatible = "gpio-export" },
+ { /* sentinel */ }
+};
+
+static int of_gpio_export_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *cnp;
+ u32 val;
+ int nb = 0;
+
+ for_each_child_of_node(np, cnp) {
+ const char *name = NULL;
+ int gpio;
+ bool dmc;
+ int max_gpio = 1;
+ int i;
+
+ of_property_read_string(cnp, "gpio-export,name", &name);
+
+ if (!name)
+ max_gpio = of_gpio_count(cnp);
+
+ for (i = 0; i < max_gpio; i++) {
+ unsigned flags = 0;
+ enum of_gpio_flags of_flags;
+
+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
+ if (!gpio_is_valid(gpio))
+ return gpio;
+
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
+ flags |= GPIOF_ACTIVE_LOW;
+
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ else
+ flags |= GPIOF_IN;
+
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
+ continue;
+
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
+ gpio_export_with_name(gpio, dmc, name);
+ nb++;
+ }
+ }
+
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
+
+ return 0;
+}
+
+static struct platform_driver gpio_export_driver = {
+ .driver = {
+ .name = "gpio-export",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_export_ids),
+ },
+ .probe = of_gpio_export_probe,
+};
+
+module_platform_driver(gpio_export_driver);
+
+#endif
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -122,6 +122,12 @@ static inline int gpio_export(unsigned g
return gpiod_export(gpio_to_desc(gpio), direction_may_change);
}
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
+{
+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
+}
+
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -427,6 +427,7 @@ static inline struct gpio_desc *devm_get
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc);
@@ -434,6 +435,13 @@ void gpiod_unexport(struct gpio_desc *de
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
+static inline int _gpiod_export(struct gpio_desc *desc,
+ bool direction_may_change,
+ const char *name)
+{
+ return -ENOSYS;
+}
+
static inline int gpiod_export(struct gpio_desc *desc,
bool direction_may_change)
{
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -544,7 +544,7 @@ static struct class gpio_class = {
*
* Returns zero on success, else an error.
*/
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
{
struct gpio_chip *chip;
struct gpiod_data *data;
@@ -604,6 +604,8 @@ int gpiod_export(struct gpio_desc *desc,
offset = gpio_chip_hwgpio(desc);
if (chip->names && chip->names[offset])
ioname = chip->names[offset];
+ if (name)
+ ioname = name;
dev = device_create_with_groups(&gpio_class, chip->dev,
MKDEV(0, 0), data, gpio_groups,
@@ -625,6 +627,12 @@ err_unlock:
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
return status;
}
+EXPORT_SYMBOL_GPL(__gpiod_export);
+
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
+{
+ return __gpiod_export(desc, direction_may_change, NULL);
+}
EXPORT_SYMBOL_GPL(gpiod_export);
static int match_export(struct device *dev, const void *desc)

View File

@@ -0,0 +1,131 @@
From 39385cb5f3274735b03ed1f8e7ff517b02a0beed Mon Sep 17 00:00:00 2001
From: Johan Hedberg <johan.hedberg@intel.com>
Date: Sat, 12 Nov 2016 17:03:07 +0200
Subject: [PATCH] Bluetooth: Fix using the correct source address type
The hci_get_route() API is used to look up local HCI devices, however
so far it has been incapable of dealing with anything else than the
public address of HCI devices. This completely breaks with LE-only HCI
devices that do not come with a public address, but use a static
random address instead.
This patch exteds the hci_get_route() API with a src_type parameter
that's used for comparing with the right address of each HCI device.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/hci_core.h | 2 +-
net/bluetooth/6lowpan.c | 4 ++--
net/bluetooth/hci_conn.c | 26 ++++++++++++++++++++++++--
net/bluetooth/l2cap_core.c | 2 +-
net/bluetooth/rfcomm/tty.c | 2 +-
net/bluetooth/sco.c | 2 +-
6 files changed, 30 insertions(+), 8 deletions(-)
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1003,7 +1003,7 @@ static inline void hci_set_drvdata(struc
}
struct hci_dev *hci_dev_get(int index);
-struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src);
+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, u8 src_type);
struct hci_dev *hci_alloc_dev(void);
void hci_free_dev(struct hci_dev *hdev);
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -1102,7 +1102,6 @@ static int get_l2cap_conn(char *buf, bda
{
struct hci_conn *hcon;
struct hci_dev *hdev;
- bdaddr_t *src = BDADDR_ANY;
int n;
n = sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %hhu",
@@ -1113,7 +1112,8 @@ static int get_l2cap_conn(char *buf, bda
if (n < 7)
return -EINVAL;
- hdev = hci_get_route(addr, src);
+ /* The LE_PUBLIC address type is ignored because of BDADDR_ANY */
+ hdev = hci_get_route(addr, BDADDR_ANY, BDADDR_LE_PUBLIC);
if (!hdev)
return -ENOENT;
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -609,7 +609,7 @@ int hci_conn_del(struct hci_conn *conn)
return 0;
}
-struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type)
{
int use_src = bacmp(src, BDADDR_ANY);
struct hci_dev *hdev = NULL, *d;
@@ -630,7 +630,29 @@ struct hci_dev *hci_get_route(bdaddr_t *
*/
if (use_src) {
- if (!bacmp(&d->bdaddr, src)) {
+ bdaddr_t id_addr;
+ u8 id_addr_type;
+
+ if (src_type == BDADDR_BREDR) {
+ if (!lmp_bredr_capable(d))
+ continue;
+ bacpy(&id_addr, &d->bdaddr);
+ id_addr_type = BDADDR_BREDR;
+ } else {
+ if (!lmp_le_capable(d))
+ continue;
+
+ hci_copy_identity_address(d, &id_addr,
+ &id_addr_type);
+
+ /* Convert from HCI to three-value type */
+ if (id_addr_type == ADDR_LE_DEV_PUBLIC)
+ id_addr_type = BDADDR_LE_PUBLIC;
+ else
+ id_addr_type = BDADDR_LE_RANDOM;
+ }
+
+ if (!bacmp(&id_addr, src) && id_addr_type == src_type) {
hdev = d; break;
}
} else {
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -7044,7 +7044,7 @@ int l2cap_chan_connect(struct l2cap_chan
BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", &chan->src, dst,
dst_type, __le16_to_cpu(psm));
- hdev = hci_get_route(dst, &chan->src);
+ hdev = hci_get_route(dst, &chan->src, chan->src_type);
if (!hdev)
return -EHOSTUNREACH;
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -178,7 +178,7 @@ static void rfcomm_reparent_device(struc
struct hci_dev *hdev;
struct hci_conn *conn;
- hdev = hci_get_route(&dev->dst, &dev->src);
+ hdev = hci_get_route(&dev->dst, &dev->src, BDADDR_BREDR);
if (!hdev)
return;
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -219,7 +219,7 @@ static int sco_connect(struct sock *sk)
BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
- hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src);
+ hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, BDADDR_BREDR);
if (!hdev)
return -EHOSTUNREACH;

View File

@@ -0,0 +1,37 @@
From 345bafc04fa2dea44dbdc8bda5633de256a74262 Mon Sep 17 00:00:00 2001
From: Yu Liu <yudiliu@google.com>
Date: Mon, 19 Apr 2021 16:53:30 -0700
Subject: [PATCH] Bluetooth: Fix the HCI to MGMT status conversion table
[ Upstream commit 4ef36a52b0e47c80bbfd69c0cce61c7ae9f541ed ]
0x2B, 0x31 and 0x33 are reserved for future use but were not present in
the HCI to MGMT conversion table, this caused the conversion to be
incorrect for the HCI status code greater than 0x2A.
Reviewed-by: Miao-chen Chou <mcchou@chromium.org>
Signed-off-by: Yu Liu <yudiliu@google.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/mgmt.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -212,12 +212,15 @@ static u8 mgmt_status_table[] = {
MGMT_STATUS_TIMEOUT, /* Instant Passed */
MGMT_STATUS_NOT_SUPPORTED, /* Pairing Not Supported */
MGMT_STATUS_FAILED, /* Transaction Collision */
+ MGMT_STATUS_FAILED, /* Reserved for future use */
MGMT_STATUS_INVALID_PARAMS, /* Unacceptable Parameter */
MGMT_STATUS_REJECTED, /* QoS Rejected */
MGMT_STATUS_NOT_SUPPORTED, /* Classification Not Supported */
MGMT_STATUS_REJECTED, /* Insufficient Security */
MGMT_STATUS_INVALID_PARAMS, /* Parameter Out Of Range */
+ MGMT_STATUS_FAILED, /* Reserved for future use */
MGMT_STATUS_BUSY, /* Role Switch Pending */
+ MGMT_STATUS_FAILED, /* Reserved for future use */
MGMT_STATUS_FAILED, /* Slot Violation */
MGMT_STATUS_FAILED, /* Role Switch Failed */
MGMT_STATUS_INVALID_PARAMS, /* EIR Too Large */

View File

@@ -0,0 +1,52 @@
From 433c3febcb837cf8f2758660c6a89e1d734c55dc Mon Sep 17 00:00:00 2001
From: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
Date: Wed, 28 Jul 2021 15:51:04 +0800
Subject: [PATCH] Bluetooth: skip invalid hci_sync_conn_complete_evt
[ Upstream commit 92fe24a7db751b80925214ede43f8d2be792ea7b ]
Syzbot reported a corrupted list in kobject_add_internal [1]. This
happens when multiple HCI_EV_SYNC_CONN_COMPLETE event packets with
status 0 are sent for the same HCI connection. This causes us to
register the device more than once which corrupts the kset list.
As this is forbidden behavior, we add a check for whether we're
trying to process the same HCI_EV_SYNC_CONN_COMPLETE event multiple
times for one connection. If that's the case, the event is invalid, so
we report an error that the device is misbehaving, and ignore the
packet.
Link: https://syzkaller.appspot.com/bug?extid=66264bf2fd0476be7e6c [1]
Reported-by: syzbot+66264bf2fd0476be7e6c@syzkaller.appspotmail.com
Tested-by: syzbot+66264bf2fd0476be7e6c@syzkaller.appspotmail.com
Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_event.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3748,6 +3748,21 @@ static void hci_sync_conn_complete_evt(s
switch (ev->status) {
case 0x00:
+ /* The synchronous connection complete event should only be
+ * sent once per new connection. Receiving a successful
+ * complete event when the connection status is already
+ * BT_CONNECTED means that the device is misbehaving and sent
+ * multiple complete event packets for the same new connection.
+ *
+ * Registering the device more than once can corrupt kernel
+ * memory, hence upon detecting this invalid event, we report
+ * an error and ignore the packet.
+ */
+ if (conn->state == BT_CONNECTED) {
+ bt_dev_err(hdev, "Ignoring connect complete event for existing connection");
+ goto unlock;
+ }
+
conn->handle = __le16_to_cpu(ev->handle);
conn->state = BT_CONNECTED;
conn->type = ev->link_type;

View File

@@ -0,0 +1,33 @@
From 69f728dac41d13fc3e8d4514684e476ebd0d61f5 Mon Sep 17 00:00:00 2001
From: Wei Yongjun <weiyongjun1@huawei.com>
Date: Wed, 13 Oct 2021 16:55:46 +0800
Subject: [PATCH] Bluetooth: Fix debugfs entry leak in hci_register_dev()
[ Upstream commit 5a4bb6a8e981d3d0d492aa38412ee80b21033177 ]
Fault injection test report debugfs entry leak as follows:
debugfs: Directory 'hci0' with parent 'bluetooth' already present!
When register_pm_notifier() failed in hci_register_dev(), the debugfs
create by debugfs_create_dir() do not removed in the error handing path.
Add the remove debugfs code to fix it.
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_core.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3420,6 +3420,7 @@ int hci_register_dev(struct hci_dev *hde
return id;
err_wqueue:
+ debugfs_remove_recursive(hdev->debugfs);
destroy_workqueue(hdev->workqueue);
destroy_workqueue(hdev->req_workqueue);
err:

View File

@@ -0,0 +1,97 @@
Index: qca-ssdk/src/init/ssdk_init.c
===================================================================
--- qca-ssdk.orig/src/init/ssdk_init.c
+++ qca-ssdk/src/init/ssdk_init.c
@@ -137,6 +137,10 @@
#include "ssdk_scomphy.h"
#endif
+#include <linux/debugfs.h>
+#include "fal/fal_fdb.h"
+#include "ref/ref_vsi.h"
+
#ifdef IN_RFS
struct rfs_device rfs_dev;
struct notifier_block ssdk_inet_notifier;
@@ -2005,10 +2009,81 @@ void ssdk_ess_reset(void)
char ssdk_driver_name[] = "ess_ssdk";
+static ssize_t ssdk_flush_mac_write(struct file *f, const char *buffer,
+ size_t len, loff_t *offset)
+{
+ fal_fdb_entry_t entry;
+ char data[18];
+ ssize_t ret;
+ char mac[6];
+
+ ret = simple_write_to_buffer(data, sizeof(data), offset, buffer, len);
+
+ if (ret < 0)
+ return ret;
+ data[17] = 0;
+
+ if (sscanf(data, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
+ &mac[0], &mac[1], &mac[2], &mac[3],
+ &mac[4], &mac[5]) != 6) {
+ printk("failed to parse mac\n");
+ return -1;
+ }
+
+ {
+ fal_fdb_op_t fdb_op;
+ fal_fdb_entry_t fdb_entry;
+ sw_error_t ret;
+
+ memset(&fdb_op, 0, sizeof(fdb_op));
+ memset(&fdb_entry, 0, sizeof(fdb_entry));
+
+ ret = fal_fdb_entry_extend_getfirst(0, &fdb_op, &fdb_entry);
+ while (ret == SW_OK) {
+ /*printk("%s:%s[%d]%d %2x:%2x:%2x:%2x:%2x:%2x | %2x:%2x:%2x:%2x:%2x:%2x\n", __FILE__, __func__, __LINE__,
+ fdb_entry.fid, fdb_entry.addr.uc[0], fdb_entry.addr.uc[1], fdb_entry.addr.uc[2], fdb_entry.addr.uc[3], fdb_entry.addr.uc[4], fdb_entry.addr.uc[5],
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);*/
+ if (!memcmp(mac, &fdb_entry.addr, 6)) {
+ memset(&entry, 0, sizeof(entry));
+ memcpy(&entry.addr, mac, ETH_ALEN);
+ entry.fid = fdb_entry.fid;
+
+ if (SW_OK != fal_fdb_entry_del_bymac(0, &entry))
+ printk("failed to delete FDB entry\n");
+ else
+ printk("deleted %s/%d\n", data, entry.fid);
+ }
+
+ ret = fal_fdb_entry_extend_getnext(0, &fdb_op, &fdb_entry);
+ }
+
+ }
+ return len;
+}
+
+const struct file_operations ssdk_flush_mac_fops = {
+ .owner = THIS_MODULE,
+ .write = ssdk_flush_mac_write,
+};
+
+static int debugfs_fdb_init(void)
+{
+ void *ret;
+
+ ret = debugfs_create_file("ssdk_flush_mac", 0644, NULL, NULL,
+ &ssdk_flush_mac_fops);
+ if (!ret)
+ pr_warn("Failed to create ssdk_flush_mac in debugfs");
+
+ return 0;
+}
+
static int ssdk_probe(struct platform_device *pdev)
{
struct device_node *np;
+ debugfs_fdb_init();
+
np = of_node_get(pdev->dev.of_node);
if (of_device_is_compatible(np, "qcom,ess-instance"))
return of_platform_populate(np, NULL, NULL, &pdev->dev);

View File

@@ -0,0 +1,157 @@
#
# Copyright (C) 2023 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=mcu-firmware
PKG_VERSION:=2023-03-12
PKG_RELEASE:=1
PKG_MAINTAINER:=Piotr Dymacz <pepe2k@gmail.com>
include $(INCLUDE_DIR)/package.mk
define Package/mcu-fw-default
CATEGORY:=Firmware
SUBMENU:=MCU firmware
SECTION:=firmware
TITLE:=MCU firmware
endef
# Zephyr versions
# 4 fields separated with underscore:
# version-name_git-sha_pipeline-id_sha256-of-package
ZEPHYR_VERSIONS := \
zephyr-v3.3.x_7055d10e538e_3877473859_321a0daf6328698a913c6504d19aa85a5170dfce6039b86d31d2e9162d34af7c \
zephyr-main_cf50a3c570bb_3912606668_10922f34cdde9e16cbee76a13a14fb935b9d1fe13eb9136cba31de27033a9c3e
ZEPHYR_FW_CI_URL := https://gitlab.com/pepe2k/zephyr/-/jobs/
ZEPHYR_FW_TYPES := \
hello_world \
hci_uart \
hci_usb
# Zephyr 'hello_world' targets
ZEPHYR_HELLO_WORLD_TARGETS := \
cig_wf196_nrf52833 \
edgecore_eap102_nrf52840 \
nrf52840dongle_nrf52840
# Zephyr 'hci_uart' targets
ZEPHYR_HCI_UART_TARGETS:= \
cig_wf196_nrf52833 \
edgecore_eap102_nrf52840 \
nrf52840dongle_nrf52840
# Zephyr 'hci_usb' targets
ZEPHYR_HCI_USB_TARGETS := \
edgecore_eap102_nrf52840 \
nrf52840dongle_nrf52840
word-underscore = $(word $2,$(subst _, ,$1))
define Download/zephyr-fw
URL:=$(ZEPHYR_FW_CI_URL)$(call word-underscore,$(2),3)/
URL_FILE:=artifacts/download?file_type=archive
FILE:=$(call word-underscore,$(2),1)-$(call word-underscore,$(2),2).zip
HASH:=$(call word-underscore,$(2),4)
endef
$(foreach FW,$(ZEPHYR_VERSIONS),$(eval $(call Download,zephyr-fw,$(FW))))
# $(1) firmware name (e.g. hci_usb)
define zephyr-fw-host-support
define Package/zephyr-$(1)-host-support
$(call Package/mcu-fw-default)
DEPENDS:=+mcu
TITLE:=Zephyr '$(1)' common host side support
HIDDEN:=1
endef
define Package/zephyr-$(1)-host-support/install
$(CP) ./files/$(1)/* $$(1)/
endef
endef
# $(1) version (e.g zephyr-v3.3.x)
# $(2) firmware name (e.g. hci_usb)
# $(3) target/board name (e.g. nrf52840dongle_nrf52840)
define zephyr-fw
define Package/$(1)-$(2)-$(3)
$(call Package/mcu-fw-default)
DEPENDS:=+mcu $(call zephyr-fw-deps,$(2))
TITLE:=Zephyr '$(2)'
endef
define Package/$(1)-$(2)-$(3)/description
Zephyr '$(1)' based firmware '$(2)' for '$(3)' board
endef
define Package/$(1)-$(2)-$(3)/install
$(INSTALL_DIR) $$(1)/lib/firmware/mcu/$(3)/$(1)__$(2)
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(1)/$(3)/$(1)__$(2)/*.bin \
$$(1)/lib/firmware/mcu/$(3)/$(1)__$(2)/
endef
endef
define zephyr-fw-deps
$(if $(wildcard ./files/$(1)/*),+zephyr-$(1)-host-support) \
$(if $(findstring hci_u,$1),+bluez-daemon +kmod-bluetooth +kmod-crypto-user)
endef
define zephyr-fw-unzip
mkdir -p $(PKG_BUILD_DIR)/$(call word-underscore,$(1),1); \
unzip -q -d $(PKG_BUILD_DIR)/$(call word-underscore,$(1),1) \
$(DL_DIR)/$(call word-underscore,$(1),1)-$(call word-underscore,$(1),2).zip; \
for fw in $(PKG_BUILD_DIR)/$(call word-underscore,$(1),1)/*.tar.gz; do \
$(TAR) -C $(PKG_BUILD_DIR)/$(call word-underscore,$(1),1) --one-top-level -xzf $$$$fw; \
rm -rf $$$$fw; \
done;
endef
define Build/Prepare
$(foreach FW,$(ZEPHYR_VERSIONS),$(call zephyr-fw-unzip,$(FW)))
endef
define Build/Compile
endef
# Generate host side support packages (per firmware type)
$(foreach FW,$(ZEPHYR_FW_TYPES),\
$(if $(wildcard ./files/$(FW)/*),$(eval $(call zephyr-fw-host-support,$(FW)))))
$(foreach FW,$(ZEPHYR_FW_TYPES),\
$(if $(wildcard ./files/$(FW)/*),$(eval $(call BuildPackage,zephyr-$(FW)-host-support))))
# Generate dedicated Zephyr firmware packages (per firmware version, type and board)
$(foreach VER,$(ZEPHYR_VERSIONS),\
$(foreach TARGET,$(ZEPHYR_HELLO_WORLD_TARGETS),\
$(eval $(call zephyr-fw,$(call word-underscore,$(VER),1),hello_world,$(TARGET)))))
$(foreach VER,$(ZEPHYR_VERSIONS),\
$(foreach TARGET,$(ZEPHYR_HCI_UART_TARGETS),\
$(eval $(call zephyr-fw,$(call word-underscore,$(VER),1),hci_uart,$(TARGET)))))
$(foreach VER,$(ZEPHYR_VERSIONS),\
$(foreach TARGET,$(ZEPHYR_HCI_USB_TARGETS),\
$(eval $(call zephyr-fw,$(call word-underscore,$(VER),1),hci_usb,$(TARGET)))))
$(foreach VER,$(ZEPHYR_VERSIONS),\
$(foreach TARGET,$(ZEPHYR_HELLO_WORLD_TARGETS),\
$(eval $(call BuildPackage,$(call word-underscore,$(VER),1)-hello_world-$(TARGET)))))
$(foreach VER,$(ZEPHYR_VERSIONS),\
$(foreach TARGET,$(ZEPHYR_HCI_UART_TARGETS),\
$(eval $(call BuildPackage,$(call word-underscore,$(VER),1)-hci_uart-$(TARGET)))))
$(foreach VER,$(ZEPHYR_VERSIONS),\
$(foreach TARGET,$(ZEPHYR_HCI_USB_TARGETS),\
$(eval $(call BuildPackage,$(call word-underscore,$(VER),1)-hci_usb-$(TARGET)))))

View File

@@ -0,0 +1,79 @@
#!/bin/sh
. /lib/functions.sh
. /lib/functions/mcu.sh
attach_hci_controller() {
local section="$1"
local sn
local pid
local interface
local uart_path
local uart_baud
local uart_flow
[ -n "$section" ] || return 1
command -v btattach > /dev/null 2>&1 || return 1
config_load mcu
config_get sn "$section" sn
config_get interface "$section" interface
config_get uart_path "$section" uart_path
config_get uart_baud "$section" uart_baud "115200"
config_get uart_flow "$section" uart_flow "0"
[ -n "$sn" ] || return 1
if [ "$interface" = "usb" ]; then
uart_baud="1000000"
uart_flow="1"
dev_found=""
usb_path="/sys/bus/usb/devices/*"
for dev_path in $usb_path; do
dev="$(basename "$dev_path")"
[[ $dev == *":"* ]] && continue
[ "$sn" = "$(cat "${dev_path}/serial" 2>/dev/null)" ] && {
dev_found="$dev"
break
}
done
[ -n "$dev_found" ] || return 1
usb_path="/sys/bus/usb/devices/${dev_found}*/tty/*"
for tty_path in $usb_path; do
tty="$(basename "$tty_path")"
[ -c "/dev/${tty}" ] && {
uart_path="/dev/${tty}"
break
}
done
fi
[ -c "$uart_path" ] || return 1
# Give MCU some time for BLE controller setup
sleep 1
if [ "$uart_flow" = "1" ]; then
btattach -B "$uart_path" -S "$uart_baud" > /dev/null 2>&1 &
else
btattach -B "$uart_path" -S "$uart_baud" -N > /dev/null 2>&1 &
fi
pid="$!"
kill -0 "$pid" > /dev/null 2>&1 && {
echo "$pid" > "/var/run/mcu.${sn}.pid"
return 0
}
return 1
}
attach_hci_controller "$1" || exit 1
exit 0

50
feeds/mcu/mcu/Makefile Normal file
View File

@@ -0,0 +1,50 @@
#
# Copyright (C) 2023 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=mcu
PKG_VERSION:=2023-03-22
PKG_RELEASE=1
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=
PKG_MAINTAINER:=Piotr Dymacz <pepe2k@gmail.com>
include $(INCLUDE_DIR)/package.mk
define Package/mcu
TITLE:=Generic OpenWrt/OpenWiFi MCU config and management handler
CATEGORY:=Utilities
DEPENDS:=+umcumgr +libubox
SECTION:=utils
endef
define Package/mcu/conffiles
/etc/config/mcu
endef
define Build/Compile
endef
define Package/mcu/install
$(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/hotplug.d/usb $(1)/lib/functions $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/mcu.init $(1)/etc/init.d/mcu
$(INSTALL_DATA) ./files/mcu.hotplug $(1)/etc/hotplug.d/usb/30-mcu
$(INSTALL_DATA) ./files/mcu.sh $(1)/lib/functions
$(if $(wildcard ./files/uci-defaults/$(BOARD)_$(SUBTARGET)), \
$(INSTALL_DATA) ./files/uci-defaults/$(BOARD)_$(SUBTARGET) \
$(1)/etc/uci-defaults/20-mcu, \
$(if $(wildcard ./files/uci-defaults/$(BOARD)), \
$(INSTALL_DATA) ./files/uci-defaults/$(BOARD) \
$(1)/etc/uci-defaults/20-mcu \
) \
)
endef
$(eval $(call BuildPackage,mcu))

View File

@@ -0,0 +1,32 @@
config mcu 'uart_no_hw_flow'
option interface 'uart'
option bootloader 'mcuboot'
option enable_pin 'mcu-enable'
option uart_path '/dev/ttyMSM1'
option uart_baud '115200'
option firmware 'zephyr-main__hello_world'
option disabled '1'
config mcu 'uart_with_hw_flow'
option interface 'uart'
option bootloader 'mcuboot'
option enable_pin 'mcu-enable'
option uart_path '/dev/ttyMSM1'
option uart_baud '1000000'
option uart_flow '1'
option firmware 'zephyr-main__hello_world'
option disabled '1'
config mcu 'usb_with_enable_pin'
option interface 'usb'
option bootloader 'mcuboot'
option enable_pin 'mcu-enable'
option firmware 'zephyr-main__hello_world'
option disabled '1'
config mcu 'usb_no_enable_pin'
option interface 'usb'
option bootloader 'mcuboot'
option sn 'ABCDEF1234567890'
option firmware 'zephyr-main__hello_world'
option disabled '1'

View File

@@ -0,0 +1,142 @@
#!/bin/sh
. /lib/functions.sh
. /lib/functions/mcu.sh
MCU_SCRIPT_NAME="mcu-hotplug"
MCU_CFG_FOUND="0"
mcu_hotplug_setup() {
local sn
local fw_type
local disabled
local sn_dev="$2"
local uart="$3"
SECT="$1"
MCU_SYSINFO_OUTPUT=""
MCU_IMGLIST_OUTPUT=""
[ "$MCU_CFG_FOUND" = "1" ] && return 0
config_get sn "$SECT" sn
[ "$sn" != "$sn_dev" ] && return 0
MCU_SCRIPT_NAME="mcu-hotplug.${SECT}"
MCU_CFG_FOUND="1"
mcu_logi "found matching config section '$SECT'"
# Section disabled?
config_get_bool disabled "$SECT" disabled "0"
[ "$disabled" = "1" ] && {
mcu_logw "section is disabled in config"
return 0
}
# Stop related service
[ -f "/var/run/mcu.${sn}.pid" ] && {
kill "$(cat "/var/run/mcu.${sn}.pid" 2>/dev/null)" \
> /dev/null 2>&1
rm -f "/var/run/mcu.${sn}.pid" > /dev/null 2>&1
}
mcu_sn_check_and_update "$sn" "$uart"
[ $? -ne 0 ] && return 1
mcu_fw_check_and_update "$uart"
rc="$?"
[ "$rc" = "1" ] && return 1
[ "$rc" = "0" ] && {
fw_type="$(uci -q get "mcu.${SECT}.firmware" | awk -F '__' '{print $2}')"
[ -n "$fw_type" ] || return 0
[ -x "${MCU_HS_DIR}/${fw_type}.sh" ] && \
"${MCU_HS_DIR}/${fw_type}.sh" "$SECT"
}
return 0
}
# We are looking for ttyACM with specific product name and USB VID:PID
[ "$ACTION" = "add" -a \
"$DRIVER" = "cdc_acm" -a \
"$DEVTYPE" = "usb_interface" ] && {
usb_path="/sys/bus/usb/devices/"
dev="$(echo "$DEVICENAME" | cut -d ':' -f 1)"
[ -n "$dev" ] || return 1
p="$(cat "${usb_path}/${dev}/product" 2>/dev/null)"
id="$(cat "${usb_path}/${dev}/idVendor" 2>/dev/null)"
id="${id}$(cat "${usb_path}//${dev}/idProduct" 2>/dev/null)"
sn="$(cat "${usb_path}/${dev}/serial" 2>/dev/null)"
[ "$p" = "$MCUBOOT_USB_PRODUCT" -a \
"$id" = "$MCUBOOT_USB_VID_PID" ] || return 0
mcu_logi "found compatible MCU with S/N '$sn' at USB bus '$dev'"
# We expect just a single ttyACM interface
usb_path="/sys/bus/usb/devices/${dev}*/tty/*"
for tty in $usb_path; do
[ -c "/dev/$(basename "$tty")" ] && {
uart_path="/dev/$(basename "$tty")"
break
}
done
[ -n "$uart_path" ] || {
mcu_loge "failed to find ttyACM interface"
return 1
}
# Try to acquire lock (init script might be handling this device)
exec 9>"$MCU_FLOCK_FILE" || return 1
flock -n 9 || {
mcu_logd "lock taken by init script, skipping"
return 1
}
config_load mcu
config_foreach mcu_hotplug_setup mcu "$sn" "$uart_path"
# Add new config section for this MCU if no matching found (by S/N)
[ "$MCU_CFG_FOUND" = "0" ] && {
MCU_SCRIPT_NAME="mcu-hotplug"
sect="${sn:0:8}_usb"
mcu_logi "no matching MCU config found, adding new (disabled): '$sect'"
[ -d /etc/config-shadow ] && {
uci -c /etc/config-shadow -q batch <<-EOF
set mcu.${sect}=mcu
set mcu.${sect}.interface=usb
set mcu.${sect}.bootloader=mcuboot
set mcu.${sect}.sn=$sn
set mcu.${sect}.disabled=1
EOF
uci -c /etc/config-shadow -q commit mcu
}
uci -q batch <<-EOF
set mcu.${sect}=mcu
set mcu.${sect}.interface=usb
set mcu.${sect}.bootloader=mcuboot
set mcu.${sect}.sn=$sn
set mcu.${sect}.disabled=1
EOF
uci -q commit mcu
flock -u 9
return 0
}
flock -u 9
}

View File

@@ -0,0 +1,309 @@
#!/bin/sh /etc/rc.common
START=80
. /lib/functions/mcu.sh
SECT=
mcu_setup_uart() {
local uart="$1"
local baud="$2"
local flow="$3"
local gpio_path="$4"
local gpio_on="$5"
local sn="$6"
local fw_type
# Take out MCU out of reset and read basic info
mcu_enable_pin_set "$gpio_path" "$gpio_on"
sleep 1
mcu_sn_check_and_update "$sn" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
mcu_fw_check_and_update "$uart" "$baud" "$flow"
rc="$?"
[ "$rc" = "1" ] && return 1
[ "$rc" = "2" ] && {
sleep 1
mcu_req "boot" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
}
fw_type="$(uci -q get "mcu.${SECT}.firmware" | awk -F '__' '{print $2}')"
[ -n "$fw_type" ] || return 0
[ -x "${MCU_HS_DIR}/${fw_type}.sh" ] && \
"${MCU_HS_DIR}/${fw_type}.sh" "$SECT"
}
mcu_setup_usb() {
local gpio_path="$1"
local gpio_on="$2"
local sn="$3"
local gpio_off="0"
local uart
local fw_type
[ "$gpio_on" = "0" ] && gpio_off="1"
# If we have S/N in config, only take out the MCU from reset
[ -n "$sn" ] && {
mcu_logi "MCU S/N already set, hotplug will perform config"
mcu_enable_pin_set "$gpio_path" "$gpio_on"
return 0
}
# If S/N is missing, we need to take out MCU from reset, find out
# its S/N and save it for later
exec 9>"$MCU_FLOCK_FILE" || {
mcu_loge "failed to obtain lock (exec fail)!"
return 1
}
flock -n 9 || {
mcu_loge "failed to obtain lock (flock fail)!"
return 1
}
usb_path="/sys/bus/usb/devices/*"
devs_old=""
for dev_path in $usb_path; do
dev="$(basename "$dev_path")"
[[ $dev == *":"* ]] && continue
p="$(cat "${dev_path}/product" 2>/dev/null)"
id="$(cat "${dev_path}/idVendor" 2>/dev/null)"
id="${id}$(cat "${dev_path}/idProduct" 2>/dev/null)"
[ "$p" = "$MCUBOOT_USB_PRODUCT" -a \
"$id" = "$MCUBOOT_USB_VID_PID" ] && \
devs_old="$devs_old $dev"
done
mcu_enable_pin_set "$gpio_path" "$gpio_on"
sleep 2
dev_found=""
for dev_path in $usb_path; do
dev="$(basename "$dev_path")"
[[ $dev == *":"* ]] && continue
p="$(cat "${dev_path}/product" 2>/dev/null)"
id="$(cat "${dev_path}/idVendor" 2>/dev/null)"
id="${id}$(cat "${dev_path}/idProduct" 2>/dev/null)"
[ "$p" = "$MCUBOOT_USB_PRODUCT" -a \
"$id" = "$MCUBOOT_USB_VID_PID" ] && {
[ -n "$devs_old" ] && {
if echo "$devs_old" | grep -q "$dev"; then
continue
fi
}
dev_found="$dev"
break
}
done
[ -n "$dev_found" ] || {
mcu_loge "failed to find MCU on USB bus"
mcu_enable_pin_set "$gpio_path" "$gpio_off"
flock -u 9
return 1
}
mcu_logd "MCU found on USB bus: '$dev_found'"
# We expect just a single ttyACM interface
usb_path="/sys/bus/usb/devices/${dev_found}*/tty/*"
for tty_path in $usb_path; do
tty="$(basename "$tty_path")"
[ -c "/dev/${tty}" ] && {
uart="/dev/${tty}"
break
}
done
[ -n "$uart" ] || {
mcu_loge "failed to find ttyACM interface"
mcu_enable_pin_set "$gpio_path" "$gpio_off"
flock -u 9
return 1
}
mcu_sn_check_and_update "$sn" "$uart"
[ $? -ne 0 ] && {
mcu_enable_pin_set "$gpio_path" "$gpio_off"
flock -u 9
return 1
}
mcu_fw_check_and_update "$uart"
rc="$?"
[ "$rc" = "1" ] && {
mcu_enable_pin_set "$gpio_path" "$gpio_off"
flock -u 9
return 1
}
[ "$rc" = "0" ] && {
fw_type="$(uci -q get "mcu.${SECT}.firmware" | awk -F '__' '{print $2}')"
[ -n "$fw_type" -a -x "${MCU_HS_DIR}/${fw_type}.sh" ] && \
"${MCU_HS_DIR}/${fw_type}.sh" "$SECT"
}
flock -u 9
}
mcu_setup() {
local sn
local action
local fw_type
local disabled
local uart_baud
local uart_flow
local uart_path
local interface
local bootloader
local enable_pin
local gpio_path
local gpio_on="1"
local gpio_off="0"
SECT="$1"
MCU_SCRIPT_NAME="mcu-init.${SECT}"
action="$2"
MCU_SYSINFO_OUTPUT=""
MCU_IMGLIST_OUTPUT=""
# Section disabled?
[ "$action" = "start" ] && {
config_get_bool disabled "$SECT" disabled "0"
[ "$disabled" = "1" ] && {
mcu_logw "section is disabled in config"
return 0
}
}
config_get sn "$SECT" sn
config_get bootloader "$SECT" bootloader
config_get enable_pin "$SECT" enable_pin
config_get interface "$SECT" interface
config_get uart_path "$SECT" uart_path
config_get uart_baud "$SECT" uart_baud "115200"
config_get_bool uart_flow "$SECT" uart_flow "0"
# Stop related service
[ "$action" = "stop" ] && {
[ -n "$sn" -a -f "/var/run/mcu.${sn}.pid" ] && {
kill "$(cat "/var/run/mcu.${sn}.pid" 2>/dev/null)" \
> /dev/null 2>&1
rm -f "/var/run/mcu.${sn}.pid" > /dev/null 2>&1
}
}
# As for now, only 'mcuboot' bootloader is supported
case "$bootloader" in
"mcuboot")
command -v umcumgr > /dev/null 2>&1 || {
mcu_loge "missing 'umcumgr' tool"
return 1
}
;;
*)
mcu_loge "unsupported or unset 'bootloader' option"
return 1
;;
esac
# Verify 'enable_pin' option
if [ -z "$enable_pin" ]; then
# USB based MCU without GPIO based way for reset are fully
# handled by the hotplug script
[ "$interface" = "usb" ] && {
mcu_logw "'enable_pin' option is unset, ignoring"
return 0
}
[ "$interface" = "uart" ] && {
mcu_loge "'enable_pin' option is unset"
return 1
}
else
gpio_path="/sys/class/gpio/${enable_pin}"
[ -d "$gpio_path" ] || {
mcu_loge "invalid 'enable_pin' option"
return 1
}
[ "$(cat "${gpio_path}/active_low")" = "1" ] && {
gpio_on="0"
gpio_off="1"
}
# TODO: should we maybe bail out here if the MCU was took out
# of reset already before, by something/someone else?
[ "$(cat "${gpio_path}/value")" = "$gpio_on" ] && {
if [ "$action" = "start" ]; then
mcu_logw "MCU already enabled, resetting"
else
mcu_logi "disabling MCU"
fi
mcu_enable_pin_set "$gpio_path" "$gpio_off"
sleep 1
}
fi
[ "$action" = "stop" ] && return 0
# For now only 'usb' and 'uart' interfaces are supported
case "$interface" in
"uart")
[ -z "$uart_path" -o ! -c "$uart_path" ] && {
mcu_loge "invalid or unset 'uart_path' option"
return 1
}
mcu_setup_uart "$uart_path" "$uart_baud" "$uart_flow" \
"$gpio_path" "$gpio_on" "$sn"
;;
"usb")
mcu_setup_usb "$gpio_path" "$gpio_on" "$sn"
;;
*)
mcu_loge "unsupported or unset 'interface' option"
return 1
;;
esac
}
start() {
config_load mcu
config_foreach mcu_setup mcu "start"
return 0
}
stop() {
config_load mcu
config_foreach mcu_setup mcu "stop"
return 0
}

501
feeds/mcu/mcu/files/mcu.sh Normal file
View File

@@ -0,0 +1,501 @@
#!/bin/sh
. /usr/share/libubox/jshn.sh
# Product name and VID:PID used by OpenWrt/OpenWiFi MCUboot fork
MCUBOOT_USB_PRODUCT="MCUboot serial recovery"
MCUBOOT_USB_VID_PID="16c005e1"
# Host support and firmware directories
MCU_HS_DIR="/etc/mcu.d"
MCU_FW_DIR="/lib/firmware/mcu"
MCU_FLOCK_FILE="/tmp/lock/mcu"
MCU_SYSINFO_OUTPUT=
MCU_IMGLIST_OUTPUT=
MCU_SCRIPT_NAME=""
# logger helpers
mcu_log() {
if [ -n "$MCU_SCRIPT_NAME" ]; then
logger -p "$1" -t "${MCU_SCRIPT_NAME}[$$]" "$2"
else
logger -p "$1" "$2"
fi
}
mcu_loge() {
mcu_log "err" "$1"
}
mcu_logd() {
mcu_log "debug" "$1"
}
mcu_logi() {
mcu_log "info" "$1"
}
mcu_logn() {
mcu_log "notice" "$1"
}
mcu_logw() {
mcu_log "warn" "$1"
}
mcu_fetch_fwlist() {
local uart="$1"
local baud="$2"
local flow="$3"
if [ "$flow" = "1" ]; then
flow=" -f"
else
flow=""
fi
[ -n "$baud" ] || baud="115200"
[ -n "$MCU_IMGLIST_OUTPUT" ] && return 0
MCU_IMGLIST_OUTPUT="$(umcumgr -s -d "$uart" -b "$baud$flow" list)"
[ $? -eq 0 ] || {
mcu_loge "request 'list' failed (uart='$uart', baud='$baud', flow='$flow')"
return 1
}
}
mcu_fetch_sysinfo() {
local uart="$1"
local baud="$2"
local flow="$3"
if [ "$flow" = "1" ]; then
flow=" -f"
else
flow=""
fi
[ -n "$baud" ] || baud="115200"
[ -n "$MCU_SYSINFO_OUTPUT" ] && return 0
MCU_SYSINFO_OUTPUT="$(umcumgr -s -d "$uart" -b "$baud$flow" sysinfo)"
[ $? -eq 0 ] || {
mcu_loge "request 'sysinfo' failed (uart='$uart', baud='$baud', flow='$flow')"
return 1
}
}
mcu_get() {
local param="$1"
local slot="$2"
local value
local metadata
local sysinfo_field
case "$param" in
"board"|\
"soft_ver"|\
"serial_num"|\
"active_slot")
sysinfo_field="$param"
;;
"slots_num")
sysinfo_field="single_slot"
;;
"fwname")
[ -n "$slot" ] || return 1
param="image list: slot${slot} fw_name"
metadata="$(echo "$MCU_IMGLIST_OUTPUT" | grep "slot${slot}_metadata=" | cut -d '=' -f 2)"
[ -n "$metadata" ] && {
json_load "$metadata"
json_get_var value fw_name
}
;;
"fwsha")
[ -n "$slot" ] || return 1
param="image list: slot${slot}_hash"
value="$(echo "$MCU_IMGLIST_OUTPUT" | grep "slot${slot}_hash=" | cut -d '=' -f 2)"
;;
*)
return 1
;;
esac
[ -n "$sysinfo_field" ] && {
value="$(echo "$MCU_SYSINFO_OUTPUT" | grep "${sysinfo_field}=" | cut -d '=' -f 2)"
[ "$sysinfo_field" = "single_slot" ] && {
[ -n "$value" ] || value="1"
[ "$value" != "1" ] && value="2"
}
param="sysinfo: $param"
}
[ -n "$value" ] && mcu_logd "$param: '$value'"
echo "$value"
}
mcu_req() {
local cmd="$1"
local uart="$2"
local baud="$3"
local flow="$4"
case "$cmd" in
"boot"|\
"reset")
;;
*)
return 1
;;
esac
if [ "$flow" = "1" ]; then
flow=" -f"
else
flow=""
fi
[ -n "$baud" ] || baud="115200"
umcumgr -s -d "$uart" -b "$baud$flow" "$cmd" || {
mcu_loge "request '$cmd' failed (uart='$uart', baud='$baud', flow='$flow')"
return 1
}
mcu_logi "MCU requested '$cmd'"
}
mcu_sel_slot() {
local slot="$1"
local uart="$2"
local baud="$3"
local flow="$4"
if [ "$flow" = "1" ]; then
flow=" -f"
else
flow=""
fi
[ -n "$baud" ] || baud="115200"
# Request firmware active slot change
umcumgr -s -d "$uart" -b "$baud$flow" select "$slot" || {
mcu_loge "request 'select slot' failed (uart='$uart', baud='$baud', flow='$flow')"
return 1
}
mcu_logi "active firmware slot changed to: '$slot'"
}
mcu_fwfile_sha() {
local path="$1"
local value
[ -f "$path" ] || return 1
value="$(umcumgr -s hash "$path" | grep "hash=" | cut -d '=' -f 2)"
[ -n "$value" ] || return 1
echo "$value"
}
mcu_fw_upload() {
local board="$1"
local slot="$2"
local fw_name="$3"
local uart="$4"
local baud="$5"
local flow="$6"
local fw_path
if [ "$flow" = "1" ]; then
flow=" -f"
else
flow=""
fi
[ -n "$baud" ] || baud="115200"
fw_path="${MCU_FW_DIR}/${board}/${fw_name}/slot${slot}.bin"
umcumgr -q info "$fw_path" > /dev/null 2>&1 || {
mcu_loge "invalid or missing firmware file: '$fw_path'"
return 1
}
mcu_logi "uploading '$fw_name' to slot: '$slot'..."
# Upload fw to selected slot (TODO: slots numbering Zephyr vs. MCUboot)
[ "$slot" = "1" ] && slot="2"
umcumgr -q -n "$slot" -d "$uart" -b "$baud$flow" upload "$fw_path" || {
mcu_loge "request 'upload' failed (uart='$uart', baud='$baud', flow='$flow')"
return 1
}
mcu_logi "firmware uploaded!"
}
mcu_enable_pin_set() {
local gpio="$1"
local gpio_value="$2"
mcu_logd "setting MCU enable_pin '$(basename "$gpio")' to '$gpio_value'"
echo "$gpio_value" > "${gpio}/value" 2>/dev/null
}
mcu_sn_check_and_update() {
local sn="$1"
local uart="$2"
local baud="$3"
local flow="$4"
local sn_dev
# Fetch sysinfo
mcu_fetch_sysinfo "$uart" "$baud" "$flow" || return 1
sn_dev="$(mcu_get "serial_num")"
[ -n "$sn_dev" ] || return 1
[ -n "$sn_dev" ] && {
if [ -z "$sn" ]; then
[ -d /etc/config-shadow ] && {
uci -c /etc/config-shadow -q set mcu.${SECT}.sn="$sn_dev"
uci -c /etc/config-shadow -q commit mcu
}
uci -q set mcu.${SECT}.sn="$sn_dev"
uci -q commit mcu
else
[ "$sn" != "$sn_dev" ] && {
mcu_loge "MCU S/N mismatch ('$sn_dev' != '$sn')!"
return 1
}
fi
}
return 0
}
# Returns:
# 0 if MCU was requested to boot firmware
# 1 on error
# 2 if MCU was requested to reset
mcu_fw_check_and_update() {
local uart="$1"
local baud="$2"
local flow="$3"
local active_slot
local fw_slots
local slot0_fw
local slot0_sha
local slot1_fw
local slot1_sha
local firmware
local fw0_sha
local fw1_sha
local board
local soft_ver
config_get firmware "$SECT" firmware
[ -n "$firmware" ] || mcu_logw "option 'firmware' unset"
# Fetch sysinfo and firmware images list
mcu_fetch_sysinfo "$uart" "$baud" "$flow" || return 1
mcu_fetch_fwlist "$uart" "$baud" "$flow" || return 1
# MCU board name and software version
board="$(mcu_get "board")"
[ $? -eq 0 ] || return 1
soft_ver="$(mcu_get "soft_ver")"
[ $? -eq 0 ] || return 1
# Number of firmware slots and active slot
fw_slots="$(mcu_get "slots_num")"
[ $? -eq 0 ] || return 1
[ -n "$fw_slots" ] || fw_slots="1"
[ "$fw_slots" = "2" ] && {
active_slot="$(mcu_get "active_slot")"
[ $? -eq 0 ] || return 1
}
[ -n "$active_slot" ] || active_slot="0"
# Firmware available?
[ -n "$firmware" ] && {
if [ "$fw_slots" = "2" ]; then
[ -f "${MCU_FW_DIR}/${board}/${firmware}/slot0.bin" -a \
-f "${MCU_FW_DIR}/${board}/${firmware}/slot1.bin" ] || {
mcu_loge "firmware '$firmware' doesn't exist"
return 1
}
fw1_sha="$(mcu_fwfile_sha "${MCU_FW_DIR}/${board}/${firmware}/slot1.bin")"
else
[ -f "${MCU_FW_DIR}/${board}/${firmware}/slot0.bin" ] || {
mcu_loge "firmware '$firmware' doesn't exist"
return 1
}
fi
fw0_sha="$(mcu_fwfile_sha "${MCU_FW_DIR}/${board}/${firmware}/slot0.bin")"
}
slot0_fw="$(mcu_get "fwname" "0")"
[ $? -eq 0 ] || return 1
[ -n "$slot0_fw" ] && {
slot0_sha="$(mcu_get "fwsha" "0")"
[ $? -eq 0 ] || return 1
}
[ "$fw_slots" = "2" ] && {
slot1_fw="$(mcu_get "fwname" "1")"
[ $? -eq 0 ] || return 1
[ -n "$slot1_fw" ] && {
slot1_sha="$(mcu_get "fwsha" "1")"
[ $? -eq 0 ] || return 1
}
}
# No target firmware provided, check what's on device and update config
[ -n "$firmware" ] || {
firmware="$slot0_fw"
[ "$active_slot" = "1" ] && firmware="$slot1_fw"
[ -n "$firmware" ] && {
[ -d /etc/config-shadow ] && {
uci -c /etc/config-shadow -q set mcu.${SECT}.firmware="$firmware"
uci -c /etc/config-shadow -q commit mcu
}
uci -q set mcu.${SECT}.firmware="$firmware"
uci -q commit mcu
mcu_req "boot" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
return 0
}
return 1
}
# Do we have target firmware installed in the first slot?
[ "$firmware" = "$slot0_fw" -a "$slot0_sha" = "$fw0_sha" ] && {
mcu_logi "found matching firmware installed in slot '0'"
if [ "$fw_slots" = "2" -a "$active_slot" != "0" ]; then
mcu_sel_slot "0" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
# Changing active slots requires MCU reset at the moment
mcu_req "reset" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
return 2
else
mcu_req "boot" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
fi
return 0
}
mcu_logi "no matching firmware found in slot '0'"
# Upload firmware and reset on single-slot device
[ "$fw_slots" = "1" ] && {
mcu_fw_upload "$board" "0" "$firmware" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
mcu_req "reset" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
return 2
}
# Do we have target firmware installed in the second slot?
[ "$firmware" = "$slot1_fw" -a "$slot1_sha" = "$fw1_sha" ] && {
mcu_logi "found matching firmware installed in slot '1'"
if [ "$active_slot" != "1" ]; then
mcu_sel_slot "1" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
# Changing active slots requires MCU reset at the moment
mcu_req "reset" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
return 2
else
mcu_req "boot" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
fi
return 0
}
mcu_logi "no matching firmware found in slot '1'"
# Upload and boot firmware on multi-slot device
# Always use inactive slot
if [ "$active_slot" = "0" ]; then
active_slot="1"
else
active_slot="0"
fi
mcu_fw_upload "$board" "$active_slot" "$firmware" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
mcu_sel_slot "$active_slot" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
# Changing active slots requires MCU reset at the moment
mcu_req "reset" "$uart" "$baud" "$flow"
[ $? -ne 0 ] && return 1
return 2
}
mcu_add_uci_config() {
local name="$1"
local interface="$2"
local bootloader="$3"
local firmware="$4"
local enable_pin="$5"
local uart_path="$6"
local uart_baud="$7"
local uart_flow="$8"
uci -q set mcu.${name}="mcu"
uci -q set mcu.${name}.interface="$interface"
uci -q set mcu.${name}.bootloader="$bootloader"
uci -q set mcu.${name}.firmware="$firmware"
[ -n "$enable_pin" ] && uci -q set mcu.${name}.enable_pin="$enable_pin"
[ -n "$uart_path" ] && uci -q set mcu.${name}.uart_path="$uart_path"
[ -n "$uart_baud" ] && uci -q set mcu.${name}.uart_baud="$uart_baud"
[ "$uart_flow" = "1" ] && uci -q set mcu.${name}.uart_flow="1"
uci -q set mcu.${name}.disabled="0"
uci -q commit mcu
}

View File

@@ -0,0 +1,23 @@
[ -e /etc/config/mcu ] && exit 0
touch /etc/config/mcu
. /lib/functions.sh
. /lib/functions/mcu.sh
board=$(board_name)
case "$board" in
cig,wf196)
mcu_add_uci_config "nrf52833_uart" "uart" "mcuboot" \
"zephyr-v3.3.x__hci_uart" \
"mcu-enable" "/dev/ttyMSM1" "115200"
;;
edgecore,eap102)
mcu_add_uci_config "nrf52840_usb" "usb" "mcuboot" \
"zephyr-v3.3.x__hci_usb" \
"mcu-enable"
;;
esac
exit 0

View File

@@ -0,0 +1,43 @@
#
# Copyright (C) 2023 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=umcumgr
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://gitlab.com/pepe2k/umcumgr
PKG_SOURCE_DATE:=2023-03-06
PKG_SOURCE_VERSION:=966606a2868b8e6b0a2c7e129dc45a30e0d9ef87
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=
PKG_MAINTAINER:=Piotr Dymacz <pepe2k@gmail.com>
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
CMAKE_INSTALL:=1
define Package/umcumgr
SECTION:=utils
CATEGORY:=Utilities
DEPENDS:=+libubox
TITLE:=User space tool for MCUmgr SMP based management
endef
define Package/umcumgr/description
Simple user space tool for MCU management over MCUmgr SMP
(Simple Management Protocol) protocol
endef
define Package/umcumgr/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/umcumgr $(1)/usr/bin/
endef
$(eval $(call BuildPackage,umcumgr))

View File

@@ -1,40 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libJudy
PKG_VERSION:=1.0.5
PKG_RELEASE:=1
PKG_FIXUP=autoreconf
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
define Package/libJudy
SECTION:=base
CATEGORY:=Libraries
DEFAULT:=y
TITLE:=General purpose dynamic array
URL:=http://judy.sourceforge.net/
endef
MAKE_FLAGS += \
HOSTCC="$(HOSTCC)" \
HOSTCCFLAGS=""
#define Build/Configure
# $(call Build/Configure/Default,--prefix=/usr)
#endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(CP) $(PKG_INSTALL_DIR)/usr/include/Judy.h $(1)/usr/include/
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libJudy.{a,so*} $(1)/usr/lib/
endef
define Package/libJudy/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libJudy.so.* $(1)/usr/lib/
endef
$(eval $(call BuildPackage,libJudy))

View File

@@ -1,8 +0,0 @@
Doug Baskinks
Owner and Main Author
Contributors:
Troy Heber:
Repackaging
Project Administration

View File

@@ -1,516 +0,0 @@
Judy - C library functions for creating and accessing dynamic arrays
Copyright (C) 2004 Doug Baskins
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@@ -1,60 +0,0 @@
1.0.5 Version (May 2007) by (twh)
o added proper clean targets to enable multiple builds
o added examples directory
o Correctly Detects 32/64-bit build environment
o Allow explicit configure for 32/64-bit environment
1.0.4 Version (May 2007) by (twh)
o fixed the Checkit problem "error Judy1PrevEmpty Rcode != 1 = 0"
o Fixed memory allignment in JudyMallocIF.c (doug)
o Fixed messages from "make check" (doug).
1.0.3 Version (Feb 2006 ) by (twh)
o fixed make files to break out each copy element
to be a unique target, this also seems to have
resolved the issue where running make check rebuilds
the entire library again.
1.0.2 Version (Jan 2006 ) by (twh)
o fixed assumption of signed char in test programs.
o updated sh_build
o fixed generation of man pages from html
o fixed 32-bit and 64-bit configure
1.0.1 Version (Dec 2004) by (twh)
o fixed bootstrap to use later versions
o fixed manpage naming from (3X) to (3)
o Code changes to support Microsoft __inline directive
o Move away from using symlinks to using copies
o Added build.bat to support building on Windows
1.0.0 Version (Sept 2004) by (twh)
o Complete Autoconfisication of Judy
o Removed previous build environment
o Change INSTALL_IT back to INSTALL
o Moving to 1.0.0 to denote API change.
0.1.6 Version (1June2004) by (dlb)
o See src/sh_build in case of 'make' failures
o The is an endian-neutral version I.E. (jp_DcdPop0 deleted)
o Should not require any special platform specific compile flags
o Includes JudyHS*() -- very fast, scalable string version
o JudyHS*() is still preliminary and may need additional functionality.
o See test/manual/StringCompare.c for comparing different 'string' ADT's
o Deleted files: JudyMalloc.h, JudySL.h, JudySearch*
o All malloc() and free() is done thru interface routines in JudyMalloc.c
o Judy.h should work on all platforms that conform to ISO standards.
o After trying on many platforms, <stdint.h> was changed to <inttypes.h>
o jbgraph has some 'bash/ksh' isms that need to be removed.
o See test/manual/testjbgraph for plotting performance graphs
o 'libtools' stuff is in unknown shape.
o Does not "mangle" the root pointer (so old valgrind is not confused)
o Conform to standard "C"
o Change INSTALL to INSTALL_IT because it confused "make install"
o To he man pages need work to clean up the .html to be portable
o Plus hundreds of changes to make the source more portable.

View File

@@ -1,20 +0,0 @@
=== QUICK INSTALLATION OF JUDY LIBRARY AND MANUAL ENTRIES ===
1. ./configure #NOTE: you must do configure with either
--enable-32-bit or --enable-64-bit
depending on your system. Also note if you
are doing a non-native compile you are
responsiable for setting the appropriate
CFLAGS. See README for more information.
2. make
3. make check
4. make install # NOTE: must be SUPERUSER for make install
# This installs /opt/Judy/* and symlinks to
# files there from /usr/include/, /usr/lib/,
# /usr/share/man/, and /usr/share/doc/Judy/.
(Installation done! The rest is optional but recommended.)
5) man Judy # nroff -man version, or...
6) file:/opt/Judy/usr/share/doc/Judy/Judy_3x.htm # from LOCAL Web browser.

View File

@@ -1,19 +0,0 @@
# Tell automake we don't want to comply with every last clause in the
# GNU Maintainer's Manual.
AUTOMAKE_OPTIONS = foreign
# We need to build the following subdirectories in this order. Note that
# we put a Makefile.am in every subdirectory, even if there's nothing to
# compile, so that we can support 'make dist' gracefully.
#
# Dependencies: src <- tool (for libJudy), tool <- doc (for jhton), src <-
# test (for libJudy).
#SUBDIRS = src tool doc test make_includes
#SUBDIRS = src/JudyCommon src/JudyL src/Judy1 src/JudySL src/JudyHS src/obj
SUBDIRS = src
# These files will be included in our tarballs, even though automake knows
# nothing else about them.
#EXTRA_DIST = Makefile.multi original_configure .cvsignore
DISTCLEANFILES = config.log config.status Makefile libtool make.out

View File

@@ -1,149 +0,0 @@
Judy - C library creating and accessing dynamic arrays
==============================================================
Content
---------
1. Introduction
2. Directory Contents
3. How to install
4. License
5. Change History
6. Reporting Bugs
7. Known Issues
1. INTRODUCTION
-----------------
This tree contains sources, documents, tests, and tools for the Judy package.
This file is in a form that can be validated using the tool/readme script.
NOTE: The README files here describe some files that are not included in
every Judy source package.
WHAT IS JUDY? (see below for list of top-level directories and files)
Judy is a C library that implements a dynamic array. Empty Judy arrays are
declared with null pointers. A Judy array consumes memory only when
populated yet can grow to take advantage of all available memory. Judy's key
benefits are: scalability, performance, memory efficiency, and ease of use.
Judy arrays are designed to grow without tuning into the peta-element range,
scaling near O(log-base-256) -- 1 more RAM access at 256 X population.
Judy arrays are accessed with insert, retrieve, and delete calls for number
or string indexes. Configuration and tuning are not required -- in fact not
possible. Judy offers sorting, counting, and neighbor/empty searching.
Indexes can be sequential, clustered, periodic, or random -- it doesn't
matter to the algorithm. Judy arrays can be arranged hierarchically to
handle any bit patterns -- large indexes, sets of keys, etc.
Judy is often an improvement over common data structures such as: arrays,
sparse arrays, hash tables, B-trees, binary trees, linear lists, skiplists,
other sort and search algorithms, and counting functions.
2. JUDY TOP DIRECTORY CONTENTS:
--------------------------------
AUTHORS Judy authors and contributors
README This file.
INSTALL Summary instructions to build, check and install Judy.
COPYING Judy deliverable license notice (the LGPL).
ChangeLog List of changes per version of Judy.
configure Autoconf configure script to allow a portable build e
environment.
src/ Header and source files used to build the package.
doc/ Documents, both external (to the package) and internal.
test/ Test support and some timing programs.
tool/ Primitive tool (jhton) to convert *.html files to "man" pages.
and build tables used by Judy to malloc() sizes of memory.
3. HOW TO INSTALL
-----------------
For a quick description see the INSTALL file.
Judy is now based on the GNU Auto tools. This means that you can do the standard
configure, make, make check and make install and everything should work, with
one minor difference and a little caveat.
Judy is capable of being built as a 32-bit or a 64-bit library. Configure
will test to detect the native environment and default to that. Therefor if you
explicitly want to to compile for the non-native environment you need to tell
Judy what you want. You can run ./configure with one of the following flags:
--enable-32-bit
--enable-64-bit
The caveat comes in on machines that support both at 32-bit and 64-bit runtime
environments such as RISC platforms and x86-64. In this case your compiler will
either use 32-bit or 64-bit as default. If you plan to use the default you can
follow the above instructions and be finished.
However, if you wish to compile for the non-default target type. YOU ARE
RESPONSIBLE FOR SETTING THE CORRECT FLAGS! Such as CFLAGS to make your compiler
switch modes LDFLAGS to make your linker behave, etc.
For example: On HP-UX PA-RISC the compiler generates 32-bit code by default. If
I wish to stick with the defaults I can simply build Judy by:
./configure
make
make check
make install
If I want to build Judy as a 64-bit library on HP-UX PA-RISC I have to do:
CFLAGS=+DD64 ./configure --enable-64-bit
make
make check
make install
If I want to build Judy native (64-bit) on Linux AMD64 I have to do:
./configure
make
make check
make install
If I want to build Judy 32-bit on Linux AMD64 I have to do:
./configure --enable-32-bit
make
make check
make install
4. LICENSE
----------
The user library is licensed under the GNU Lesser Public License (LGPL)
Version 2.1, February 1999. The full text of the LGPL is located at:
COPYING
5. CHAGE HISTORY
----------------
See the ChangeLog file.
6. REPORTING BUGS
-----------------
If you encounter a bug, please submit it to the project bug list,
located on the project page:
https://sourceforge.net/projects/judy/
7. KNOWN ISSUES
---------------
When compiling on HP-UX, you may get a message like:
error 1000: Unexpected symbol:
This is a problem with the HP's compiler in that it doesn't like a typedef'ed
type following a static inline.
You can work around it by running this command from the Judy directory.
find ./ -name \*.[ch] | xargs perl -i.BAK -pe 's/static inline/static/g'

View File

@@ -1,14 +0,0 @@
#! /bin/sh
set -x
libtoolize --force --copy
#aclocal-1.9
aclocal
#autoheader2.50
autoheader
#add --include-deps if you want to bootstrap with any other compiler than gcc
#automake --add-missing --copy --include-deps
automake-1.9 --add-missing --force --copy
#autoconf2.50
autoconf
rm -f config.cache

View File

@@ -1,265 +0,0 @@
AC_PREREQ(2.57)
AC_INIT(Judy, 1.0.5, dougbaskins@yahoo.com)
AM_MAINTAINER_MODE
dnl Turn on automake, and pass it the PACKAGE_NAME and PACKAGE_VERSION, too.
AM_INIT_AUTOMAKE($PACKAGE_NAME, $PACKAGE_VERSION)
dnl Tell autoconf we want to keep our preprocessor defines in a header named
dnl config.h. This keeps automake from passing a zillion -D directives to
dnl the C compiler.
AM_CONFIG_HEADER([config.h])
dnl==========================================================================
dnl WARNING - WARNING - Shared Library Versioning - WARNING - WARNING
dnl==========================================================================
dnl This is the most dangerous part of this file--making a mistake here can
dnl cause massively painful chaos for libJudy developers, and potentially
dnl even end users. So PLEASE pay attention, and read up on the theory of
dnl shared library versioning. Tens of thousands of Linux users (and several
dnl QA departments) may thank you someday.
dnl
dnl There are two major concerns:
dnl
dnl 1) When changing the libJudy ABI (application binary interface),
dnl VERSION_INFO *must* be updated according to libtool's rules. Failure
dnl to do this will make applications using libJudy dump core, typically
dnl under obscure conditions on user systems. I won't attempt to
dnl explain these rules here; please see 'info libtool' for details.
dnl
dnl 2) When changing the libJudy ABI, it is also desirable to make libJudy
dnl "parallel installable". This means that it should be possible to
dnl install development headers and libraries for more than one version
dnl of libJudy at once. Failure to do this may cause problems for
dnl Linux distributions which include libJudy. (For example, it's
dnl impossible to switch between libpng2-dev and libpng3-dev on a
dnl Debian system without uninstalling and reinstalling both the Gnome
dnl and KDE SDKs.) For more information, do a Google search for
dnl "parallel installable".
dnl
dnl Right now, this package only provides the mechanisms to handle concern
dnl (1). Concern (2) is slightly more complicated, and will require some
dnl careful thinking. Fortunately, concern (2) doesn't become important
dnl until other SDKs rely on the libJudy SDK.
dnl
dnl Of course, it's safe to avoid changing the libJudy ABI. :-)
dnl
dnl The version scheme used by Libtool tracks interfaces, where an interface is
dnl the set of exported entry points into the library. All Libtool libraries
dnl start with -version-info set to 0:0:0 - this will be the default version
dnl number if you don't explicitly set it on the Libtool link command line. The
dnl meaning of these numbers (from left to right) is as follows:
dnl
dnl current:
dnl The number of the current interface exported by the library. A current
dnl value of 0, means that you are calling the interface exported by this
dnl library interface 0.
dnl
dnl revision:
dnl The implementation number of the most recent interface exported by this
dnl library. In this case, a revision value of 0 means that this is the
dnl first implementation of the interface.
dnl
dnl If the next release of this library exports the same interface, but has
dnl different implementation (perhaps some bugs have been fixed), the
dnl revision number will be higher, but current number will be the same. In
dnl that case, when given a choice, the library with the highest revision
dnl will always be used by the runtime loader.
dnl
dnl age:
dnl The number of previous additional interfaces supported by this library.
dnl If age were 2, then this library can be linked into executables which
dnl were built with a release of this library that exported the current
dnl interface number, current, or any of the previous two interfaces.
dnl
dnl By definition age must be less than or equal to current. At the outset, only
dnl the first ever interface is implemented, so age can only be 0.
dnl
VERSION_INFO="-version-info 1:3:0"
AC_SUBST(VERSION_INFO)
dnl==========================================================================
dnl Flavors
dnl==========================================================================
dnl Judy can be compiled in one of three flavors: "product" (the default),
dnl "debug", or "cov". We allow the user to select flavors using
dnl --enable-debug and --enable-ccover arguments to automake, which is
dnl the typical way of doing things.
dnl
dnl Note how we perform string comparison:
dnl
dnl if test "x$enable_debug" = xyes; then
dnl
dnl We do several odd things here:
dnl
dnl 1) We use 'test' instead of '[ ]' for shell portability.
dnl 2) We prefix strings with 'x' when comparing them, to protect against
dnl empty strings.
dnl 3) We ALWAYS quote user-supplied shell variables, to protect against
dnl embedded spaces.
dnl
dnl The results of this test aren't used anywhere yet.
dnl Keep the user entertained.
AC_MSG_CHECKING(which flavor to build)
dnl Process our --enable-debug argument.
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug],
[enable debugging features]),
, enable_debug=no)
if test "x$enable_debug" != xyes -a "x$enable_debug" != xno; then
AC_MSG_ERROR(You may not pass an argument to --enable-debug)
fi
dnl Process our --enable-ccover argument.
AC_ARG_ENABLE(ccover,
AC_HELP_STRING([--enable-ccover],
[enable use of ccover code coverage tools]),
, enable_ccover=no)
if test "x$enable_ccover" != xyes -a "x$enable_ccover" != xno; then
AC_MSG_ERROR(You may not pass an argument to --enable-ccover)
fi
dnl Determine our flavor.
if test "x$enable_debug" = xyes -a "x$enable_ccover" = xyes; then
AC_MSG_ERROR(You may not use --enable-debug and --enable-ccover together)
elif test "x$enable_debug" = xyes; then
FLAVOR=debug
elif test "x$enable_ccover" = xyes; then
FLAVOR=cov
else
FLAVOR=product
fi
dnl Define FLAVOR in our makefiles.
AC_SUBST(FLAVOR)
dnl Tell the user what flavor we've decided to build.
AC_MSG_RESULT($FLAVOR)
dnl==========================================================================
dnl Checks for Programs
dnl==========================================================================
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
dnl==========================================================================
dnl Checks for Header Files
dnl==========================================================================
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h malloc.h stddef.h stdint.h stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h])
dnl==========================================================================
dnl Checks for Typedefs, Structures, and Compiler Characteristics
dnl==========================================================================
dnl Standard, boring stuff.
AC_HEADER_STDBOOL
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
AC_C_VOLATILE
AC_CHECK_TYPES([ptrdiff_t])
dnl If we're compiling for a little-endian system, define JU_LITTLE_ENDIAN.
dnl If we can't tell what kind of system we're compling for, alert the
dnl user as described in 'info autoconf'.
AC_C_BIGENDIAN(, AC_DEFINE(JU_LITTLE_ENDIAN, 1,
[Define to 1 on little-endian systems.]))
b32="no"
b64="no"
AC_ARG_ENABLE(32-bit, [ --enable-32-bit Generate code for a 32-bit environment],
b32="$enableval", b32="no")
if test "x$b32" != xno; then
AC_MSG_RESULT(Configured to Build 32-bit)
if test "x$GCC" = xyes; then
CFLAGS="$CFLAGS -UJU_64BIT -m32"
else
CFLAGS="-UJU_64BIT"
fi
fi
AC_ARG_ENABLE(64-bit, [ --enable-64-bit Generate code for a 64-bit environment],
b64="$enableval", b64="no")
if test "x$b64" != xno; then
AC_MSG_RESULT(Configured to Building 64-bit)
if test "x$GCC" = xyes; then
CFLAGS="$CFLAGS -DJU_64BIT -m64"
else
CFLAGS="-DJU_64BIT"
fi
fi
if test "x$b64" = xno -a "x$b32" = xno; then
dnl Figure out if we are 32-bit or 64-bit (LP64)
AC_CHECK_SIZEOF(void *)
if test "$ac_cv_sizeof_void_p" = 8; then
AC_MSG_RESULT(Detected 64-bit Build Environment)
CFLAGS="$CFLAGS -DJU_64BIT"
else
AC_MSG_RESULT(Detected 32-bit Build Environment)
CFLAGS="$CFLAGS -UJU_64BIT"
fi
fi
dnl==========================================================================
dnl Checks for Libraries
dnl==========================================================================
AC_FUNC_ERROR_AT_LINE
AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_FUNC_MMAP
AC_FUNC_STAT
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([getpagesize gettimeofday memset munmap pow strchr strcspn strerror strstr strtoul uname])
dnl These must be called before AM_PROG_LIBTOOL, because it may want
dnl to call AC_CHECK_PROG.
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(LD, ld)
AC_CHECK_TOOL(RANLIB, ranlib, :)
dnl Checks for libtool - this must be done after we set cflags (abi issues)
dnl
AM_PROG_LIBTOOL
WARN_CFLAGS=""
build_warnings="-W -Wall -Wstrict-prototypes -Wmissing-prototypes"
AC_ARG_ENABLE([build-warnings],
[ --enable-build-warnings Enable build-time compiler warnings for gcc])
if test x"$build_warnings" = xyes; then
if test x"$GCC" = xyes; then
WARN_CFLAGS="${build_warnings}"
fi
fi
AC_SUBST(WARN_CFLAGS)
AC_CONFIG_FILES([Makefile
src/Judy1/Makefile
src/JudyCommon/Makefile
src/JudyHS/Makefile
src/JudyL/Makefile
src/JudySL/Makefile
src/Makefile
src/obj/Makefile
tool/Makefile
doc/Makefile
test/Makefile])
AC_OUTPUT

View File

@@ -1,209 +0,0 @@
man3_MANS = man/man3/Judy \
man/man3/Judy1 \
man/man3/Judy1_funcs \
man/man3/JudyL \
man/man3/JudyL_funcs \
man/man3/JudySL \
man/man3/JudySL_funcs \
man/man3/JudyHS \
man/man3/JudyHS_funcs \
man/man3/J1T \
man/man3/J1S \
man/man3/J1U \
man/man3/J1F \
man/man3/J1N \
man/man3/J1L \
man/man3/J1P \
man/man3/J1FE \
man/man3/J1NE \
man/man3/J1LE \
man/man3/J1PE \
man/man3/J1C \
man/man3/J1BC \
man/man3/J1FA \
man/man3/J1MU \
man/man3/Judy1Test \
man/man3/Judy1Set \
man/man3/Judy1Unset \
man/man3/Judy1First \
man/man3/Judy1Next \
man/man3/Judy1Last \
man/man3/Judy1Prev \
man/man3/Judy1FirstEmpty \
man/man3/Judy1NextEmpty \
man/man3/Judy1LastEmpty \
man/man3/Judy1PrevEmpty \
man/man3/Judy1Count \
man/man3/Judy1ByCount \
man/man3/Judy1FreeArray \
man/man3/Judy1MemUsed \
man/man3/JudyL \
man/man3/JLG \
man/man3/JLI \
man/man3/JLD \
man/man3/JLF \
man/man3/JLN \
man/man3/JLL \
man/man3/JLP \
man/man3/JLFE \
man/man3/JLNE \
man/man3/JLLE \
man/man3/JLPE \
man/man3/JLC \
man/man3/JLBC \
man/man3/JLFA \
man/man3/JLMU \
man/man3/JudyLGet \
man/man3/JudyLIns \
man/man3/JudyLDel \
man/man3/JudyLFirst \
man/man3/JudyLNext \
man/man3/JudyLLast \
man/man3/JudyLPrev \
man/man3/JudyLFirstEmpty \
man/man3/JudyLNextEmpty \
man/man3/JudyLLastEmpty \
man/man3/JudyLPrevEmpty \
man/man3/JudyLCount \
man/man3/JudyLByCount \
man/man3/JudyLFreeArray \
man/man3/JudyLMemUsed \
man/man3/JSLG \
man/man3/JSLI \
man/man3/JSLD \
man/man3/JSLF \
man/man3/JSLN \
man/man3/JSLL \
man/man3/JSLP \
man/man3/JSLFA \
man/man3/JudySLGet \
man/man3/JudySLIns \
man/man3/JudySLDel \
man/man3/JudySLFirst \
man/man3/JudySLNext \
man/man3/JudySLLast \
man/man3/JudySLPrev \
man/man3/JudySLFreeArray \
man/man3/JHSG \
man/man3/JHSI \
man/man3/JHSD \
man/man3/JHSFA \
man/man3/JudyHSGet \
man/man3/JudyHSIns \
man/man3/JudyHSDel \
man/man3/JudyHSFreeArray
man/man3/Judy:
../tool/jhton ext/Judy_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/Judy
man/man3/Judy1:
../tool/jhton ext/Judy1_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/Judy1
cd man/man3; ln -s Judy J1T
cd man/man3; ln -s Judy J1S
cd man/man3; ln -s Judy J1U
cd man/man3; ln -s Judy J1F
cd man/man3; ln -s Judy J1N
cd man/man3; ln -s Judy J1L
cd man/man3; ln -s Judy J1P
cd man/man3; ln -s Judy J1FE
cd man/man3; ln -s Judy J1NE
cd man/man3; ln -s Judy J1LE
cd man/man3; ln -s Judy J1PE
cd man/man3; ln -s Judy J1C
cd man/man3; ln -s Judy J1BC
cd man/man3; ln -s Judy J1FA
cd man/man3; ln -s Judy J1MU
man/man3/Judy1_funcs:
../tool/jhton ext/Judy1_funcs_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/Judy1_funcs
cd man/man3; ln -s Judy1_funcs Judy1Test
cd man/man3; ln -s Judy1_funcs Judy1Set
cd man/man3; ln -s Judy1_funcs Judy1Unset
cd man/man3; ln -s Judy1_funcs Judy1First
cd man/man3; ln -s Judy1_funcs Judy1Next
cd man/man3; ln -s Judy1_funcs Judy1Last
cd man/man3; ln -s Judy1_funcs Judy1Prev
cd man/man3; ln -s Judy1_funcs Judy1FirstEmpty
cd man/man3; ln -s Judy1_funcs Judy1NextEmpty
cd man/man3; ln -s Judy1_funcs Judy1LastEmpty
cd man/man3; ln -s Judy1_funcs Judy1PrevEmpty
cd man/man3; ln -s Judy1_funcs Judy1Count
cd man/man3; ln -s Judy1_funcs Judy1ByCount
cd man/man3; ln -s Judy1_funcs Judy1FreeArray
cd man/man3; ln -s Judy1_funcs Judy1MemUsed
man/man3/JudyL:
../tool/jhton ext/JudyL_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/JudyL
cd man/man3; ln -s JudyL JLG
cd man/man3; ln -s JudyL JLI
cd man/man3; ln -s JudyL JLD
cd man/man3; ln -s JudyL JLF
cd man/man3; ln -s JudyL JLN
cd man/man3; ln -s JudyL JLL
cd man/man3; ln -s JudyL JLP
cd man/man3; ln -s JudyL JLFE
cd man/man3; ln -s JudyL JLNE
cd man/man3; ln -s JudyL JLLE
cd man/man3; ln -s JudyL JLPE
cd man/man3; ln -s JudyL JLC
cd man/man3; ln -s JudyL JLBC
cd man/man3; ln -s JudyL JLFA
cd man/man3; ln -s JudyL JLMU
man/man3/JudyL_funcs:
../tool/jhton ext/JudyL_funcs_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/JudyL_funcs
cd man/man3; ln -s JudyL_funcs JudyLGet
cd man/man3; ln -s JudyL_funcs JudyLIns
cd man/man3; ln -s JudyL_funcs JudyLDel
cd man/man3; ln -s JudyL_funcs JudyLFirst
cd man/man3; ln -s JudyL_funcs JudyLNext
cd man/man3; ln -s JudyL_funcs JudyLLast
cd man/man3; ln -s JudyL_funcs JudyLPrev
cd man/man3; ln -s JudyL_funcs JudyLFirstEmpty
cd man/man3; ln -s JudyL_funcs JudyLNextEmpty
cd man/man3; ln -s JudyL_funcs JudyLLastEmpty
cd man/man3; ln -s JudyL_funcs JudyLPrevEmpty
cd man/man3; ln -s JudyL_funcs JudyLCount
cd man/man3; ln -s JudyL_funcs JudyLByCount
cd man/man3; ln -s JudyL_funcs JudyLFreeArray
cd man/man3; ln -s JudyL_funcs JudyLMemUsed
man/man3/JudySL:
../tool/jhton ext/JudySL_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/JudySL
cd man/man3; ln -s JudySL JSLG
cd man/man3; ln -s JudySL JSLI
cd man/man3; ln -s JudySL JSLD
cd man/man3; ln -s JudySL JSLF
cd man/man3; ln -s JudySL JSLN
cd man/man3; ln -s JudySL JSLL
cd man/man3; ln -s JudySL JSLP
cd man/man3; ln -s JudySL JSLFA
man/man3/JudySL_funcs:
../tool/jhton ext/JudySL_funcs_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/JudySL_funcs
cd man/man3; ln -s JudySL_funcs JudySLGet
cd man/man3; ln -s JudySL_funcs JudySLIns
cd man/man3; ln -s JudySL_funcs JudySLDel
cd man/man3; ln -s JudySL_funcs JudySLFirst
cd man/man3; ln -s JudySL_funcs JudySLNext
cd man/man3; ln -s JudySL_funcs JudySLLast
cd man/man3; ln -s JudySL_funcs JudySLPrev
cd man/man3; ln -s JudySL_funcs JudySLFreeArray
man/man3/JudyHS:
../tool/jhton ext/JudyHS_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/JudyHS
cd man/man3; ln -s JudyHS JHSG
cd man/man3; ln -s JudyHS JHSI
cd man/man3; ln -s JudyHS JHSD
cd man/man3; ln -s JudyHS JHSFA
man/man3/JudyHS_funcs:
../tool/jhton ext/JudyHS_funcs_3.htm | grep -v '^[ ]*$$' | sed -e 's/\.C//' > man/man3/JudyHS_funcs
cd man/man3; ln -s JudyHS_funcs JudyHSGet
cd man/man3; ln -s JudyHS_funcs JudyHSIns
cd man/man3; ln -s JudyHS_funcs JudyHSDel
cd man/man3; ln -s JudyHS_funcs JudyHSFreeArray
CLEANFILES = man/man3/*

View File

@@ -1,309 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.48 $ $Source: /cvsroot/judy/judy/doc/ext/Judy1_3.htm,v $ --->
<TITLE>Judy1(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">Judy1(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">Judy1(3)</TD>
</TR></TABLE>
<P>
<DL>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
Judy1 macros -
C library for creating and accessing a dynamic array of bits, using
any value of a word as an index.
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<B><PRE>
cc [flags] <I>sourcefiles</I> -lJudy
</PRE></B>
<P>
<B><PRE>
#include &lt;Judy.h&gt;
int Rc_int; // return code - integer
Word_t Rc_word; // return code - unsigned word
Word_t Index, Index1, Index2, Nth;
Pvoid_t PJ1Array = (Pvoid_t) NULL; // initialize Judy1 array
<A href="#J1S" >J1S</A>( Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1Set">Judy1Set()</A>
<A href="#J1U" >J1U</A>( Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1Unset">Judy1Unset()</A>
<A href="#J1T" >J1T</A>( Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1Test">Judy1Test()</A>
<A href="#J1C" >J1C</A>( Rc_word, PJ1Array, Index1, Index2); // <A href="Judy1_funcs_3.htm#Judy1Count">Judy1Count()</A>
<A href="#J1BC">J1BC</A>(Rc_int, PJ1Array, Nth, Index); // <A href="Judy1_funcs_3.htm#Judy1ByCount">Judy1ByCount()</A>
<A href="#J1FA">J1FA</A>(Rc_word, PJ1Array); // <A href="Judy1_funcs_3.htm#Judy1FreeArray">Judy1FreeArray()</A>
<A href="#J1MU">J1MU</A>(Rc_word, PJ1Array); // <A href="Judy1_funcs_3.htm#Judy1MemUsed">Judy1MemUsed()</A>
<A href="#J1F" >J1F</A>( Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1First">Judy1First()</A>
<A href="#J1N" >J1N</A>( Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1Next">Judy1Next()</A>
<A href="#J1L" >J1L</A>( Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1Last">Judy1Last()</A>
<A href="#J1P" >J1P</A>( Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1Prev">Judy1Prev()</A>
<A href="#J1FE">J1FE</A>(Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1FirstEmpty">Judy1FirstEmpty()</A>
<A href="#J1NE">J1NE</A>(Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1NextEmpty">Judy1NextEmpty()</A>
<A href="#J1LE">J1LE</A>(Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1LastEmpty">Judy1LastEmpty()</A>
<A href="#J1PE">J1PE</A>(Rc_int, PJ1Array, Index); // <A href="Judy1_funcs_3.htm#Judy1PrevEmpty">Judy1PrevEmpty()</A>
</PRE></B>
<!----------------->
<P>
<DT><B>DESCRIPTION</B></DT>
<DD>
A Judy1 array is the equivalent of a bit array or bit map.
A bit is addressed by an <B>Index</B> (key).
The array may be sparse, and the <B>Index</B> may be any word-sized <B>Value</B>.
If an index is present, it represents a set bit
(a bit set represents an index present).
If an index is absent, it represents an unset bit
(a bit unset represents an absent index).
<P>
A Judy1 array is allocated with a <B>NULL</B> pointer
<PRE>
Pvoid_t PJ1Array = (Pvoid_t) NULL;
</PRE>
Memory to support the array is allocated as bits are set,
and released as bits are unset.
If the Judy1 pointer (<B>PJ1Array</B>) is NULL, all bits are unset (and
the Judy1 array requires no memory).
<P>
As with an ordinary array, a Judy1 array contains no duplicate indexes.
<P>
Using the macros described here, rather than the
<A href="Judy1_funcs_3.htm">Judy1 function calls</A>,
the default error handling sends a
message to the standard error and terminates the program with
<B>exit(1)</B>.
For other error handling methods, see the
<A href="#J1ERR">ERRORS</A> section.
<P>
Because the macro forms are sometimes faster and have a simpler error
handling interface than the equivalent
<A href="Judy1_funcs_3.htm">functions</A>,
they are the preferred way of calling the Judy1 functions.
<P>
<DL>
<DT><A name="J1S"><B>J1S(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1Set">Judy1Set()</A></DT>
<DD>
Set <B>Index</B>'s bit in the Judy1 array <B>PJ1Array</B>.
<P>
Return <B>Rc_int</B> set to 1 if <B>Index</B>'s bit was previously unset
(successful), otherwise 0
if the bit was already set (unsuccessful).
<P>
<DT><A name="J1U"><B>J1U(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1Unset">Judy1Unset()</A></DT>
<DD>
Unset <B>Index</B>'s bit in the Judy1 array <B>PJ1Array</B>;
that is, remove <B>Index</B> from the Judy1 array.
<P>
Return <B>Rc_int</B> set to 1 if <B>Index</B>'s bit was
previously set (successful), otherwise 0
if the bit was already unset (unsuccessful).
<P>
<DT><A name="J1T"><B>J1T(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1Test">Judy1Test()</A></DT>
<DD>
Test if <B>Index</B>'s bit is set in the
Judy1 array <B>PJ1Array</B>.
<P>
Return <B>Rc_int</B> set to 1 if <B>Index</B>'s bit is set
(<B>Index</B> is present),
0 if it is unset (<B>Index</B> is absent).
<P>
<DT><A name="J1C"><B>J1C(Rc_word, PJ1Array, Index1, Index2);</B></A> // <A href="Judy1_funcs_3.htm#Judy1Count">Judy1Count()</A></DT>
<DD>
Count the number of indexes present in the Judy1 array
<B>PJ1Array</B> between
<B>Index1</B> and <B>Index2</B> (inclusive).
<P>
Return <B>Rc_word</B> set to the count.
A return <B>Value</B> of 0 can be valid as a count,
or it can indicate a special case for fully
populated array (32-bit machines only). See
<A href="Judy1_funcs_3.htm#Judy1Count">Judy1Count()</A>
for ways to resolve this.
<P>
To count all indexes present (population) in a Judy1 bit array, use:
<PRE>
J1C(Rc_word, PJ1Array, 0, -1);
</PRE>
<B>Note:</B> The -1 promotes to the maximum index, that is, all ones.
<P>
<DT><A name="J1BC"><B>J1BC(Rc_int, PJ1Array, Nth, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1ByCount">Judy1ByCount()</A></DT>
<DD>
Locate the <B>Nth</B> index that is present in the Judy1 array
<B>PJ1Array</B> (<B>Nth</B> = 1 returns the first index present).
To refer to the last index in a fully populated array (all indexes
present, which is rare), use <B>Nth</B> = 0.
<P>
Return <B>Rc_int</B> set to 1 and <B>Index</B> set to the
<B>Nth</B> index if found, otherwise return <B>Rc_int</B>
set to 0 (the <B>Value</B> of <B>Index</B> contains no
useful information).
<P>
<DT><A name="J1FA"><B>J1FA(Rc_word, PJ1Array);</B></A> // <A href="Judy1_funcs_3.htm#Judy1FreeArray">Judy1FreeArray()</A></DT>
<DD>
Free the entire Judy1 array <B>PJ1Array</B> (much faster than using a
<B>J1N()</B>, <B>J1U()</B> loop).
<P>
Return <B>Rc_word</B> set to the number of bytes freed,
and <B>PJ1Array</B> set to <B>NULL</B>.
<P>
<DT><A name="J1MU"><B>J1MU(Rc_word, PJ1Array);</B></A> // <A href="Judy1_funcs_3.htm#Judy1MemUsed">Judy1MemUsed()</A></DT>
<DD>
Return <B>Rc_word</B> set to the number of bytes of memory currently in use by
Judy1 array <B>PJ1Array</B>. This is a very fast routine, and may be used after
a <B>J1S()</B> or <B>J1U()</B> call with little performance impact.
<P>
<DT><B>Judy1 Search Functions</B></DT>
<DD>
The Judy1 search functions allow you to search for set or unset bits in the array.
You may search inclusively or exclusively,
in either forward or reverse directions.
All of the search functions use a similar calling sequence.
<B>Rc_int</B> is returned set to 1 for a successful search and the found <B>Index</B> is returned.
<B>Rc_int</B> is returned set to 0 for an unsuccessful search,
and <B>Index</B> contains no useful information.
The return code <B>Rc_int</B> must be checked prior to using the returned <B>Index</B>,
since a search failure is possible.
<P>
<DT><A name="J1F"><B>J1F(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1First">Judy1First()</A></DT>
<DD>
Search (inclusive) for the first index present that is equal
to or greater than the passed <B>Index</B>.
(Start with <B>Index</B> = 0 to find the first index in the
array.) <B>J1F()</B> is typically used to <I>begin</I> a
sorted-order scan of the indexes present in a Judy1 array.
<P>
<DT><A name="J1N"><B>J1N(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1Next">Judy1Next()</A></DT>
<DD>
Search (exclusive) for the next index present that is
greater than the passed <B>Index</B>.
<B>J1N()</B> is typically used to <I>continue</I> a
sorted-order scan of the indexes present
in a Judy1 array, or to locate a "neighbor" of a given index.
<P>
<DT><A name="J1L"><B>J1L(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1Last">Judy1Last()</A></DT>
<DD>
Search (inclusive) for the last index present that is equal
to or less than the passed <B>Index</B>. (Start with
<B>Index</B> = -1, that is, all ones, to find the last index
in the array.) <B>J1L()</B> is typically used to <I>begin</I>
a reverse-sorted-order scan
of the indexes present in a Judy1 array.
<P>
<DT><A name="J1P"><B>J1P(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1Prev">Judy1Prev()</A></DT>
<DD>
Search (exclusive) for the previous index present that is
less than the passed <B>Index</B>. <B>J1P()</B> is typically
used to <I>continue</I> a reverse-sorted-order scan of the indexes
present in a Judy1 array, or to locate a "neighbor" of a given index.
<P>
<DT><A name="J1FE"><B>J1FE(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1FirstEmpty">Judy1FirstEmpty()</A></DT>
<DD>
Search (inclusive) for the first absent index that is equal to
or greater than the passed <B>Index</B>. (Start with
<B>Index</B> = 0 to find the first index absent in the array.)
<P>
<DT><A name="J1NE"><B>J1NE(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1NextEmpty">Judy1NextEmpty()</A></DT>
<DD>
Search (exclusive) for the next absent index that is
greater than the passed <B>Index</B>.
<P>
<DT><A name="J1LE"><B>J1LE(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1LastEmpty">Judy1LastEmpty()</A></DT>
<DD>
Search (inclusive) for the last absent index that is
equal to or less than the passed <B>Index</B>.
(Start with <B>Index</B> = -1 to find the last index
absent in the array.)
<P>
<DT><A name="J1PE"><B>J1PE(Rc_int, PJ1Array, Index);</B></A> // <A href="Judy1_funcs_3.htm#Judy1PrevEmpty">Judy1PrevEmpty()</A></DT>
<DD>
Search (exclusive) for the previous absent index that is
less than the passed <B>Index</B>.
</DL>
<!----------------->
<P>
<DT><A name="J1ERR"><B>ERRORS:</B> See: </A><A href="Judy_3.htm#ERRORS">Judy_3.htm#ERRORS</A></DT>
<DD>
<!----------------->
<P>
<DT><A name="J1EX"><B>EXAMPLE</B></A></DT>
<DD>
In the following example, errors in the <B>J1S()</B> or <B>J1U()</B> calls
go to a user-defined procedure, process_malloc_failure. This is not needed
when you use the default <B>JUDYERROR()</B> macro, since the default causes
your program to exit on all failures,
including <I>malloc()</I> failure.
<P>
<PRE>
#include &lt;stdio.h&gt;
#include &lt;Judy.h&gt;
int main() // Example program of Judy1 macro APIs
{
Word_t Index; // index (or key)
Word_t Rcount; // count of indexes (or bits set)
Word_t Rc_word; // full word return value
int Rc_int; // boolean values returned (0 or 1)
Pvoid_t PJ1Array = (Pvoid_t) NULL; // initialize Judy1 array
Index = 123456;
J1S(Rc_int, J1Array, Index); // set bit at 123456
if (Rc_int == JERR) goto process_malloc_failure;
if (Rc_int == 1) printf("OK - bit successfully set at %lu\n", Index);
if (Rc_int == 0) printf("BUG - bit already set at %lu\n", Index);
Index = 654321;
J1T(Rc_int, J1Array, Index); // test if bit set at 654321
if (Rc_int == 1) printf("BUG - set bit at %lu\n", Index);
if (Rc_int == 0) printf("OK - bit not set at %lu\n", Index);
J1C(Rcount, J1Array, 0, -1); // count all bits set in array
printf("%lu bits set in Judy1 array\n", Rcount);
Index = 0;
J1F(Rc_int, J1Array, Index); // find first bit set in array
if (Rc_int == 1) printf("OK - first bit set is at %lu\n", Index);
if (Rc_int == 0) printf("BUG - no bits set in array\n");
J1MU(Rc_word, J1Array); // how much memory was used?
printf("%lu Indexes used %lu bytes of memory\n", Rcount, Rc_word);
Index = 123456;
J1U(Rc_int, J1Array, Index); // unset bit at 123456
if (Rc_int == JERR) goto process_malloc_failure;
if (Rc_int == 1) printf("OK - bit successfully unset at %lu\n", Index);
if (Rc_int == 0) printf("BUG - bit was not set at %lu\n", Index);
return(0);
}
</PRE>
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
Judy was invented by Doug Baskins and implemented by Hewlett-Packard.
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy_3.htm">Judy(3)</A>,
<A href="JudyL_3.htm">JudyL(3)</A>,
<A href="JudySL_3.htm">JudySL(3)</A>,
<A href="JudyHS_3.htm">JudyHS(3)</A>,
<BR>
<I>malloc()</I>,
<BR>
the Judy website,
<A href="http://judy.sourceforge.net">
http://judy.sourceforge.net</A>,
for more information and Application Notes.
</DL>
</BODY>
</HTML>

View File

@@ -1,260 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.8 $ $Source: /cvsroot/judy/doc/ext/Judy1_funcs_3.htm,v $ --->
<TITLE>Judy1_funcs(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">Judy1_funcs(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">Judy1_funcs(3)</TD>
</TR></TABLE>
<P>
<DL>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
Judy1 functions -
C library for creating and accessing a dynamic array of bits, using
any value of a word as an index
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<B><PRE>
int <A href="#Judy1Set" >Judy1Set</A>( PPvoid_t PPJ1Array, Word_t Index, PJError_t PJError);
int <A href="#Judy1Unset" >Judy1Unset</A>( PPvoid_t PPJ1Array, Word_t Index, PJError_t PJError);
int <A href="#Judy1Test" >Judy1Test</A>( Pcvoid_t PJ1Array, Word_t Index, PJError_t PJError);
Word_t <A href="#Judy1Count" >Judy1Count</A>( Pcvoid_t PJ1Array, Word_t Index1, Word_t Index2, PJError_t PJError);
int <A href="#Judy1ByCount" >Judy1ByCount</A>( Pcvoid_t PJ1Array, Word_t Nth, Word_t * PIndex, PJError_t PJError);
Word_t <A href="#Judy1FreeArray" >Judy1FreeArray</A>( PPvoid_t PPJ1Array, PJError_t PJError);
Word_t <A href="#Judy1MemUsed" >Judy1MemUsed</A>( Pcvoid_t PJ1Array);
int <A href="#Judy1First" >Judy1First</A>( Pcvoid_t PJ1Array, Word_t * PIndex, PJError_t PJError);
int <A href="#Judy1Next" >Judy1Next</A>( Pcvoid_t PJ1Array, Word_t * PIndex, PJError_t PJError);
int <A href="#Judy1Last" >Judy1Last</A>( Pcvoid_t PJ1Array, Word_t * PIndex, PJError_t PJError);
int <A href="#Judy1Prev" >Judy1Prev</A>( Pcvoid_t PJ1Array, Word_t * PIndex, PJError_t PJError);
int <A href="#Judy1FirstEmpty">Judy1FirstEmpty</A>(Pcvoid_t PJ1Array, Word_t * PIndex, PJError_t PJError);
int <A href="#Judy1NextEmpty" >Judy1NextEmpty</A>( Pcvoid_t PJ1Array, Word_t * PIndex, PJError_t PJError);
int <A href="#Judy1LastEmpty" >Judy1LastEmpty</A>( Pcvoid_t PJ1Array, Word_t * PIndex, PJError_t PJError);
int <A href="#Judy1PrevEmpty" >Judy1PrevEmpty</A>( Pcvoid_t PJ1Array, Word_t * PIndex, PJError_t PJError);
</PRE></B>
<!----------------->
<P>
<DT><B>DESCRIPTION</B></DT>
<DD>
A macro equivalent exists for each function call.
Because the macro forms are sometimes faster and have a simpler error
handling interface than the equivalent functions,
they are the preferred way of calling the Judy1 functions.
See <A href="Judy1_3.htm">Judy1(3)</A>
for more information.
The function call definitions are included here for completeness.
<P>
One of the difficulties in using the Judy1 function calls lies in
determining whether to pass a pointer or the address of a pointer.
Since the functions that modify the Judy1 array must also modify the
pointer to the Judy1 array, you must pass the address of the pointer
rather than the pointer itself.
This often leads to hard-to-debug programmatic errors.
In practice, the macros allow the compiler to catch programming
errors when pointers instead of addresses of pointers are passed.
<P>
The Judy1 function calls have an additional parameter beyond
those specified in the macro calls. This parameter is either a
pointer to an error structure, or <B>NULL</B> (in which case the
detailed error information is not returned).
<P>
In the following descriptions, the functions are described in
terms of how the macros use them (only in the case of
<B>#define JUDYERROR_NOTEST 1</B>). This is the suggested use
of the macros after your program has been fully debugged.
When the <B>JUDYERROR_NOTEST</B> macro is not specified,
an error structure is declared to store error information
returned from the Judy1 functions when an error occurs.
<P>
Notice the placement of the <B>&amp;</B> in the different functions.
<P>
<DL>
<DT><A name="Judy1Set"><B>Judy1Set(&amp;PJ1Array, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1S(Rc_int, PJ1Array, Index) \
Rc_int = Judy1Set(&amp;PJ1Array, Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1Unset"><B>Judy1Unset(&amp;PJ1Array, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1U(Rc_int, PJ1Array, Index) \
Rc_int = Judy1Unset(&amp;PJ1Array, Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1Test"><B>Judy1Test(PJ1Array, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1T(Rc_int, PJ1Array, Index) \
Rc_int = Judy1Test(PJ1Array, Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1Count"><B>Judy1Count(PJ1Array, Index1, Index2, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1C(Rc_word, PJ1Array, Index1, Index2) \
Rc_word = Judy1Count(PJ1Array, Index1, Index2, PJE0)
</PRE>
A return value of 0 can be an error, valid as a count, or it can indicate a special case
for a fully-populated array (32-bit machines only). If necessary, the following
code can be used to disambiguate this return:
<PRE>
JError_t JError;
Rc_word = Judy1Count(PJ1Array, Index1, Index2, &amp;JError);
if (Rc_word == 0)
{
if (JU_ERRNO(&amp;JError) == JU_ERRNO_NONE)
printf("Judy1 array population == 0\n");
if (JU_ERRNO(&amp;JError) == JU_ERRNO_FULL)
printf("Judy1 array population == 2^32\n");
if (JU_ERRNO(&amp;JError) == JU_ERRNO_NULLPPARRAY)
goto NullArray;
if (JU_ERRNO(&amp;JError) > JU_ERRNO_NFMAX)
goto Null_or_CorruptArray;
}
</PRE>
<P>
<DT><A name="Judy1ByCount"><B>Judy1ByCount(PJ1Array, Nth, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1BC(Rc_int, PJ1Array, Nth, Index) \
Rc_int = Judy1ByCount(PJ1Array, Nth, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1FreeArray"><B>Judy1FreeArray(&amp;PJ1Array, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1FA(Rc_word, PJ1Array) \
Rc_word = Judy1FreeArray(&amp;PJ1Array, PJE0)
</PRE>
<P>
<DT><A name="Judy1MemUsed"><B>Judy1MemUsed(PJ1Array)</B></A></DT>
<DD>
<PRE>
#define J1MU(Rc_word, PJ1Array) \
Rc_word = Judy1MemUsed(PJ1Array)
</PRE>
<P>
<DT><A name="Judy1First"><B>Judy1First(PJ1Array, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1F(Rc_int, PJ1Array, Index) \
Rc_int = Judy1First(PJ1Array, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1Next"><B>Judy1Next(PJ1Array, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1N(Rc_int, PJ1Array, Index) \
Rc_int = Judy1Next(PJ1Array, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1Last"><B>Judy1Last(PJ1Array, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1L(Rc_int, PJ1Array, Index) \
Rc_int = Judy1Last(PJ1Array, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1Prev"><B>Judy1Prev(PJ1Array, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1P(Rc_int, PJ1Array, Index) \
Rc_int = Judy1Prev(PJ1Array, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1FirstEmpty"><B>Judy1FirstEmpty(PJ1Array, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1FE(Rc_int, PJ1Array, Index) \
Rc_int = Judy1FirstEmpty(PJ1Array, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1NextEmpty"><B>Judy1NextEmpty(PJ1Array, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1NE(Rc_int, PJ1Array, Index) \
Rc_int = Judy1NextEmpty(PJ1Array, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1LastEmpty"><B>Judy1LastEmpty(PJ1Array, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1LE(Rc_int, PJ1Array, Index) \
Rc_int = Judy1LastEmpty(PJ1Array, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="Judy1PrevEmpty"><B>Judy1PrevEmpty(PJ1Array, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define J1PE(Rc_int, PJ1Array, Index) \
Rc_int = Judy1PrevEmpty(PJ1Array, &amp;Index, PJE0)
</PRE>
</DL>
<P>
Definitions for all of the Judy functions, the types
<B>Pvoid_t</B>,
<B>Pcvoid_t</B>,
<B>PPvoid_t</B>,
<B>Word_t</B>,
<B>JError_t</B>,
and
<B>PJError_t</B>,
the constants
<B>NULL</B>,
<B>JU_ERRNO_*</B>,
<B>JERR</B>,
and
<B>PJE0</B>,
are provided in the <B>Judy.h</B> header file
(/usr/include/Judy.h).
<B>Note</B>: Callers should define Judy1 arrays as type <B>Pvoid_t</B>,
which can be passed by value to functions that take
<B>Pcvoid_t</B> (constant <B>Pvoid_t</B>),
and also by address to functions that take <B>PPvoid_t</B>.
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
Judy was invented by Doug Baskins and implemented by Hewlett-Packard.
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy_3.htm">Judy(3)</A>,
<A href="JudyL_3.htm">JudyL(3)</A>,
<A href="JudySL_3.htm">JudySL(3)</A>,
<A href="JudyHS_3.htm">JudyHS(3)</A>,
<BR>
<I>malloc()</I>,
<BR>
the Judy website,
<A href="http://judy.sourceforge.net">
http://judy.sourceforge.net</A>,
for more information and Application Notes.
</DL>
</BODY>
</HTML>

View File

@@ -1,197 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.43 $ $Source: /cvsroot/judy/doc/ext/JudyHS_3.htm,v $ --->
<TITLE>JudyHS(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">JudyHS(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">JudyHS(3)</TD>
</TR></TABLE>
<P>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
JudyHS macros - C library for creating and accessing a dynamic array,
using an array-of-bytes of <B>Length</B> as an <B>Index</B> and a word
as a <B>Value</B>.
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<B><PRE>
cc [flags] <I>sourcefiles</I> -lJudy
#include &lt;Judy.h&gt;
Word_t * PValue; // JudyHS array element
int Rc_int; // return flag
Word_t Rc_word; // full word return value
Pvoid_t PJHSArray = (Pvoid_t) NULL; // initialize JudyHS array
uint8_t * Index; // array-of-bytes pointer
Word_t Length; // number of bytes in Index
<A href="#JHSI" >JHSI</A>( PValue, PJHSArray, Index, Length); // <A href="JudyHS_funcs_3.htm#JudyHSIns">JudyHSIns()</A>
<A href="#JHSD" >JHSD</A>( Rc_int, PJHSArray, Index, Length); // <A href="JudyHS_funcs_3.htm#JudyHSDel">JudyHSDel()</A>
<A href="#JHSG" >JHSG</A>( PValue, PJHSArray, Index, Length); // <A href="JudyHS_funcs_3.htm#JudyHSGet">JudyHSGet()</A>
<A href="#JHSFA">JHSFA</A>(Rc_word, PJHSArray); // <A href="JudyHS_funcs_3.htm#JudyHSFreeArray">JudyHSFreeArray()</A>
</PRE></B>
<!----------------->
<DT><B>DESCRIPTION</B></DT>
<DD>
A JudyHS array is the equivalent of an array of word-sized
value/pointers. An <B>Index</B> is a pointer to an array-of-bytes of
specified length: <B>Length</B>. Rather than using a null terminated
string, this difference from <A href="JudySL_3.htm">JudySL(3)</A>
allows strings to contain all bits (specifically the null character).
This new addition (May 2004) to Judy arrays is a hybird using the best
capabilities of hashing and Judy methods. <B>JudyHS</B> does not have a
poor performance case where knowledge of the hash algorithm can be used
to degrade the performance.
<P>
Since JudyHS is based on a hash method, <B>Indexes</B> are not stored in
any particular order. Therefore the JudyHSFirst(), JudyHSNext(),
JudyHSPrev() and JudyHSLast() neighbor search functions are not
practical. The <B>Length</B> of each array-of-bytes can be from 0 to
the limits of <I>malloc()</I> (about 2GB).
<P>
The hallmark of <B>JudyHS</B> is speed with scalability, but memory
efficiency is excellent. The speed is very competitive with the best
hashing methods. The memory efficiency is similar to a linked list of
the same <B>Indexes</B> and <B>Values</B>. <B>JudyHS</B> is designed to
scale from 0 to billions of <B>Indexes</B>.
<P>
A JudyHS array is allocated with a <B>NULL</B> pointer
<PRE>
Pvoid_t PJHSArray = (Pvoid_t) NULL;
</PRE>
<P>
Because the macro forms of the API have a simpler error handling
interface than the equivalent
<A href="JudyHS_funcs_3.htm">functions</A>,
they are the preferred way to use JudyHS.
<P>
<DT>
<A name="JHSI"><B>JHSI(PValue, PJHSArray, Index, Length)</B></A> // <A href="JudyHS_funcs_3.htm#JudyHSIns">JudyHSIns()</A></DT>
<DD>
Given a pointer to a JudyHS array (<B>PJHSArray</B>), insert an
<B>Index</B> string of length: <B>Length</B> and a <B>Value</B> into the
JudyHS array: <B>PJHSArray</B>. If the <B>Index</B> is successfully
inserted, the <B>Value</B> is initialized to 0. If the <B>Index</B> was
already present, the <B>Value</B> is not modified.
<P>
Return <B>PValue</B> pointing to <B>Value</B>. Your program should use
this pointer to read or modify the <B>Value</B>, for example:
<PRE>
Value = *PValue;
*PValue = 1234;
</PRE>
<P>
<B>Note</B>:
<B>JHSI()</B> and <B>JHSD</B> can reorganize the JudyHS array.
Therefore, pointers returned from previous <B>JudyHS</B> calls become
invalid and must be re-acquired (using <B>JHSG()</B>).
<P>
<DT><A name="JHSD"><B>JHSD(Rc_int, PJHSArray, Index, Length)</B></A> // <A href="JudyHS_funcs_3.htm#JudyHSDel">JudyHSDel()</A></DT>
<DD>
Given a pointer to a JudyHS array (<B>PJHSArray</B>), delete the
specified <B>Index</B> along with the <B>Value</B> from the JudyHS
array.
<P>
Return <B>Rc_int</B> set to 1 if successfully removed from the array.
Return <B>Rc_int</B> set to 0 if <B>Index</B> was not present.
<P>
<DT><A name="JHSG"><B>JHSG(PValue, PJHSArray, Index, Length)</B></A> // <A href="JudyHS_funcs_3.htm#JudyHSGet">JudyHSGet()</A></DT>
<DD>
Given a pointer to a JudyHS array (<B>PJHSArray</B>),
find <B>Value</B> associated with <B>Index</B>.
<P>
Return <B>PValue</B> pointing to <B>Index</B>'s <B>Value</B>.
Return <B>PValue</B> set to <B>NULL</B> if the <B>Index</B> was not present.
<P>
<DT><A name="JHSFA"><B>JHSFA(Rc_word, PJHSArray)</B></A> // <A href="JudyHS_funcs_3.htm#JudyHSFreeArray">JudyHSFreeArray()</A></DT>
<DD>
Given a pointer to a JudyHS array (<B>PJHSArray</B>), free the entire array.
<P>
Return <B>Rc_word</B> set to the number of bytes freed and <B>PJHSArray</B> set to NULL.
<!----------------->
<P>
<DT><A name="ERRORS"><B>ERRORS:</B> See: </A><A href="Judy_3.htm#ERRORS">Judy_3.htm#ERRORS</A></DT>
<DD>
<P>
<DT><B>EXAMPLES</B></DT>
<DD>
Show how to program with the JudyHS macros. This program will print
duplicate lines and their line number from <I>stdin</I>.
<P><PRE>
#include &lt;unistd.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;Judy.h&gt;
// Compiled:
// cc -O PrintDupLines.c -lJudy -o PrintDupLines
#define MAXLINE 1000000 /* max fgets length of line */
uint8_t Index[MAXLINE]; // string to check
int // Usage: PrintDupLines &lt; file
main()
{
Pvoid_t PJArray = (PWord_t)NULL; // Judy array.
PWord_t PValue; // Judy array element pointer.
Word_t Bytes; // size of JudyHS array.
Word_t LineNumb = 0; // current line number
Word_t Dups = 0; // number of duplicate lines
while (fgets(Index, MAXLINE, stdin) != (char *)NULL)
{
LineNumb++; // line number
// store string into array
JHSI(PValue, PJArray, Index, strlen(Index));
if (PValue == PJERR) // See ERRORS section
{
fprintf(stderr, "Out of memory -- exit\n");
exit(1);
}
if (*PValue == 0) // check if duplicate
{
Dups++;
printf("Duplicate lines %lu:%lu:%s", *PValue, LineNumb, Index);
}
else
{
*PValue = LineNumb; // store Line number
}
}
printf("%lu Duplicates, free JudyHS array of %lu Lines\n",
Dups, LineNumb - Dups);
JHSFA(Bytes, PJArray); // free JudyHS array
printf("JudyHSFreeArray() free'ed %lu bytes of memory\n", Bytes);
return (0);
}
</PRE>
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
JudyHS was invented and implemented by Doug Baskins after retiring from Hewlett-Packard.
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy_3.htm">Judy(3)</A>,
<A href="Judy1_3.htm">Judy1(3)</A>,
<A href="JudyL_3.htm">JudyL(3)</A>,
<A href="JudySL_3.htm">JudySL(3)</A>,
<BR>
<I>malloc()</I>,
<BR>
the Judy website,
<A href="http://judy.sourceforge.net">
http://judy.sourceforge.net</A>,
for further information and Application Notes.
</BODY>
</HTML>

View File

@@ -1,150 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.5 $ $Source: /cvsroot/judy/doc/ext/JudyHS_funcs_3.htm,v $ --->
<TITLE>JudyHS_funcs(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">JudyHS_funcs(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">JudyHS_funcs(3)</TD>
</TR></TABLE>
<P>
<DL>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
JudyHS functions -
C library for creating and accessing a dynamic array,
using an array-of-bytes of a length: <B>Length</B> as an <B>Index</B> and a word
as a <B>Value</B>.
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<B><PRE>
PPvoid_t <A href="#JudyHSIns" >JudyHSIns</A>(PPvoid_t PPJHS, void *Index, Word_t Length, PJError_t PJError);
int <A href="#JudyHSDel" >JudyHSDel</A>(PPvoid_t PPJHS, void *Index, Word_t Length, PJError_t PJError);
PPvoid_t <A href="#JudyHSGet" >JudyHSGet</A>(Pcvoid_t PJHS, void *Index, Word_t Length, PJError_t PJError);
Word_t <A href="#JudyHSFreeArray">JudyHSFreeArray</A>(PPvoid_t PPJHS, PJError_t PJError);
</PRE></B>
<!----------------->
<P>
<DT><B>DESCRIPTION</B></DT>
<DD>
A macro equivalent exists for each function call. Because the macro
forms are sometimes faster and have a simpler error handling interface
than the equivalent functions, they are the preferred way of calling the
JudyHS functions.
See <A href="JudyHS_3.htm">JudyHS(3)</A>
for more information.
The function call definitions are included here for completeness.
<P>
One of the difficulties in using the JudyHS function calls lies in
determining whether to pass a pointer or the address of a pointer.
Since the functions that modify the JudyHS array must also modify the
pointer to the JudyHS array, you must pass the address of the pointer
rather than the pointer itself.
This often leads to hard-to-debug programmatic errors.
In practice, the macros allow the compiler to catch programming
errors when pointers instead of addresses of pointers are passed.
<P>
The JudyHS function calls have an additional parameter beyond those
specified in the macro calls. This parameter is either a pointer to an
error structure, or <B>NULL</B> (in which case the error information is
not returned -- only <B>PJERR</B> in the return parameter).
<P>
In the following descriptions, the functions are described in
terms of how the macros use them.
This is the suggested use
of the macros after your program has been fully debugged.
When the <B>JUDYERROR_NOTEST</B> macro is not specified,
an error structure is declared to store error information
returned from the JudyHS functions when an error occurs.
<P>
Notice the placement of the <B>&amp;</B> in the different functions.
<P>
<DL>
<DT><A name="JudyHSIns"><B>JudyHSIns(&amp;PJHS, Index, Length, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JHSI(PValue, PJHS, Index) \
PValue = JudyLIns(&amp;PJHS, Index, PJE0)
</PRE>
<P>
<DT><A name="JudyHSDel"><B>JudyHSDel(&amp;PJHS, Index, Length, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JHSD(Rc_int, PJHS, Index, Length) \
Rc_int = JudyHSDel(&amp;PJHS, Index, Length, PJE0)
</PRE>
<P>
<DT><A name="JudyHSGet"><B>JudyHSGet(PJHS, Index, Length)</B></A></DT>
<DD>
<PRE>
#define JHSG(PValue, PJHS, Index, Length) \
PValue = JudyHSIns(PJHS, Index, Length)
</PRE>
<P>
<DT><A name="JudyHSFreeArray"><B>JudyHSFreeArray(&amp;PJHS, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JHSFA(Rc_word, PJHS) \
Rc_word = JudyHSFreeArray(&amp;PJHS, PJE0)
</PRE>
</DL>
<P>
Definitions for all the Judy functions, the types
<B>Pvoid_t</B>,
<B>Pcvoid_t</B>,
<B>PPvoid_t</B>,
<B>Word_t </B>,
<B>JError_t</B>,
and
<B>PJError_t</B>,
the constants
<B>NULL</B>,
<B>JU_ERRNO_*</B>,
<B>JERR</B>,
<B>PPJERR</B>,
and
<B>PJE0</B>
are provided in the <B>Judy.h</B> header file
(/usr/include/Judy.h).
<B>Note</B>: Callers should define JudyHS arrays as type <B>Pvoid_t</B>,
which can be passed by value to functions that take
<B>Pcvoid_t</B> (constant <B>Pvoid_t</B>),
and also by address to functions that take <B>PPvoid_t</B>.
<P>
The return type from most <B>JudyHS</B> functions is <B>PPvoid_t</B> so
that the values stored in the array can be pointers to other objects,
which is a typical usage, or cast to a <B>Word_t *</B> when a pointer
to a value is required instead of a pointer to a pointer.
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
JudyHS was invented and implemented by Doug Baskins after retiring from Hewlett-Packard.
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy_3.htm">Judy(3)</A>,
<A href="Judy1_3.htm">Judy1(3)</A>,
<A href="JudyL_3.htm">JudyL(3)</A>,
<A href="JudySL_3.htm">JudySL(3)</A>,
<A href="JudyHS_3.htm">JudyHS(3)</A>,
<BR>
<I>malloc()</I>,
<BR>
the Judy website,
<A href="http://judy.sourceforge.net">
http://judy.sourceforge.net</A>,
for more information and Application Notes.
</DL>
</BODY>
</HTML>

View File

@@ -1,358 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.55 $ $Source: /cvsroot/judy/doc/ext/JudyL_3.htm,v $ --->
<TITLE>JudyL(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">JudyL(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">JudyL(3)</TD>
</TR></TABLE>
<P>
<DL>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
JudyL macros -
C library for creating and accessing a dynamic array of words, using
a word as an index.
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<B><PRE>
cc [flags] <I>sourcefiles</I> -lJudy
#include &lt;Judy.h&gt;
int Rc_int; // return code - integer
Word_t Rc_word; // return code - unsigned word
Word_t Index, Index1, Index2, Nth;
PWord_t PValue; // pointer to return value
Pvoid_t PJLArray = (Pvoid_t) NULL; // initialize JudyL array
<A href="#JLI" >JLI</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLIns">JudyLIns()</A>
<A href="#JLD" >JLD</A>( Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLDel">JudyLDel()</A>
<A href="#JLG" >JLG</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLGet">JudyLGet()</A>
<A href="#JLC" >JLC</A>( Rc_word, PJLArray, Index1, Index2); // <A href="JudyL_funcs_3.htm#JudyLCount">JudyLCount()</A>
<A href="#JLBC" >JLBC</A>(PValue, PJLArray, Nth, Index); // <A href="JudyL_funcs_3.htm#JudyLByCount">JudyLByCount()</A>
<A href="#JLFA" >JLFA</A>(Rc_word, PJLArray); // <A href="JudyL_funcs_3.htm#JudyLFreeArray">JudyLFreeArray()</A>
<A href="#JLMU" >JLMU</A>(Rc_word, PJLArray); // <A href="JudyL_funcs_3.htm#JudyLMemUsed">JudyLMemUsed()</A>
<A href="#JLF" >JLF</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLFirst">JudyLFirst()</A>
<A href="#JLN" >JLN</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLNext">JudyLNext()</A>
<A href="#JLL" >JLL</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLLast">JudyLLast()</A>
<A href="#JLP" >JLP</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLPrev">JudyLPrev()</A>
<A href="#JLFE">JLFE</A>(Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLFirstEmpty">JudyLFirstEmpty()</A>
<A href="#JLNE" >JLNE</A>(Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLNextEmpty">JudyLNextEmpty()</A>
<A href="#JLLE" >JLLE</A>(Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLLastEmpty">JudyLLastEmpty()</A>
<A href="#JLPE" >JLPE</A>(Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLPrevEmpty">JudyLPrevEmpty()</A>
</PRE></B>
<!----------------->
<P>
<DT><B>
DESCRIPTION
</B></DT>
<DD>
A JudyL array is the equivalent of an array of word-sized values.
A <B>Value</B> is addressed by an <B>Index</B> (key).
The array may be sparse, and the <B>Index</B> may be any word-sized number.
Memory to support the array is allocated as index/value pairs are inserted,
and released as index/value pairs are deleted. A JudyL array can also be
thought of as a mapper, that is "map" a word to another word/pointer.
<P>
As with an ordinary array, there are no duplicate indexes in a JudyL array.
<P>
The value may be used as a scalar, or a pointer to a structure or block of data
(or even another Judy array).
<P>
A JudyL array is allocated with a <B>NULL</B> pointer
<PRE>
Pvoid_t PJLArray = (Pvoid_t) NULL;
</PRE>
<P>
Using the macros described here, rather than the
<A href="JudyL_funcs_3.htm">JudyL function calls</A>,
the default error handling sends a
message to the standard error and terminates the program with <I>exit(1);</I>.
For other error handling methods, see the
<A href="#ERRORS">ERRORS</A> section.
<A href="#JLI" >JLI</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3.htm#JudyLIns">JudyLIns()</A>
<P>
Because the macro forms are sometimes faster and have a simpler error
handling interface than the equivalent
<A href="JudyL_funcs_3.htm">JudyL functions</A>,
they are the preferred way of calling the JudyL functions.
<P>
<DL>
<DT><A name="JLI"><B>JLI(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLIns">JudyLIns()</A></DT>
<DD>
Insert an <B>Index</B> and <B>Value</B> into the JudyL array <B>PJLArray</B>.
If the <B>Index</B> is successfully inserted,
the <B>Value</B> is initialized to 0. If the <B>Index</B> was already present,
the <B>Value</B> is not modified.
<P>
Return <B>PValue</B> pointing to <B>Value</B>.
Your program can use this pointer to read or modify <B>Value</B> until the next
<B>JLI()</B> (insert), <B>JLD()</B> (delete) or <B>JLFA()</B> (freearray)
is executed on <B>PJLArray</B>. Examples:
<PRE>
*PValue = 1234;
Value = *PValue;
</PRE>
<P>
Return <B>PValue</B> set to <B>PJERR</B> if a <I>malloc()</I> fail occured.
<B>Note</B>:
<B>JLI()</B> and <B>JLD()</B> reorganize the JudyL array.
Therefore, <B>PValue</B> returned from previous <B>JudyL</B> calls become
invalid and must be re-acquired.
<P>
<DT><A name="JLD"><B>JLD(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLDel">JudyLDel()</A></DT>
<DD>
Delete the <B>Index</B>/<B>Value</B> pair from the JudyL array.
<P>
Return <B>Rc_int</B> set to 1 if successful.
Return <B>Rc_int</B> set to 0 if <B>Index</B> was not present.
Return <B>Rc_int</B> set to <B>JERR</B> if a <I>malloc()</I> fail occured.
<P>
<DT><A name="JLG"><B>JLG(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLGet">JudyLGet()</A></DT>
<DD>
Get the pointer <B>PValue</B> associated with <B>Index</B> in the <B>PJLArray</B> Judy array.
<P>
Return <B>PValue</B> pointing to <B>Value</B>.
Return <B>PValue</B> set to <B>NULL</B> if the <B>Index</B> was not present.
Return <B>PValue</B> set to <B>PJERR</B> if a <I>malloc()</I> fail occured.
<P>
<DT><A name="JLC"><B>JLC(Rc_word, PJLArray, Index1, Index2)</B></A> // <A href="JudyL_funcs_3.htm#JudyLCount">JudyLCount()</A></DT>
<DD>
Count the number of indexes present in the JudyL array <B>PJLArray</B> between
<B>Index1</B> and <B>Index2</B> (inclusive).
<P>
Return <B>Rc_word</B> set to the count.
A return value of 0 can be valid as a count.
<P>
To count all indexes present in a JudyL array, use:
<PRE>
JLC(Rc_word, PJLArray, 0, -1);
</PRE>
<P>
<DT><A name="JLBC"><B>JLBC(PValue, PJLArray, Nth, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLByCount">JudyLByCount()</A></DT>
<DD>
Locate the <B>Nth</B> index that is present in the JudyL array
<B>PJLArray</B> (<B>Nth</B> = 1 returns the first index present).
<P>
Return <B>PValue</B> pointing to its <B>Value</B> and <B>Index</B>
set to the <B>Nth</B> index if found, otherwise return
<B>PValue</B> set to <B>NULL</B> (the value of <B>Index</B>
is undefined).
<P>
<DT><A name="JLFA"><B>JLFA(Rc_word, PJLArray)</B></A> // <A href="JudyL_funcs_3.htm#JudyLFreeArray">JudyLFreeArray()</A></DT>
<DD>
Given a pointer to a JudyL array, free the entire array (much faster
than using a
<B>JLN()</B>, <B>JLD()</B> loop).
<P>
Return <B>Rc_word</B> set to the number of bytes freed and <B>PJLArray</B>
set to <B>NULL</B>.
<P>
<DT><A name="JLMU"><B>JLMU(Rc_word, PJLArray)</B></A> // <A href="JudyL_funcs_3.htm#JudyLMemUsed">JudyLMemUsed()</A></DT>
<DD>
Return <B>Rc_word</B> set to the number of bytes of memory <I>malloc()</I>'ed
by <B>PJLArray</B>.
This is a very fast routine, and may be used before and after
a <B>JLI()</B> or <B>JLD()</B> call with little performance impact.
<P>
<DT><B>JudyL Search Functions</B></DT>
<DD>
<B>JLF()</B>, <B>JLN()</B>, <B>JLL()</B>, <B>JLP()</B>
allow you to search for indexes
in the array.
You may search inclusively or exclusively,
in either forward or reverse directions.
If successful,
<B>Index</B> is returned set to the found index, and
<B>PValue</B> is returned set to a pointer to <B>Index</B>'s <B>Value</B>.
If unsuccessful,
<B>PValue</B> is returned set to <B>NULL</B>,
and <B>Index</B> contains no useful information.
<B>PValue</B> must be tested for non-<B>NULL</B> prior
to using <B>Index</B>,
since a search failure is possible.
<P>
<B>JLFE()</B>, <B>JLNE()</B>, <B>JLLE()</B>, <B>JLPE()</B> allow you to search for
indexes that are not present ("empty") in the array.
You may search inclusively or exclusively,
in either forward or reverse directions.
If successful, <B>Index</B> is returned set to a not present ("empty") index, and
<B>Rc_int</B> is returned set to 1.
If unsuccessful, <B>Rc_int</B> is returned set to 0, and and <B>Index</B> contains no useful information.
<B>Rc_int</B> must be checked prior to using <B>Index</B>, since a search failure is possible.
<P>
<DT><A name="JLF"><B>JLF(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLFirst">JudyLFirst()</A></DT>
<DD>
Search (inclusive) for the first index present that is equal to or greater than the
passed <B>Index</B>.
(Start with <B>Index</B> = 0 to find the first index in the array.)
<B>JLF()</B> is typically used to <I>begin</I> a sorted-order scan of
the indexes present in a JudyL array.
<P>
<DT><A name="JLN"><B>JLN(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLNext">JudyLNext()</A></DT>
<DD>
Search (exclusive) for the next index present that is greater than the passed
<B>Index</B>.
<B>JLN()</B> is typically used to <I>continue</I> a sorted-order scan of
the indexes present in a JudyL array, or to locate a "neighbor" of a given index.
<P>
<DT><A name="JLL"><B>JLL(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLLast">JudyLLast()</A></DT>
<DD>
Search (inclusive) for the last index present that is equal to or less than the passed <B>Index</B>.
(Start with <B>Index</B> = -1, that is, all ones, to find the last index in the array.)
<B>JLL()</B> is typically used to <I>begin</I> a reverse-sorted-order
scan of the indexes present in a JudyL array.
<P>
<DT><A name="JLP"><B>JLP(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLPrev">JudyLPrev()</A></DT>
<DD>
Search (exclusive) for the previous index present that is less than the
passed <B>Index</B>.
<B>JLP()</B> is typically used to <I>continue</I> a reverse-sorted-order
scan of the indexes present in a JudyL array, or to locate a "neighbor" of
a given index.
<P>
<DT><A name="JLFE"><B>JLFE(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLFirstEmpty">JudyLFirstEmpty()</A></DT>
<DD>
Search (inclusive) for the first index absent that is equal to or greater than the passed
<B>Index</B>.
(Start with <B>Index</B> = 0 to find the first index absent in the array.)
<P>
<DT><A name="JLNE"><B>JLNE(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLNextEmpty">JudyLNextEmpty()</A></DT>
<DD>
Search (exclusive) for the next index absent that is greater than the passed <B>Index</B>.
<P>
<DT><A name="JLLE"><B>JLLE(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLLastEmpty">JudyLLastEmpty()</A></DT>
<DD>
Search (inclusive) for the last index absent that is equal to or less than the passed <B>Index</B>.
(Start with <B>Index</B> = -1, that is, all ones, to find the last index absent
in the array.)
<P>
<DT><A name="JLPE"><B>JLPE(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3.htm#JudyLPrevEmpty">JudyLPrevEmpty()</A></DT>
<DD>
Search (exclusive) for the previous index absent that is less than the passed
<B>Index</B>.
</DL>
<!----------------->
<P>
<DT><B>Multi-dimensional JudyL Arrays</B></DT>
<DD>
Storing a pointer to another JudyL array in a JudyL array's <B>Value</B>
is a simple way to support dynamic multi-dimensional arrays.
These arrays (or trees) built using JudyL arrays are very fast and
memory efficient. (In fact, that is how JudySL and JudyHS are implemented).
An arbitrary number of dimensions can be realized this way.
To terminate the number of dimensions (or tree), the <B>Value</B> pointer is
marked to <B>NOT</B> point to another Judy array. A <B>JLAP_INVALID</B> flag is
used in the least significant bit(s) of the pointer.
After the flag <B>JLAP_INVALID</B> is removed, it is used as a pointer to the users data.
The <B>Judy.h</B> header file defines <B>JLAP_INVALID</B>.
See code fragment below.
<P>
Note: The current version of <B>Judy.h</B> changed this flag from 0x4 to 0x1
to allow for a <I>malloc()</I> that does not deliver memory on an 8 byte
aligned boundry (such as old versions of valgrind).
<P>
The following example code segment can be used to determine whether or
not a pointer points to another JudyL:
<P>
<PRE>
PValue = (PWord_t)PMultiDimArray;
for (Dim = 0; ;Dim++)
{
if (PValue == (PWord_t)NULL) goto IndexNotFound;
/* Advance to next dimension in array */
JLG(PValue, (Pvoid_t)*PValue, Index[Dim]);
/* Check if pointer to user buffer: */
if (*PValue &amp; JLAP_INVALID)) break;
}
UPointer = (UPointer_t) (*PValue &amp; ~JLAP_INVALID); // mask and cast.
printf("User object pointer is 0x%lx\n", (Word_t) UPointer);
...
</PRE>
<P>
Note: This works because <I>malloc()</I> guarantees to return a pointer
with the least bit(s) == 0x0.
You must remove <B>JLAP_INVALID</B> before using the pointer.
</DL>
<!----------------->
<P>
<DT><A name="JLERR"><B>ERRORS:</B> See: </A><A href="Judy_3.htm#ERRORS">Judy_3.htm#ERRORS</A></DT>
<DD>
<!----------------->
<P>
<DT><B>EXAMPLE</B></DT>
<DD>
Read a series of index/value pairs from the standard input, store
in a JudyL array, and then print out in sorted order.
<P>
<PRE>
#include &lt;stdio.h&gt;
#include &lt;Judy.h&gt;
Word_t Index; // array index
Word_t Value; // array element value
Word_t * PValue; // pointer to array element value
int Rc_int; // return code
Pvoid_t PJLArray = (Pvoid_t) NULL; // initialize JudyL array
while (scanf("%lu %lu", &amp;Index, &amp;Value))
{
JLI(PValue, PJLArray, Index);
If (PValue == PJERR) goto process_malloc_failure;
*PValue = Value; // store new value
}
// Next, visit all the stored indexes in sorted order, first ascending,
// then descending, and delete each index during the descending pass.
Index = 0;
JLF(PValue, PJLArray, Index);
while (PValue != NULL)
{
printf("%lu %lu\n", Index, *PValue));
JLN(PValue, PJLArray, Index);
}
Index = -1;
JLL(PValue, PJLArray, Index);
while (PValue != NULL)
{
printf("%lu %lu\n", Index, *PValue));
JLD(Rc_int, PJLArray, Index);
if (Rc_int == JERR) goto process_malloc_failure;
JLP(PValue, PJLArray, Index);
}
</PRE>
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
Judy was invented by Doug Baskins and implemented by Hewlett-Packard.
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy_3.htm">Judy(3)</A>,
<A href="Judy1_3.htm">Judy1(3)</A>,
<A href="JudySL_3.htm">JudySL(3)</A>,
<A href="JudyHS_3.htm">JudyHS(3)</A>,
<BR>
<I>malloc()</I>,
<BR>
<A href="http://judy.sourceforge.net">
http://judy.sourceforge.net</A>,
for more information and Application Notes.
</BODY>
</HTML>

View File

@@ -1,248 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.5 $ $Source: /cvsroot/judy/doc/ext/JudyL_funcs_3.htm,v $ --->
<TITLE>JudyL_funcs(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">JudyL_funcs(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">JudyL_funcs(3)</TD>
</TR></TABLE>
<P>
<DL>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
JudyL functions -
C library for creating and accessing a dynamic array of words, using
any value of a word as an index
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<B><PRE>
PPvoid_t <A href="#JudyLIns" >JudyLIns</A>( PPvoid_t PPJLArray, Word_t Index, PJError_t PJError);
int <A href="#JudyLDel" >JudyLDel</A>( PPvoid_t PPJLArray, Word_t Index, PJError_t PJError);
PPvoid_t <A href="#JudyLGet" >JudyLGet</A>( Pcvoid_t PJLArray, Word_t Index, PJError_t PJError);
Word_t <A href="#JudyLCount" >JudyLCount</A>( Pcvoid_t PJLArray, Word_t Index1, Word_t Index2, PJError_t PJError);
PPvoid_t <A href="#JudyLByCount" >JudyLByCount</A>( Pcvoid_t PJLArray, Word_t Nth, Word_t * PIndex, PJError_t PJError);
Word_t <A href="#JudyLFreeArray ">JudyLFreeArray</A>( PPvoid_t PPJLArray, PJError_t PJError);
Word_t <A href="#JudyLMemUsed" >JudyLMemUsed</A>( Pcvoid_t PJLArray);
PPvoid_t <A href="#JudyLFirst" >JudyLFirst</A>( Pcvoid_t PJLArray, Word_t * PIndex, PJError_t PJError);
PPvoid_t <A href="#JudyLNext" >JudyLNext</A>( Pcvoid_t PJLArray, Word_t * PIndex, PJError_t PJError);
PPvoid_t <A href="#JudyLLast" >JudyLLast</A>( Pcvoid_t PJLArray, Word_t * PIndex, PJError_t PJError);
PPvoid_t <A href="#JudyLPrev" >JudyLPrev</A>( Pcvoid_t PJLArray, Word_t * PIndex, PJError_t PJError);
int <A href="#JudyLFirstEmpty">JudyLFirstEmpty</A>(Pcvoid_t PJLArray, Word_t * PIndex, PJError_t PJError);
int <A href="#JudyLNextEmpty" >JudyLNextEmpty</A>( Pcvoid_t PJLArray, Word_t * PIndex, PJError_t PJError);
int <A href="#JudyLLastEmpty" >JudyLLastEmpty</A>( Pcvoid_t PJLArray, Word_t * PIndex, PJError_t PJError);
int <A href="#JudyLPrevEmpty" >JudyLPrevEmpty</A>( Pcvoid_t PJLArray, Word_t * PIndex, PJError_t PJError);
</PRE></B>
<!----------------->
<P>
<DT><B>DESCRIPTION</B></DT>
<DD>
A macro equivalent exists for each function call.
Because the macro forms are sometimes faster and have a simpler error
handling interface than the equivalent functions,
they are the preferred way of calling the JudyL functions.
See <A href="JudyL_3.htm">JudyL(3)</A>
for more information.
The function call definitions are included here for completeness.
<P>
One of the difficulties in using the JudyL function calls lies in
determining whether to pass a pointer or the address of a pointer.
Since the functions that modify the JudyL array must also modify the
pointer to the JudyL array, you must pass the address of the pointer
rather than the pointer itself.
This often leads to hard-to-debug programmatic errors.
In practice, the macros allow the compiler to catch programming
errors when pointers instead of addresses of pointers are passed.
<P>
The JudyL function calls have an additional parameter beyond
those specified in the macro calls. This parameter is either a
pointer to an error structure, or <B>NULL</B> (in which case the
detailed error information is not returned).
<P>
In the following descriptions, the functions are described in
terms of how the macros use them (only in the case of
<B>#define JUDYERROR_NOTEST 1</B>). This is the suggested use
of the macros after your program has been fully debugged.
When the <B>JUDYERROR_NOTEST</B> macro is not specified,
an error structure is declared to store error information
returned from the JudyL functions when an error occurs.
<P>
Notice the placement of the <B>&amp;</B> in the different functions.
<P>
<DL>
<DT><A name="JudyLIns"><B>JudyLIns(&amp;PJLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLI(PValue, PJLArray, Index) \
PValue = JudyLIns(&amp;PJLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudyLDel"><B>JudyLDel(&amp;PJLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLD(Rc_int, PJLArray, Index) \
Rc_int = JudyLDel(&amp;PJLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudyLGet"><B>JudyLGet(PJLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLG(PValue, PJLArray, Index) \
PValue = JudyLGet(PJLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudyLCount"><B>JudyLCount(PJLArray, Index1, Index2, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLC(Rc_word, PJLArray, Index1, Index2) \
Rc_word = JudyLCount(PJLArray, Index1, Index2, PJE0)
</PRE>
<P>
<DT><A name="JudyLByCount"><B>JudyLByCount(PJLArray, Nth, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLBC(PValue, PJLArray, Nth, Index) \
PValue = JudyLByCount(PJLArray, Nth, &amp;Index, PJE0)
</PRE>
<P>
<DT><A name="JudyLFreeArray"><B>JudyLFreeArray(&amp;PJLArray, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLFA(Rc_word, PJLArray) \
Rc_word = JudyLFreeArray(&amp;PJLArray, PJE0)
</PRE>
<P>
<DT><A name="JudyLMemUsed"><B>JudyLMemUsed(PJLArray)</B></A></DT>
<DD>
<PRE>
#define JLMU(Rc_word, PJLArray) \
Rc_word = JudyLMemUsed(PJLArray)
</PRE>
<P>
<DT><A name="JudyLFirst"><B>JudyLFirst(PJLArray, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLF(PValue, PJLArray, Index) \
PValue = JudyLFirst(PJLArray, &amp;Index, PJEO)
</PRE>
<P>
<DT><A name="JudyLNext"><B>JudyLNext(PJLArray, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLN(PValue, PJLArray, Index) \
PValue = JudyLNext(PJLArray, &amp;Index, PJEO)
</PRE>
<P>
<DT><A name="JudyLLast"><B>JudyLLast(PJLArray, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLL(PValue, PJLArray, Index) \
PValue = JudyLLast(PJLArray, &amp;Index, PJEO)
</PRE>
<P>
<DT><A name="JudyLPrev"><B>JudyLPrev(PJLArray, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLP(PValue, PJLArray, Index) \
PValue = JudyLPrev(PJLArray, &amp;Index, PJEO)
</PRE>
<P>
<DT><A name="JudyLFirstEmpty"><B>JudyLFirstEmpty(PJLArray, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLFE(Rc_int, PJLArray, Index) \
Rc_int = JudyLFirstEmpty(PJLArray, &amp;Index, PJEO)
</PRE>
<P>
<DT><A name="JudyLNextEmpty"><B>JudyLNextEmpty(PJLArray, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLNE(Rc_int, PJLArray, Index) \
Rc_int = JudyLNextEmpty(PJLArray, &amp;Index, PJEO)
</PRE>
<P>
<DT><A name="JudyLLastEmpty"><B>JudyLLastEmpty(PJLArray, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLLE(Rc_int, PJLArray, Index) \
Rc_int = JudyLLastEmpty(PJLArray, &amp;Index, PJEO)
</PRE>
<P>
<DT><A name="JudyLPrevEmpty"><B>JudyLPrevEmpty(PJLArray, &amp;Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JLPE(Rc_int, PJLArray, Index) \
Rc_int = JudyLPrevEmpty(PJLArray, &amp;Index, PJEO)
</PRE>
</DL>
<P>
Definitions for all the Judy functions, the types
<B>Pvoid_t</B>,
<B>Pcvoid_t</B>,
<B>PPvoid_t</B>,
<B>Word_t</B>,
<B>JError_t</B>,
and
<B>PJError_t</B>,
the constants
<B>NULL</B>,
<B>JU_ERRNO_*</B>,
<B>JERR</B>,
<B>PPJERR</B>,
and
<B>PJE0</B>,
are provided in the <B>Judy.h</B> header file
(/usr/include/Judy.h).
<B>Note</B>: Callers should define JudyL arrays as type <B>Pvoid_t</B>,
which can be passed by value to functions that take
<B>Pcvoid_t</B> (constant <B>Pvoid_t</B>),
and also by address to functions that take <B>PPvoid_t</B>.
<P>
The return type from most <B>JudyL</B> functions is <B>PPvoid_t</B> so
that the values stored in the array can be pointers to other objects,
which is a typical usage, or cast to a <B>Word_t *</B> when a pointer
to a <B>Value</B> is required instead of a pointer to a pointer.
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
Judy was invented by Doug Baskins and implemented by Hewlett-Packard.
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy_3.htm">Judy(3)</A>,
<A href="Judy1_3.htm">Judy1(3)</A>,
<A href="JudyL_3.htm">JudyL(3)</A>,
<A href="JudySL_3.htm">JudySL(3)</A>,
<A href="JudyHS_3.htm">JudyHS(3)</A>,
<BR>
<I>malloc()</I>,
<BR>
the Judy website,
<A href="http://judy.sourceforge.net">
http://judy.sourceforge.net</A>,
for more information and Application Notes.
</DL>
</BODY>
</HTML>

View File

@@ -1,246 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.43 $ $Source: /cvsroot/judy/doc/ext/JudySL_3.htm,v $ --->
<TITLE>JudySL(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">JudySL(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">JudySL(3)</TD>
</TR></TABLE>
<P>
<DL>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
JudySL macros -
C library for creating and accessing a dynamic array, using
a null-terminated string as an <B>Index</B> (associative array)
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<B><PRE>
cc [flags] <I>sourcefiles</I> -lJudy
#include &lt;Judy.h&gt;
#define MAXLINELEN 1000000 // define maximum string length
Word_t * PValue; // JudySL array element
uint8_t Index[MAXLINELEN]; // string
int Rc_int; // return value
Word_t Rc_word; // full word return value
Pvoid_t PJSLArray = (Pvoid_t) NULL; // initialize JudySL array
<A href="#JSLI" >JSLI</A>( PValue, PJSLArray, Index); // <A href="JudySL_funcs_3.htm#JudySLIns">JudySLIns()</A>
<A href="#JSLD" >JSLD</A>( Rc_int, PJSLArray, Index); // <A href="JudySL_funcs_3.htm#JudySLDel">JudySLDel()</A>
<A href="#JSLG" >JSLG</A>( PValue, PJSLArray, Index); // <A href="JudySL_funcs_3.htm#JudySLGet">JudySLGet()</A>
<A href="#JSLFA">JSLFA</A>(Rc_word, PJSLArray); // <A href="JudySL_funcs_3.htm#JudySLFreeArray">JudySLFreeArray()</A>
<A href="#JSLF" >JSLF</A>( PValue, PJSLArray, Index); // <A href="JudySL_funcs_3.htm#JudySLFirst">JudySLFirst()</A>
<A href="#JSLN" >JSLN</A>( PValue, PJSLArray, Index); // <A href="JudySL_funcs_3.htm#JudySLNext">JudySLNext()</A>
<A href="#JSLL" >JSLL</A>( PValue, PJSLArray, Index); // <A href="JudySL_funcs_3.htm#JudySLLast">JudySLLast()</A>
<A href="#JSLP" >JSLP</A>( PValue, PJSLArray, Index); // <A href="JudySL_funcs_3.htm#JudySLPrev">JudySLPrev()</A>
</PRE></B>
<!----------------->
<P>
<DT><B>DESCRIPTION</B></DT>
<DD>
A JudySL array is the equivalent of a sorted set of strings, each associated
with a <B>Value</B> (word).
A <B>Value</B> is addressed by an <B>Index</B> (key), which is a null-terminated
character string of any length.
Memory to support the array is allocated as index/value pairs are inserted,
and released as index/value pairs are deleted.
This is a form of associative array, where array elements are also sorted
lexicographically (case-sensitive) by indexes.
This could be thought of as
<P><PRE>
void * JudySLArray["Toto, I don't think we're in Kansas any more"];
</PRE>
<P>
A JudySL array is allocated with a <B>NULL</B> pointer
<PRE>
Pvoid_t PJSLArray = (Pvoid_t) NULL;
</PRE>
As with an ordinary array, there are no duplicate indexes (strings)
in a JudySL array.
<P>
Using the macros described here, rather than the
<A href="JudySL_funcs_3.htm">JudySL function calls</A>,
the default error handling sends a
message to the standard error and terminates the program with
<B>exit(1)</B>.
<P>
<DT><A name="JSLI"><B>JSLI(PValue, PJSLArray, Index)</B></A> // <A href="JudySL_funcs_3.htm#JudySLIns">JudySLIns()</A></DT>
<DD>
Insert an <B>Index</B> string and <B>Value</B> in the JudySL array <B>PJSLArray</B>.
If the <B>Index</B> is successfully inserted,
the <B>Value</B> is initialized to 0. If the <B>Index</B> was already present,
the <B>Value</B> is not modified.
<P>
Return <B>PValue</B> pointing to <B>Index</B>'s <B>Value</B>.
Your program must use this pointer to modify the <B>Value</B>,
for example:
<PRE>
*PValue = 1234;
</PRE>
<P>
<B>Note</B>:
<B>JSLI()</B> and <B>JSLD</B> reorganize the JudySL array.
Therefore, pointers returned from previous <B>JudySL</B> calls become
invalid and must be reacquired.
<P>
<DT><A name="JSLD"><B>JSLD(Rc_int, PJSLArray, Index)</B></A> // <A href="JudySL_funcs_3.htm#JudySLDel">JudySLDel()</A></DT>
<DD>
Delete the specified <B>Index</B>/<B>Value</B> pair (array element) from the
JudySL array.
<P>
Return <B>Rc_int</B> set to 1 if successful.
array and it was previously inserted.
Return <B>Rc_int</B> set to 0 if <B>Index</B> was not present.
<P>
<DT><A name="JSLG"><B>JSLG(PValue, PJSLArray, Index)</B></A> // <A href="JudySL_funcs_3.htm#JudySLGet">JudySLGet()</A></DT>
<DD>
Get the pointer to <B>Index</B>'s <B>Value</B>.
<P>
Return <B>PValue</B> pointing to <B>Index</B>'s <B>Value</B>.
Return <B>PValue</B> set to <B>NULL</B> if the <B>Index</B> was not present.
<P>
<DT><A name="JSLFA"><B>JSLFA(Rc_word, PJSLArray)</B></A> // <A href="JudySL_funcs_3.htm#JudySLFreeArray">JudySLFreeArray()</A></DT>
<DD>
Given a pointer to a JudySL array (<B>PJSLArray</B>), free the entire array (much faster
than using a <B>JSLN()</B>, <B>JSLD()</B> loop.)
<P>
Return <B>Rc_word</B> set to the number of bytes freed and <B>PJSLArray</B> set to NULL.
<P>
<DT><B>JudySL Search Functions</B></DT>
<DD>
The JudySL search functions allow you to search for indexes in the array.
You may search inclusively or exclusively,
in either forward or reverse directions.
<P>
If successful,
<B>Index</B> is returned set to the found index, and
<B>PValue</B> is returned set to a pointer to <B>Index</B>'s <B>Value</B>.
If unsuccessful,
<B>PValue</B> is returned set to <B>NULL</B>,
and <B>Index</B> contains no useful information.
<B>PValue</B> must be tested for non-<B>NULL</B> prior
to using <B>Index</B>,
since a search failure is possible.
<P>
<B>Note</B>:
To accomodate all possible returns, the <B>Index</B> buffer must be
at least as large
as the largest string stored in the array.
<P>
<DT><A name="JSLF"><B>JSLF(PValue, PJSLArray, Index)</B></A> // <A href="JudySL_funcs_3.htm#JudySLFirst">JudySLFirst()</A></DT>
<DD>
Search (inclusive) for the first index present that is equal to or greater than the
passed <B>Index</B> string.
(Start with a null string to find the first index in the array.)
<B>JSLF()</B> is typically used to <I>begin</I> a sorted-order scan of
the valid indexes in a JudySL array.
<PRE>
uint8_t Index[MAXLINELEN];
strcpy (Index, "");
JSLF(PValue, PJSLArray, Index);
</PRE>
<P>
<DT><A name="JSLN"><B>JSLN(PValue, PJSLArray, Index)</B></A> // <A href="JudySL_funcs_3.htm#JudySLNext">JudySLNext()</A></DT>
<DD>
Search (exclusive) for the next index present that is greater than the passed
<B>Index</B> string.
<B>JSLN()</B> is typically used to <I>continue</I> a sorted-order scan of
the valid indexes in a JudySL array, or to locate a "neighbor" of a given
index.
<P>
<DT><A name="JSLL"><B>JSLL(PValue, PJSLArray, Index)</B></A> // <A href="JudySL_funcs_3.htm#JudySLLast">JudySLLast()</A></DT>
<DD>
Search (inclusive) for the last index present that is equal to or less
than the passed <B>Index</B> string.
(Start with a maximum-valued string to look up the last index in the array,
such as a max-length string of 0xff bytes.)
<B>JSLL()</B> is typically used to <I>begin</I> a reverse-sorted-order
scan of the valid indexes in a JudySL array.
<P>
<DT><A name="JSLP"><B>JSLP(PValue, PJSLArray, Index)</B></A> // <A href="JudySL_funcs_3.htm#JudySLPrev">JudySLPrev()</A></DT>
<DD>
Search (exclusive) for the previous index present that is less than the
passed <B>Index</B> string.
<B>JSLP()</B> is typically used to <I>continue</I> a reverse-sorted-order
scan of the valid indexes in a JudySL array, or to locate a "neighbor" of
a given index.
<!----------------->
<P>
<DT><A name="JSLERR"><B>ERRORS:</B> See: </A><A href="Judy_3.htm#ERRORS">Judy_3.htm#ERRORS</A></DT>
<DD>
<!----------------->
<P>
<DT><B>EXAMPLE</B> of a string sort routine</DT>
<P><PRE>
#include &lt;stdio.h&gt;
#include &lt;Judy.h&gt;
#define MAXLINE 1000000 // max string (line) length
uint8_t Index[MAXLINE]; // string to insert
int // Usage: JudySort &lt; file_to_sort
main()
{
Pvoid_t PJArray = (PWord_t)NULL; // Judy array.
PWord_t PValue; // Judy array element.
Word_t Bytes; // size of JudySL array.
while (fgets(Index, MAXLINE, stdin) != (char *)NULL)
{
JSLI(PValue, PJArray, Index); // store string into array
if (PValue == PJERR) // if out of memory?
{ // so do something
printf("Malloc failed -- get more ram\n");
exit(1);
}
++(*PValue); // count instances of string
}
Index[0] = '\0'; // start with smallest string.
JSLF(PValue, PJArray, Index); // get first string
while (PValue != NULL)
{
while ((*PValue)--) // print duplicates
printf("%s", Index);
JSLN(PValue, PJArray, Index); // get next string
}
JSLFA(Bytes, PJArray); // free array
fprintf(stderr, "The JudySL array used %lu bytes of memory\n", Bytes);
return (0);
}
</PRE>
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
Judy was invented by Doug Baskins and implemented by Hewlett-Packard.
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy_3.htm">Judy(3)</A>,
<A href="Judy1_3.htm">Judy1(3)</A>,
<A href="JudyL_3.htm">JudyL(3)</A>,
<A href="JudyHS_3.htm">JudyHS(3)</A>,
<BR>
<I>malloc()</I>,
<BR>
the Judy website,
<A href="http://judy.sourceforge.net">
http://judy.sourceforge.net</A>,
for further information and Application Notes.
</DL>
</BODY>
</HTML>

View File

@@ -1,186 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.5 $ $Source: /cvsroot/judy/doc/ext/JudySL_funcs_3.htm,v $ --->
<TITLE>JudySL_funcs(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">JudySL_funcs(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">JudySL_funcs(3)</TD>
</TR></TABLE>
<P>
<DL>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
JudySL functions -
C library for creating and accessing a dynamic array, using
a null-terminated string as an index (associative array)
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<B><PRE>
PPvoid_t <A href="#JudySLIns" >JudySLIns</A>( PPvoid_t PPJSLArray, const uint8_t * Index, PJError_t PJError);
int <A href="#JudySLDel" >JudySLDel</A>( PPvoid_t PPJSLArray, const uint8_t * Index, PJError_t PJError);
PPvoid_t <A href="#JudySLGet" >JudySLGet</A>( Pcvoid_t PJSLArray, const uint8_t * Index, PJError_t PJError);
Word_t <A href="#JudySLFreeArray">JudySLFreeArray</A>(PPvoid_t PPJSLArray, PJError_t PJError);
PPvoid_t <A href="#JudySLFirst" >JudySLFirst</A>( Pcvoid_t PJSLArray, uint8_t * Index, PJError_t PJError);
PPvoid_t <A href="#JudySLNext" >JudySLNext</A>( Pcvoid_t PJSLArray, uint8_t * Index, PJError_t PJError);
PPvoid_t <A href="#JudySLLast" >JudySLLast</A>( Pcvoid_t PJSLArray, uint8_t * Index, PJError_t PJError);
PPvoid_t <A href="#JudySLPrev" >JudySLPrev</A>( Pcvoid_t PJSLArray, uint8_t * Index, PJError_t PJError);
</PRE></B>
<!----------------->
<P>
<DT><B>DESCRIPTION</B></DT>
<DD>
A macro equivalent exists for each function call.
Because the macro forms are sometimes faster and have a simpler error
handling interface than the equivalent functions,
they are the preferred way of calling the JudySL functions.
See <A href="JudySL_3.htm">JudySL(3)</A>
for more information.
The function call definitions are included here for completeness.
<P>
One of the difficulties in using the JudySL function calls lies in
determining whether to pass a pointer or the address of a pointer.
Since the functions that modify the JudySL array must also modify the
pointer to the JudySL array, you must pass the address of the pointer
rather than the pointer itself.
This often leads to hard-to-debug programmatic errors.
In practice, the macros allow the compiler to catch programming
errors when pointers instead of addresses of pointers are passed.
<P>
The JudySL function calls have an additional parameter beyond
those specified in the macro calls. This parameter is either a
pointer to an error structure, or <B>NULL</B> (in which case the
detailed error information is not returned).
<P>
In the following descriptions, the functions are described in
terms of how the macros use them (only in the case of
<B>#define JUDYERROR_NOTEST 1</B>). This is the suggested use
of the macros after your program has been fully debugged.
When the <B>JUDYERROR_NOTEST</B> macro is not specified,
an error structure is declared to store error information
returned from the JudySL functions when an error occurs.
<P>
Notice the placement of the <B>&amp;</B> in the different functions.
<P>
<DL>
<DT><A name="JudySLIns"><B>JudySLIns(&amp;PJSLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JSLI(PValue, PJSLArray, Index) \
PValue = JudyLIns(&amp;PJSLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudySLDel"><B>JudySLDel(&amp;PJSLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JSLD(Rc_int, PJSLArray, Index) \
Rc_int = JudySLDel(&amp;PJSLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudySLGet"><B>JudySLGet(PJSLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JSLG(PValue, PJSLArray, Index) \
PValue = JudySLIns(PJSLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudySLFreeArray"><B>JudySLFreeArray(&amp;PJSLArray, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JSLFA(Rc_word, PJSLArray) \
Rc_word = JudySLFreeArray(&amp;PJSLArray, PJE0)
</PRE>
<P>
<DT><A name="JudySLFirst"><B>JudySLFirst(PJSLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JSLF(PValue, PJSLArray, Index) \
PValue = JudySLFirst(PJSLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudySLNext"><B>JudySLNext(PJSLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JSLN(PValue, PJSLArray, Index) \
PValue = JudySLNext(PJSLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudySLLast"><B>JudySLLast(PJSLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JSLL(PValue, PJSLArray, Index) \
PValue = JudySLLast(PJSLArray, Index, PJE0)
</PRE>
<P>
<DT><A name="JudySLPrev"><B>JudySLPrev(PJSLArray, Index, &amp;JError)</B></A></DT>
<DD>
<PRE>
#define JSLP(PValue, PJSLArray, Index) \
PValue = JudySLPrev(PJSLArray, Index, PJE0)
</PRE>
</DL>
<P>
Definitions for all the Judy functions, the types
<B>Pvoid_t</B>,
<B>Pcvoid_t</B>,
<B>PPvoid_t</B>,
<B>Word_t </B>,
<B>JError_t</B>,
and
<B>PJError_t</B>,
the constants
<B>NULL</B>,
<B>JU_ERRNO_*</B>,
<B>JERR</B>,
<B>PPJERR</B>,
and
<B>PJE0</B>
are provided in the <B>Judy.h</B> header file
(/usr/include/Judy.h).
<B>Note</B>: Callers should define JudySL arrays as type <B>Pvoid_t</B>,
which can be passed by value to functions that take
<B>Pcvoid_t</B> (constant <B>Pvoid_t</B>),
and also by address to functions that take <B>PPvoid_t</B>.
<P>
The return type from most <B>JudySL</B> functions is <B>PPvoid_t</B> so
that the values stored in the array can be pointers to other objects,
which is a typical usage, or cast to a <B>Word_t *</B> when a pointer
to a value is required instead of a pointer to a pointer.
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
Judy was invented by Doug Baskins and implemented by Hewlett-Packard.
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy_3.htm">Judy(3)</A>,
<A href="Judy1_3.htm">Judy1(3)</A>,
<A href="JudyL_3.htm">JudyL(3)</A>,
<A href="JudySL_3.htm">JudySL(3)</A>,
<A href="JudyHS_3.htm">JudyHS(3)</A>,
<BR>
<I>malloc()</I>,
<BR>
the Judy website,
<A href="http://judy.sourceforge.net">
http://judy.sourceforge.net</A>,
for more information and Application Notes.
</DL>
</BODY>
</HTML>

View File

@@ -1,283 +0,0 @@
<HTML>
<HEAD>
<!-- @(#) $Revision: 4.36 $ $Source: /cvsroot/judy/doc/ext/Judy_3.htm,v $ --->
<TITLE>Judy(3)</TITLE>
</HEAD>
<BODY>
<TABLE border=0 width="100%"><TR>
<TD width="40%" align="left">Judy(3)</TD>
<TD width="10%" align="center"> </TD>
<TD width="40%" align="right">Judy(3)</TD>
</TR></TABLE>
<P>
<!----------------->
<DT><B>NAME</B></DT>
<DD>
Judy arrays -
C library functions for creating and accessing dynamic arrays
</DD>
<!----------------->
<P>
<DT><B>SYNOPSIS</B></DT>
<DD>
<PRE>
<A href="Judy1_3.htm">Judy1</A> - maps an <B>Index</B> (word) to a <B>bit</B>
<A href="JudyL_3.htm">JudyL</A> - maps an <B>Index</B> (word) to a <B>Value</B> (word/pointer)
<A href="JudySL_3.htm">JudySL</A> - maps an <B>Index</B> (null terminated string) to a <B>Value</B>
<A href="JudyHS_3.htm">JudyHS</A> - maps an <B>Index</B> (array-of-bytes) of <B>Length</B> to a <B>Value</B>
</PRE>
<!----------------->
<P>
<DT><B>DESCRIPTION</B></DT>
<DD>
The Judy family of functions supports fully dynamic arrays. These
arrays may be indexed by a 32- or 64-bit word (depending on processor
word size), a null terminated string or an array-of-bytes plus length.
A dynamic array (sparsely populated) can also be thought of as a
<I>mapping function</I> or <I>associative memory</I>.
<P>
A <B>Word_t</B> is a <I>typedef unsigned long int </I> in <B>Judy.h</B>
and must be the same size as <I>sizeof(void *)</I> I.E. a pointer.
<P>
<A href="Judy1_3.htm">Judy1</A> functions: <B>Index</B> is a
<B>Word_t</B> and <B>Value</B> is just a <B>bit</B> or simply
a flag that <B>Index</B> is present or missing from the array.
This can be thought of as a huge bitmap.
<P>
<A href="JudyL_3.htm">JudyL</A> functions: <B>Index</B> is a
<B>Word_t</B> and <B>Value</B> is a <B>Word_t</B>. This makes
<B>JudyL</B> a pure word-to-word/pointer mapper. <B>JudySL</B> and
<B>JudyHL</B> are based on this property of <B>JudyL</B>.
<P>
<A href="JudySL_3.htm">JudySL</A> functions: <B>Index</B> is a
null-terminated string and <B>Value</B> is a <B>Word_t</B>.
<P>
<A href="JudyHS_3.htm">JudyHS</A> functions: <B>Index</B> is an
array-of-bytes of length: <B>Length</B>. <B>Value</B> is a
<B>Word_t</B>. This new addition (May 2004) to Judy is a hybird using
the best features of hashing and Judy methods. The author believes
<B>JudyHS</B> is a good replacement for a hashing method when resizing
the hash table is done during population growth. A correctly tuned hash
method with a <B>static</B> hash table size and population is unbeatable
for speed. However, <B>JudyHS</B> will perform better than a hashing
method with smaller and larger populations than the optimum hash table
size. <B>JudyHS</B> does not have a degenerate performance case where
knowledge of the hash algorithm can be exploited. (I.E. JudyHS does
not use a linked list to handle hash collisions, it uses a tree of
<B>JudyL</B> arrays and a virtual hash table size of 4 billion).
<P>
Judy arrays are both <B>speed-</B> and <B>memory-efficient</B>, with no
tuning or configuration required, across a wide range of index set types
(sequential, periodic, clustered, random). Judy's speed and memory
usage are typically better than other data storage models such as
skiplists, linked lists, binary, ternary, b-trees, or even hashing, and
improves with very large data sets.
<P>
A Judy array is created merely by defining a null pointer and then
storing (inserting) the first element into the array under that pointer.
The memory used by a Judy array is nearly proportional to the population
(number of elements).
<P>
Judy has two Application Program Interfaces (APIs): a C macro
interface, and a function call interface. Because the macro forms are
sometimes faster and have a simpler error handling interface than the
equivalent functions, they are the preferred way of using the Judy
functions.
<P>
Since an initial (empty) Judy array is represented by a null pointer, it
is possible to construct an array of Judy arrays. In other words, a
Judy array's <B>Values</B> (except Judy1) can be pointers to other Judy
arrays. This makes it very simple to construct an array with an
arbitrary number of dimensions or <B>Index</B> sizes. (JudySL and
JudyHS are implemented using JudyL this way).
<!----------------->
<P>
<DT><B>A 10 MINUTE TECHNICAL DESCRIPTION</B></DT>
<DD>
may be found at
<A href="http://judy.sourceforge.net/downloads/10minutes.htm">http://judy.sourceforge.net/downloads/10minutes.htm</A>
<!----------------->
<P>
<DT><B>A 3 HOUR TECHNICAL DESCRIPTION</B> (out of date and a bit corny)</DT>
<DD>
may be found at
<A href="http://judy.sourceforge.net/application/shop_interm.pdf">http://judy.sourceforge.net/application/shop_interm.pdf</A>
<!----------------->
<P>
<DT>
<A name="DOWNLOADS"> <B>DOWNLOADS</B></A></DT>
<DD>
Judy source downloads are available at
<A href="http://sourceforge.net/projects/judy">http://sourceforge.net/projects/judy</A><BR>
Binarys may be built and installed in a minute or two
after downloading
<P>
For versions including more platforms and/or new features see:
<A href="http://judy.sourceforge.net/downloads/">http://judy.sourceforge.net/downloads/</A>
<!----------------->
<P>
<DT><B>AUTHOR</B></DT>
<DD>
Judy was invented by Doug Baskins (dougbaskins .AT, yahoo.com) and
implemented by Hewlett-Packard. (Note: Judy is named for the
inventor's sister, after discarding many proposed names.)
<!----------------->
<P>
<DT>
<A name="FILES">
<B>FILES</B></A></DT>
<DD>
Locations of interest include:
<BR>
<A href="http://sourceforge.net/projects/judy">http://sourceforge.net/projects/judy</A>
-- project downloads<BR>
<A href="file:/usr/share/doc/Judy/">file:/usr/share/doc/Judy/</A>
-- for HTML version of man pages.<BR>
/usr/share/doc/Judy/demo/ -- demonstration program source files.<BR>
<BR>
The author attempted to write interesting application notes using
advanced features of Judy. They may be found at
<A href="http://judy.sourceforge.net/application/">"http://judy.sourceforge.net/application/</A>
(Some may be out of date).
<!----------------->
<P>
<DT><A name="ERRORS"><B>ERRORS</B></A></DT>
<DD>
A lot of thought (and time) went into making error handling in Judy
simple, while maintaining flexibility and capability. Error handling is
a very boring subject even to write about. So read this short section
and use the recommended second method. It generates the fastest code,
uses the least amount of memory and requires you to write extra code
only for insert/deletes functions. Also it is compatible with the other
two methods. This method is for production code that may want to handle
<I>malloc()</I> fails differently than the Judy default. If the Judy
default method of handling <I>malloc()</I> fails are OK, then use the
first method.
<P>
There are <I>two (2)</I> categories of Judy error returns, (or for any dynamic ADT):
<P>
1) User programming errors (bugs) such as memory corruption or
invalid pointers.
<BR>
2) Out-of-memory (<I>malloc()</I> failure) with <B>I</B>nsert
(<B>S</B>et) or <B>D</B>elete (<B>U</B>nset) when modifying a Judy
array. Not all calls to insert and delete call <I>malloc()</I>, so they
may succeed even when a call to <I>malloc()</I> would fail.
<BR>
<P>
There are roughly <I>three (3)</I> methods of handling errors when using
the macros:
<DL>
<P>
<DT><B>1) Default Error Handling Method</B></DT>
<DD>
The default is to print error messages to <B>stderr</B>, for example:
<P>
<PRE>
File 'YourCfile.c', line 1234: JudyLIns(), JU_ERRNO_* == 2, ID == 321
</PRE>
This indicates that an error occurred in the <B>JudyLIns()</B> function
at line 321. Line 1234 is the line in 'YourCfile.c' where the
<B>JLI()</B> call failed. JU_ERRNO_* == 2 is equal to JU_ERRNO_NOMEM
(as defined in the <B>Judy.h</B> file). The ID number indicates the
source line number in the function where the error originated. Your
program then terminates with an <I>exit(1);</I>. By default, both
categories of Judy error returns are printed this way. (The 'ID == 321'
is for die hards that want more detail or for debugging Judy itself.)
<BR>
<P>
<DT><B>2) Disable Macro Error Handling</B> </DT>
<DD>
When your program is "bug free", the only errors returned should be
<I>malloc()</I> failures. Therefore all error returns can be treated as
a <I>malloc()</I> failure. By using the below <B>#define</B>, all
error testing and printing is turned off. Additional code needs to be
added to the code that can have <I>malloc()</I> failures. Judy was
designed to leave the same data in the array before the call if a
<I>malloc()</I> fail occurs. (During testing of Judy, we found very few
<I>malloc()</I>/OS's that were bug free after a <I>malloc()</I> failure.
Sometimes it took weeks to discover because most systems go into a
paging frenzy before running out of memory).
<PRE>
#define JUDYERROR_NOTEST 1
</PRE>
(in your program code), or
<PRE>
cc -DJUDYERROR_NOTEST <I>sourcefile</I> -lJudy
</PRE>
(on your command line).
<PRE>
// This is an example of how to program using method two (2).
JLI(PValue, PLArray, Index);
if (PValue == PJERR) goto out_of_memory_handling;
...
JLD(RC_int, PLArray, Index);
if (RC_int == JERR) goto out_of_memory_handling;
...
J1S(RC_int, P1Array, Index);
if (RC_int == JERR) goto out_of_memory_handling;
...
J1U(RC_int, P1Array, Index);
if (RC_int == JERR) goto out_of_memory_handling;
...
</PRE>
Note: Without 'JUDYERROR_NOTEST' defined, the 'goto
out_of_memory_handling' will never be executed and will be optimized out
by the compiler. The default method will be used -- Macro will print
error information if an error occurs as explained above.
<P>
With 'JUDYERROR_NOTEST' defined, the 'goto out_of_memory_handling' will
be executed when an error occurs -- which should only happen when
<I>malloc()</I> fails.
<DT><B>3) User-Specified JUDYERROR() Macro Method</B> </DT>
<DD>
The <B>JUDYERROR()</B> macro (in <B>Judy.h</B>) provides flexibility for
handling error returns as needed to suit your program while still using
the Judy array macros instead of function calls. You can use a
different <B>JUDYERROR()</B> macro to suit your needs. The following
example is a possible alternative to the default. It is used to
distinguish between the two types of errors (described above), and
explicitly test for the remaining JU_ERRNO_NOMEM errors possible in your
program.
<P>
<PRE>
// This is an example of Judy macro API to continue when out of memory
// and print and exit(1) when any other error occurs.
#ifndef JUDYERROR_NOTEST
#include &lt;stdio.h&gt; // needed for fprintf()
// This is the macro that the Judy macro APIs use for return codes of -1:
#define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) \
{ \
if ((JudyErrno) != JU_ERRNO_NOMEM) /* ! a malloc() failure */ \
{ \
(void) fprintf(stderr, "File '%s', line %d: %s(), " \
"JU_ERRNO_* == %d, ID == %d\n", \
CallerFile, CallerLine, \
JudyFunc, JudyErrno, JudyErrID); \
exit(1); \
} \
}
#endif // JUDYERROR_NOTEST not defined
<BR>
</PRE>
This error handling macro must be included before the <B>#include &lt;Judy.h&gt;</B>
statement in your program.
</DL>
<!----------------->
<P>
<DT><B>SEE ALSO</B></DT>
<DD>
<A href="Judy1_3.htm">Judy1(3)</A>,
<A href="JudyL_3.htm">JudyL(3)</A>,
<A href="JudySL_3.htm">JudySL(3)</A>,
<A href="JudyHS_3.htm">JudyHS(3)</A>
</BODY>
</HTML>

View File

@@ -1,20 +0,0 @@
# @(#) $Revision: 4.11 $
Judy_3.htm the Judy(3) overview manual entry in HTML format;
normally placed where a web browser can read it
Judy1_3.htm describes the Judy1*() macros
Judy1_funcs_3.htm describes the Judy1*() functions
JudyL_3.htm describes the JudyL*() macros
JudyL_funcs_3.htm describes the JudyL*() functions
JudySL_3.htm describes the JudySL*() macros
JudySL_funcs_3.htm describes the JudySL*() functions
JudyHS_3.htm describes the JudyHS*() macros
JudyHS_funcs_3.htm describes the JudyHS*() functions
# Note: The library package README file comes from the following file, but the
# hierarchy of example sources package README files come from each
# corresponding directory:
README_deliver packaged with other Judy delivered files, renamed to just
"README" in that context

View File

@@ -1,20 +0,0 @@
# @(#) $Revision: 4.11 $
Judy_3.htm the Judy(3) overview manual entry in HTML format;
normally placed where a web browser can read it
Judy1_3.htm describes the Judy1*() macros
Judy1_funcs_3.htm describes the Judy1*() functions
JudyL_3.htm describes the JudyL*() macros
JudyL_funcs_3.htm describes the JudyL*() functions
JudySL_3.htm describes the JudySL*() macros
JudySL_funcs_3.htm describes the JudySL*() functions
JudyHS_3.htm describes the JudyHS*() macros
JudyHS_funcs_3.htm describes the JudyHS*() functions
# Note: The library package README file comes from the following file, but the
# hierarchy of example sources package README files come from each
# corresponding directory:
README_deliver packaged with other Judy delivered files, renamed to just
"README" in that context

View File

@@ -1,190 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML EXPERIMENTAL 970324//EN">
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="Adobe FrameMaker 5.5/HTML Export Filter">
<LINK REL="STYLESHEET" HREF="10minutes.css">
<TITLE> A 10-MINUTE DESCRIPTION OF HOW JUDY ARRAYS WORK AND WHY THEY ARE SO FAST</TITLE></HEAD>
<BODY BGCOLOR="#ffffff">
<DIV>
<H1 CLASS="Title">
<A NAME="pgfId=997347">
</A>
A 10-MINUTE DESCRIPTION OF HOW JUDY ARRAYS WORK AND WHY THEY ARE SO FAST</H1>
<P CLASS="Body">
<A NAME="pgfId=997353">
</A>
By Doug Baskins, doug@sourcejudy.com</P>
<P CLASS="Body">
<A NAME="pgfId=997395">
</A>
October 16, 2001, Revised July 2002</P>
<P CLASS="Body">
<A NAME="pgfId=997492">
</A>
As the inventor of the Judy algorithm I've been asked repeatedly, &quot;What makes Judy so fast?&quot; The answer is not simple, but finally I can share all of the details. (In June 2002, Judy was opened sourced with a LGPL license and hosted at
<A HREF="http://sourceforge.net/projects/judy">http://sourceforge.net/projects/judy</A>
Let's see if I can give you a good understanding in 10 minutes. (The Judy data structures are very well described in another paper, the
<A HREF="http://www.sourcejudy.com/application/shop_interm.pdf">Judy Shop Manual</A>
, but it took me about three hours to read!)</P>
<P CLASS="Body">
<A NAME="pgfId=997354">
</A>
A Judy tree is generally faster than and uses less memory than contemporary forms of trees such as binary (AVL) trees, b-trees, and skip-lists. When used in the &quot;Judy Scalable Hashing&quot; configuration, Judy is generally faster then a hashing method at all populations. (See also
<A HREF="http://www.sourcejudy.com/application/">http://www.sourcejudy.com/application/</A>
Judy_hashing.</P>
<P CLASS="Body">
<A NAME="pgfId=997488">
</A>
<EM CLASS="bold">
Expanse</EM>
, <EM CLASS="bold">
population</EM>
, and <EM CLASS="bold">
density</EM>
are not commonly used terms in tree search literature, so let's define them here:</P>
<UL>
<LI CLASS="Bulleted">
<A NAME="pgfId=997357">
</A>
<EM CLASS="bold">
Expanse</EM>
is a range of possible keys, such as: 256..511</LI>
<LI CLASS="Bulleted">
<A NAME="pgfId=997358">
</A>
<EM CLASS="bold">
Population</EM>
is the count of keys contained in an expanse, such as, 260, 300, 499, 500 = 4.</LI>
<LI CLASS="Bulleted">
<A NAME="pgfId=997359">
</A>
<EM CLASS="bold">
Density</EM>
is used to describe the sparseness of an expanse of keys; density = population / expanse. A density of 1.0 means that all possible keys are set or valid in that expanse.</LI>
</UL>
<P CLASS="Body">
<A NAME="pgfId=997360">
</A>
<EM CLASS="bold">
Node</EM>
and <EM CLASS="bold">
branch</EM>
are used interchangeably in this document.</P>
<P CLASS="Body">
<A NAME="pgfId=997361">
</A>
<EM CLASS="bold">
Key</EM>
and <EM CLASS="bold">
index</EM>
are used interchangeably. A Judy tree is thought of as an unbounded Judy array at the API level. The expanse of JudyL or Judy1 arrays are bounded by the expanse of the word (32[64]-bits) used for the index/key. A JudySL array is only bounded by the length of the key string that can be stored in the machine.</P>
<P CLASS="Body">
<A NAME="pgfId=997362">
</A>
A (CPU) <EM CLASS="bold">
cache-line fill</EM>
is additional time required to do a read reference from RAM when a word is not found in cache. In today's computers the time for a cache-line fill is in the range of 50..2000 machine instructions. Therefore a cache-line fill should be avoided when fewer than 50 instructions can do the same job. (Modern machines tend to pipeline writes to RAM. They often take no additional time in the Judy design.)</P>
<P CLASS="Body">
<A NAME="pgfId=997363">
</A>
Some of the reasons Judy outperforms binary trees, b-trees, and skip-lists:</P>
<UL>
<LI CLASS="Bulleted">
<A NAME="pgfId=997364">
</A>
Judy rarely compromises speed/space performance for simplicity (Judy will never be called simple except at the API).</LI>
<LI CLASS="Bulleted">
<A NAME="pgfId=997365">
</A>
Judy is designed to avoid cache-line fills wherever possible. (This is the main design criteria for Judy.)</LI>
<LI CLASS="Bulleted">
<A NAME="pgfId=997366">
</A>
A b-tree requires a search of each node (branch), resulting in more cache-line fills.</LI>
<LI CLASS="Bulleted">
<A NAME="pgfId=997367">
</A>
A binary-tree has many more levels (about 8X), resulting in more cache-line fills.</LI>
<LI CLASS="Bulleted">
<A NAME="pgfId=997544">
</A>
A skip-list is roughly equivalent to a degree-4 (4-ary) tree, resulting in more cache-line fills.</LI>
<LI CLASS="Bulleted">
<A NAME="pgfId=997545">
</A>
An &quot;expanse&quot;-based digital tree (of which Judy is a variation) never needs balancing as it grows.</LI>
<LI CLASS="Bulleted">
<A NAME="pgfId=997370">
</A>
A portion (8 bits) of the key is used to subdivide an expanse into sub-trees. Only the remainder of the key need exist in the sub-trees, if at all, resulting in key compression.</LI>
</UL>
<P CLASS="Body">
<A NAME="pgfId=997371">
</A>
The Achilles heel of a simple digital tree is very poor memory utilization, especially when the N in N-ary (the degree or fanout of each branch) increases. The Judy tree design was able to solve this problem. In fact a Judy tree is more memory-efficient than almost any other competitive structure (including a simple linked list). A highly populated linear array[] is the notable exception.</P>
<P CLASS="Body">
<A NAME="pgfId=997372">
</A>
From a speed point of view Judy is chiefly a 256-ary digital tree or trie (per D. Knuth Volume 3 definitions). A degree of 256-ary is a somewhat &quot;magic&quot; N-ary for a variety of reasons -- mostly because a byte (the least addressable memory unit) is 8 bits. Also a higher degree means reduced cache-line fills per access. You see the theme here -- avoid cache-line fills like the plague.</P>
<P CLASS="Body">
<A NAME="pgfId=997373">
</A>
It is interesting to note that an early version of Judy used branch widening (sometimes called a level-compressed trie). Branch widening opportunities occur primarily in the upper level(s) of the tree. Since a tree is a hierarchy, the upper branches are likely to be in cache, thus branch widening did not significantly reduce the number of actual cache-line fills. Branch widening was removed in later versions of Judy. (However, Judy was also tuned to use as few instructions as possible when an access was likely to be in the cache.)</P>
<P CLASS="Body">
<A NAME="pgfId=997374">
</A>
The presence of a CPU cache in modern machines has changed many of the ways to write a performance algorithm. To take advantage of a cache, it is important to leverage as much as possible. In a Judy tree, the presence of a cache results in 1..3 (or more) fewer cache-line fills per access than would be possible without a cache.</P>
<P CLASS="Body">
<A NAME="pgfId=997375">
</A>
As a digression, note that a hash method loses the advantages of a cache as the size of the hash table approaches or exceeds the size of the cache. With very large hash tables, the cache is no help at all. Also, hash methods often use a linked list to handle collisions (synonyms) and typically use a slow hash algorithm (greater than 50ns) or suffer from numerous collisions. &quot;Judy Scalable Hashing&quot; is an effective replacement for common hash methods when very high performance is required for small in-cache data sets. (See also
<A HREF="http://www.sourcejudy.com/application/">http://www.sourcejudy.com/application/</A>
Judy_hashing.</P>
<P CLASS="Body">
<A NAME="pgfId=997376">
</A>
With an expanse of 2^32 (or 256^4), a maximum of 4 cache-line fills would be required for a worst-case highly populated 256-ary digital tree access. In an expanse of 2^64 (or 256^8), 8 cache-line fills would be the worst case. In practice, Judy does much better than this. The reason is (in part) due to the fact &quot;density&quot; of the keys is seldom the lowest possible number in a &quot;majority&quot; of the sub-expanses. It takes high density combined with high population to increase the depth of a Judy tree. It would take a long time to explain why. The short version is an analogy with sand. It takes a lot of sand to build a tall sand pile, especially if it takes 256 grains to support 1 grain above it. In a 64-bit Judy, it would probably require more RAM than exists on this planet to get it to have 8 levels. A binary tree reaches 8 levels with a population of 256. It is truly remarkable to me how much research has been done on binary trees and still being taught.</P>
<P CLASS="Body">
<A NAME="pgfId=997377">
</A>
Judy adapts efficiently to a wide range of populations and data set densities. Since the Judy data structure is a tree of trees, each sub-tree is a static expanse that is optimized to match the "character" or density of the keys it contains. To support this flexibility, in 32[64]-bit Judy there are approximately 25[85] major data structures and a similar number of minor structures. I am going to only describe a few of them so you can infer how density is synergistic with compression.</P>
<P CLASS="Body">
<A NAME="pgfId=997378">
</A>
From a memory consumption (size) point of view, a Judy tree shares (does not duplicate) common digits of a key in a tree. This form of key compression is a natural outcome from using a digital tree. This would be very awkward to do in trees balanced by population and, as far as I know, has never been done. Each pointer traversed in a Judy tree points to ever smaller sub-expanses, while decoding another 8 bits of the key. (In a pure digital tree, the keys are not stored in the tree, they are inferred by position.)</P>
<P CLASS="Body">
<A NAME="pgfId=997552">
</A>
Now let me try to describe the top of a small Judy (JudyL) tree and the bottom of a highly populated Judy1 tree. A Judy tree with a population of zero is simply a NULL pointer. A JudyL tree with a population of one key is a root pointer to a 2-word object containing a key and and associated value.
A JudyL tree with a population of 2 keys, is 4-word object with 2 values and 2 sorted keys. A tree with a population of 3 keys, is an 8-word object with a count word + 3 values and 3 sorted keys.</P>
<P CLASS="Body">
<A NAME="pgfId=997381">
</A>
This continues until the population grows to 32 keys. At this point an actual tree structure is formed with a &quot;compressed&quot; 256-ary node (branch) that decodes the first byte of each key. The value 32 was chosen because this is where a tree structure requires an equivalent number of cache-line fills. All objects below this top branch contain keys that are shortened by at least the first byte.</P>
<P CLASS="Body">
<A NAME="pgfId=997382">
</A>
There are three kinds of branches. Two are 1-cache-line fill objects to traverse, and one is a 2-cache-line fill object to traverse. In every path down the tree and at all populations, a maximum of one of the 2-cache-line fill branches is used. This means it is sometimes possible to have 1 additional (the branch design often subtracts 1) cache-line fill than you would expect from a pure 256-ary branch traversal in an otherwise complete Judy tree.</P>
<P CLASS="Body">
<A NAME="pgfId=997383">
</A>
On the other extreme, a highly populated Judy1 tree where the key has been decoded down to 1 byte, and the density of a 256-wide sub-expanse of keys grows to greater than 0.094 (25 keys / 256 expanse), a bitmap of 32 bytes (256 bits) is formed from an existing sorted array of 24 1-byte keys. (I am leaving out the handling of the values.) This results in a key using about an average of 1.3 (32/25) bytes of memory (up from 1.0). Note that increasing the density (population) at this point does NOT require more memory for keys. For example, when the density reaches 0.5 (population = 128 / expanse = 256), the memory consumed is about 2 bits ((32/128)*8) per key + some overhead (2.0+ words) for the tree structure.</P>
<P CLASS="Body">
<A NAME="pgfId=997579">
</A>
Notice that to insert or delete a key is almost as simple as setting or clearing a bit. Also notice, the memory consumption is almost the same for both 32- and 64-bit Judy trees. Given the same set of keys, both 32- and 64-bit Judy trees have remarkably similar key-memory, depth, and performance. However, the memory consumption for 64-bit Judy is higher because the pointers and values (JudyL) are double the size.</P>
<P CLASS="Body">
<A NAME="pgfId=997580">
</A>
In this short writeup it wasn't possible to describe all the data structure details such as: Root, JPM, narrow and rich pointers, linear, bitmap and uncompressed branches, value areas, immediate indexes, terminal nodes (leafs), least compressed form, memory management, fast leaf searches and counting trees.</P>
<P CLASS="Body">
<A NAME="pgfId=997386">
</A>
Well I cannot describe Judy in 10 minutes -- what possessed me? I hope you understand some of what I have said and question me on the rest -- particularly those doubts. I will try to elaborate on parts where I get questions.
<BR><BR>
Doug Baskins
<BR>
doug@sourcejudy.com</P>
</DIV>
</BODY>
</HTML>

View File

@@ -1,47 +0,0 @@
/* @(#) $Revision: 4.2 $ $Source: /judy/src/funcs/Judy1Dup.c $ */
#include "Judy.h"
/*******************************************************************
* Name: Judy1Dup
*
* Description:
* Clone (duplicate) a Judy Array.
*
* Parameters:
* PPvoid_t PPDest (OUT)
* Pointer to a new Judy array with the same
* index/value pairs as PSource.
* Any initial value pointed to by PPDest is ignored.
*
* Pvoid_t PSource (IN)
* Ptr to source Judy array being duplicated.
* If PSource is NULL, TRUE is returned since this
* is simply a valid Null Judy array.
*
* JError_t *PJError (OUT)
* Judy error structure pointer.
*
* Returns:
* JERR - error, see PJError
* !JERR - success
*/
int
Judy1Dup(PPvoid_t PPDest, Pvoid_t PSource, JError_t * PJError)
{
Pvoid_t newJArray = 0; // new Judy1 array to ppopulate
Word_t kindex; // Key/index
int Ins_rv = 0; // Insert return value
for (kindex = 0L, Ins_rv = Judy1First(PSource, &kindex, PJError);
Ins_rv == 1; Ins_rv = Judy1Next(PSource, &kindex, PJError))
{
Ins_rv = Judy1Set(&newJArray, kindex, PJError);
}
if (Ins_rv == JERR)
return Ins_rv;
*PPDest = newJArray;
return Ins_rv;
} /* Judy1Dup */

View File

@@ -1,31 +0,0 @@
/* @(#) $Revision: 4.2 $ $Source: /judy/src/funcs/Judy1Dup.H $ */
#include <Judy.h>
/* ******************************************************************
* Name: Judy1Dup
*
* Description:
* Clone (duplicate) a Judy Array.
*
* Parameters:
* PPvoid_t PPDest (OUT)
* Pointer to a new Judy array with the same
* index/value pairs as PSource.
* Any initial value pointed to by PPDest is ignored.
*
* Pvoid_t PSource (IN)
* Ptr to source Judy array being duplicated.
* If PSource is NULL, TRUE is returned since this
* is simply a valid Null Judy array.
*
* JError_t *PJError (OUT)
* Judy error structure pointer.
*
* Returns:
* JERR - error, see PJError
* !JERR - success
*/
int
Judy1Dup(PPvoid_t PPDest, Pvoid_t PSource, JError_t * PJError);

View File

@@ -1,80 +0,0 @@
/*
* @(#) $Revision: 4.3 $ $Source: /judy/src/funcs/Judy1DupCheck.c $
*
* Judy1DupCheck.c
*
* Test Judy1Dup.c
*/
#include <errno.h>
#include <limits.h>
#include "Judy1Dup.h"
#define LARRAYSIZE(array) sizeof(array)/sizeof(Word_t)
// fcn to init a Judy array with an array of ulong's
Pvoid_t
ularray2Judy(Word_t *ularray, Word_t ularray_size)
{
Word_t i;
Pvoid_t PJArray = 0;
JError_t JError;
for (i = 0L; i < ularray_size; i++)
{
if (Judy1Set(&PJArray, ularray[i], &JError) == JERR)
{
printf("ularray2Judy: Judy1Set failure, error %d\n",
JU_ERRNO(&JError));
exit(2);
}
}
return PJArray;
} /* ularray2Judy */
int
main()
{
static Word_t knowns[] = { 0, 1, 1024, 4095, 4096, 4097, 4098, 123456 };
int i;
Pvoid_t PJArray = 0;
Pvoid_t PJArrayNew = 0;
Word_t Index;
int Judy_rv; // Judy Return value
JError_t JError;
// populate a judy array with known values
PJArray = ularray2Judy(knowns, LARRAYSIZE(knowns));
printf("Testing Judy1Dup ...");
// dup the judy array
if ((Judy1Dup(&PJArrayNew, PJArray, &JError)) == JERR)
{
printf("Judy1Dup failed: error %d\n", JU_ERRNO(&JError));
return (2);
}
// compare the duped array with known values
for (i = 0, Index = 0L, Judy_rv = Judy1First(PJArrayNew, &Index, &JError);
Judy_rv == 1; i++, Judy_rv = Judy1Next(PJArrayNew, &Index, &JError))
{
if (Index != knowns[i])
{
printf("Judy1DupCheck Failed: Judy1Dup does not match original\n");
return (2);
}
}
if (i != LARRAYSIZE(knowns))
{
printf
("Judy1DupCheck Failed: Judy1Dup does not match original (too short)\n");
exit(2);
}
else
printf("Ok\n");
return (0);
}

View File

@@ -1,150 +0,0 @@
/*
* @(#) $Revision: 4.2 $ $Source: /judy/src/funcs/Judy1Op.c $
*
* Judy1 set operations.
*
* The name of this function, "Judy1Op", was carefully chosen from
* a list of alternatives:
*
* Judy1Op() - It's hard to see that O is a letter and not a zero.
* Judy1Set() - Sounds like you are setting a bit.
* Judy1BS() - BS for Bit Set functions.
* Judy1SO() - SO for Set Operations
* Judy1AndIDontGiveADarn() - too long but goes with
* Judy1WhoseOnFirst() - now called Judy1First() and
* Judy1WhatsOnSecond() - now called Judy1Next()
*
* But Judy1SetOp() would conflict with Judy1Set() if we rename Judy1Set(), so
* Judy1Op() it is.
*/
#include "Judy.h"
#include "Judy1Op.h"
/*******************************************************************
* Name: Judy1Op
*
* Description:
* Logical set operations on Judy1 arrays.
*
* All of these operations can be done on an unbounded array because
* the dreaded "NOT" is avoided. The "NOT"'s can be implemented
* when Judy1 supports them.
*
* Parameters:
* PPvoid_t PPDest (OUT)
* Ptr to the Judy destination array.
* Any initial value pointed to by PPDest is ignored.
*
* Pvoid_t PSet1 (IN)
* First Judy1 set.
* This will be NULL for an empty Judy1 array.
*
* Pvoid_t PSet2 (IN)
* Second Judy1 set.
* This will be NULL for an empty Judy1 array.
*
* Word_t Operation (IN)
* Operation to be performed (ie. PSet1 {Operation} PSet2)
* Valid Operation values are:
*
* JUDY1OP_AND - intersection of two sets
* JUDY1OP_OR - union of two sets
* JUDY1OP_ANDNOT - set1 with set2 removed
*
* JError_t * PJError (OUT)
* Judy Error struct used to return Judy error.
*
* Returns:
* !JERR if successful
* JERR if an error occurs
* If the error is a caller error (invalid Operation or no PPDest)
* then the PJError error code will be JU_ERRNO_NONE.
*/
int
Judy1Op(PPvoid_t PPDest, Pvoid_t PSet1, Pvoid_t PSet2,
Word_t Operation, JError_t * PJError)
{
Pvoid_t PnewJArray = 0; // empty Judy array
Word_t Index1 = 0L;
Word_t Index2 = 0L;
int Judy_rv;
if (!PPDest)
return JERR;
switch (Operation)
{
case JUDY1OP_AND:
// step through each array looking for index matches
Judy_rv = Judy1First(PSet1, &Index1, PJError);
Judy_rv += Judy1First(PSet2, &Index2, PJError);
while (Judy_rv == 2)
{
if (Index1 < Index2)
{
Index1 = Index2;
Judy_rv = Judy1First(PSet1, &Index1, PJError);
}
else if (Index1 > Index2)
{
Index2 = Index1;
Judy_rv = Judy1First(PSet2, &Index2, PJError);
}
else
{
// do the AND
Judy_rv = Judy1Set(&PnewJArray, Index1, PJError);
if (Judy_rv == JERR)
return JERR;
// bump to the next bits
Judy_rv = Judy1Next(PSet1, &Index1, PJError);
Judy_rv += Judy1Next(PSet2, &Index2, PJError);
}
}
*PPDest = PnewJArray;
break;
case JUDY1OP_OR:
/* Set all the bits from PSet1 */
for (Index1 = 0L, Judy_rv = Judy1First(PSet1, &Index1, PJError);
Judy_rv == 1; Judy_rv = Judy1Next(PSet1, &Index1, PJError))
{
if (Judy1Set(&PnewJArray, Index1, PJError) == JERR)
return JERR;
}
/* Set all the bits from PSet2 */
for (Index1 = 0L, Judy_rv = Judy1First(PSet2, &Index1, PJError);
Judy_rv == 1; Judy_rv = Judy1Next(PSet2, &Index1, PJError))
{
if (Judy1Set(&PnewJArray, Index1, PJError) == JERR)
return JERR;
}
*PPDest = PnewJArray;
break;
case JUDY1OP_ANDNOT:
// PSet1 with PSet2 removed
// 0010 = PSet1(1010) ANDNOT PSet2(1100)
for (Index1 = 0L, Judy_rv = Judy1First(PSet1, &Index1, PJError);
Judy_rv == 1; Judy_rv = Judy1Next(PSet1, &Index1, PJError))
{
// if bit doesn't exist in PSet2, then add to result
if (0 == Judy1Test(PSet2, Index1, PJError))
{
if (Judy1Set(&PnewJArray, Index1, PJError) == JERR)
return JERR;
}
}
*PPDest = PnewJArray;
break;
default:
return JERR;
}
return !JERR;
} /* Judy1Op */

View File

@@ -1,15 +0,0 @@
#ifndef _JUDY1OP_INCLUDED
#define _JUDY1OP_INCLUDED
// @(#) $Revision: 4.1 $ $Source: /judy/src/funcs/Judy1Op.h $
//
// HEADER FILE FOR EXPORTED FEATURES FROM Judy1Op().
#define JUDY1OP_AND 1L
#define JUDY1OP_OR 2L
#define JUDY1OP_ANDNOT 3L
extern int Judy1Op(PPvoid_t PPDest, Pvoid_t PSet1, Pvoid_t PSet2,
Word_t Operation, JError_t * PJError);
#endif // ! _JUDY1OP_INCLUDED

View File

@@ -1,150 +0,0 @@
// @(#) $Revision: 4.3 $ $Source: /judy/src/funcs/Judy1OpCheck.c $
/*
* Judy1OpCheck.c
*
* Test Judy1Op.c
*
* Returns 0 if successful, -1 if test fails.
*/
#include <errno.h>
#include <limits.h>
#include "Judy.h"
#include "Judy1Op.h"
#define LARRAYSIZE(array) sizeof(array)/sizeof(Word_t)
static Word_t set1[] = { 0L,
5L,
6L,
7L,
1024L,
11111L,
65534L,
65535L,
65536L,
555555L,
ULONG_MAX
};
static Word_t set2[] = { 7L,
9L,
1023L,
12345L,
65535L,
ULONG_MAX
};
static Word_t resultAND[] = { 7L,
65535L,
ULONG_MAX
};
static Word_t resultOR[] = { 0L,
5L,
6L,
7L,
9L,
1023L,
1024L,
11111L,
12345L,
65534L,
65535L,
65536L,
555555L,
ULONG_MAX
};
static Word_t result1ANDNOT2[] = { 0L,
5L,
6L,
1024L,
11111L,
65534L,
65536L,
555555L
};
static Word_t result2ANDNOT1[] = { 9L,
1023L,
12345L
};
// fcn to init a Judy array with an array of ulong's
void *
ularray2Judy(Word_t *ularray, Word_t ularray_size)
{
Word_t i;
void *PJArray = 0;
JError_t JError;
for (i = 0L; i < ularray_size; i++)
{
if (Judy1Set(&PJArray, ularray[i], &JError) == JERR)
{
printf("ularray2Judy: Judy1Set failure, error %d\n",
JU_ERRNO(&JError));
exit(2);
}
}
return PJArray;
} /* ularray2Judy */
// fcn to test Judy1Op and check the results
void
testandcheck(void *PJSet1, void *PJSet2, Word_t operation,
char *opstr, Word_t *result, int result_size)
{
void *PJArrayNew;
Word_t Index;
int i;
int judy_rv = 0;
JError_t JError;
printf("Testing Judy1Op(%s) ...", opstr);
if (Judy1Op(&PJArrayNew, PJSet1, PJSet2, operation, &JError) == JERR)
printf(" failed, error %d\n", JU_ERRNO(&JError));
else
{ // check results
for (i = 0, Index = 0L, judy_rv =
Judy1First(PJArrayNew, &Index, &JError); judy_rv == 1;
i++, judy_rv = Judy1Next(PJArrayNew, &Index, &JError))
{
if ((i >= result_size) || (Index != result[i]))
{
printf("Failed\n");
return;
}
}
if (i > result_size)
printf("Failed\n");
else
printf("Ok\n");
}
return;
}
int
main()
{
void *PJSet1 = 0;
void *PJSet2 = 0;
// Test Judy1Op
// init PJSet1 and PJSet2
PJSet1 = ularray2Judy(set1, LARRAYSIZE(set1));
PJSet2 = ularray2Judy(set2, LARRAYSIZE(set2));
testandcheck(PJSet1, PJSet2, JUDY1OP_AND, "AND",
resultAND, LARRAYSIZE(resultAND));
testandcheck(PJSet1, PJSet2, JUDY1OP_OR, "OR",
resultOR, LARRAYSIZE(resultOR));
testandcheck(PJSet1, PJSet2, JUDY1OP_ANDNOT, "1ANDNOT2",
result1ANDNOT2, LARRAYSIZE(result1ANDNOT2));
testandcheck(PJSet2, PJSet1, JUDY1OP_ANDNOT, "2ANDNOT1",
result2ANDNOT1, LARRAYSIZE(result2ANDNOT1));
return (0);
}

View File

@@ -1,13 +0,0 @@
CCFLAGS += -ggdb
LIBS = -lJudy
all: Judy1DupCheck Judy1OpCheck
Judy1DupCheck: Judy1Dup.c Judy1DupCheck.c
$(CC) $(CCFLAGS) -o $@ $^ $(LIBS)
Judy1OpCheck: Judy1Op.c Judy1OpCheck.c
$(CC) $(CCFLAGS) -o $@ $^ $(LIBS)
clean:
rm -f Judy1DupCheck Judy1OpCheck *.o

View File

@@ -1,8 +0,0 @@
This directory contains example programs that show some of the many ways Judy
can be utilized, in other words it contains useful applications of Judy.
Judy1Dup: Clone (duplicate) a Judy Array.
Judy1Op: Support Logical "set" operations on Judy1 arrays.
See the source code for more information.

View File

@@ -1,622 +0,0 @@
#ifndef _JUDY_INCLUDED
#define _JUDY_INCLUDED
// _________________
//
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.52 $ $Source: /judy/src/Judy.h $
//
// HEADER FILE FOR EXPORTED FEATURES IN JUDY LIBRARY, libJudy.*
//
// See the manual entries for details.
//
// Note: This header file uses old-style comments on #-directive lines and
// avoids "()" on macro names in comments for compatibility with older cc -Aa
// and some tools on some platforms.
// PLATFORM-SPECIFIC
#ifdef JU_WIN /* =============================================== */
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else /* ================ ! JU_WIN ============================= */
// ISO C99: 7.8 Format conversion of integer types <inttypes.h>
#include <inttypes.h> /* if this FAILS, try #include <stdint.h> */
// ISO C99: 7.18 Integer types uint*_t
//#include <stdint.h>
#endif /* ================ ! JU_WIN ============================= */
// ISO C99 Standard: 7.20 General utilities
#include <stdlib.h>
// ISO C99 Standard: 7.10/5.2.4.2.1 Sizes of integer types
#include <limits.h>
#ifdef __cplusplus /* support use by C++ code */
extern "C" {
#endif
// ****************************************************************************
// DECLARE SOME BASE TYPES IN CASE THEY ARE MISSING:
//
// These base types include "const" where appropriate, but only where of
// interest to the caller. For example, a caller cares that a variable passed
// by reference will not be modified, such as, "const void * Pindex", but not
// that the called function internally does not modify the pointer itself, such
// as, "void * const Pindex".
//
// Note that its OK to pass a Pvoid_t to a Pcvoid_t; the latter is the same,
// only constant. Callers need to do this so they can also pass & Pvoid_t to
// PPvoid_t (non-constant).
#ifndef _PCVOID_T
#define _PCVOID_T
typedef const void * Pcvoid_t;
#endif
#ifndef _PVOID_T
#define _PVOID_T
typedef void * Pvoid_t;
typedef void ** PPvoid_t;
#endif
#ifndef _WORD_T
#define _WORD_T
typedef unsigned long Word_t, * PWord_t; // expect 32-bit or 64-bit words.
#endif
#ifndef NULL
#define NULL 0
#endif
// ****************************************************************************
// SUPPORT FOR ERROR HANDLING:
//
// Judy error numbers:
//
// Note: These are an enum so theres a related typedef, but the numbers are
// spelled out so you can map a number back to its name.
typedef enum // uint8_t -- but C does not support this type of enum.
{
// Note: JU_ERRNO_NONE and JU_ERRNO_FULL are not real errors. They specify
// conditions which are otherwise impossible return values from 32-bit
// Judy1Count, which has 2^32 + 1 valid returns (0..2^32) plus one error
// return. These pseudo-errors support the return values that cannot otherwise
// be unambiguously represented in a 32-bit word, and will never occur on a
// 64-bit system.
JU_ERRNO_NONE = 0,
JU_ERRNO_FULL = 1,
JU_ERRNO_NFMAX = JU_ERRNO_FULL,
// JU_ERRNO_NOMEM comes from malloc(3C) when Judy cannot obtain needed memory.
// The system errno value is also set to ENOMEM. This error can be recoverable
// if the calling application frees other memory.
//
// TBD: Currently there is no guarantee the Judy array has no memory leaks
// upon JU_ERRNO_NOMEM.
JU_ERRNO_NOMEM = 2,
// Problems with parameters from the calling program:
//
// JU_ERRNO_NULLPPARRAY means PPArray was null; perhaps PArray was passed where
// &PArray was intended. Similarly, JU_ERRNO_NULLPINDEX means PIndex was null;
// perhaps &Index was intended. Also, JU_ERRNO_NONNULLPARRAY,
// JU_ERRNO_NULLPVALUE, and JU_ERRNO_UNSORTED, all added later (hence with
// higher numbers), mean: A non-null array was passed in where a null pointer
// was required; PValue was null; and unsorted indexes were detected.
JU_ERRNO_NULLPPARRAY = 3, // see above.
JU_ERRNO_NONNULLPARRAY = 10, // see above.
JU_ERRNO_NULLPINDEX = 4, // see above.
JU_ERRNO_NULLPVALUE = 11, // see above.
JU_ERRNO_NOTJUDY1 = 5, // PArray is not to a Judy1 array.
JU_ERRNO_NOTJUDYL = 6, // PArray is not to a JudyL array.
JU_ERRNO_NOTJUDYSL = 7, // PArray is not to a JudySL array.
JU_ERRNO_UNSORTED = 12, // see above.
// Errors below this point are not recoverable; further tries to access the
// Judy array might result in EFAULT and a core dump:
//
// JU_ERRNO_OVERRUN occurs when Judy detects, upon reallocation, that a block
// of memory in its own freelist was modified since being freed.
JU_ERRNO_OVERRUN = 8,
// JU_ERRNO_CORRUPT occurs when Judy detects an impossible value in a Judy data
// structure:
//
// Note: The Judy data structure contains some redundant elements that support
// this type of checking.
JU_ERRNO_CORRUPT = 9
// Warning: At least some C or C++ compilers do not tolerate a trailing comma
// above here. At least we know of one case, in aCC; see JAGad58928.
} JU_Errno_t;
// Judy errno structure:
//
// WARNING: For compatibility with possible future changes, the fields of this
// struct should not be referenced directly. Instead use the macros supplied
// below.
// This structure should be declared on the stack in a threaded process.
typedef struct J_UDY_ERROR_STRUCT
{
JU_Errno_t je_Errno; // one of the enums above.
int je_ErrID; // often an internal source line number.
Word_t je_reserved[4]; // for future backward compatibility.
} JError_t, * PJError_t;
// Related macros:
//
// Fields from error struct:
#define JU_ERRNO(PJError) ((PJError)->je_Errno)
#define JU_ERRID(PJError) ((PJError)->je_ErrID)
// For checking return values from various Judy functions:
//
// Note: Define JERR as -1, not as the seemingly more portable (Word_t)
// (~0UL), to avoid a compiler "overflow in implicit constant conversion"
// warning.
#define JERR (-1) /* functions returning int or Word_t */
#define PJERR ((Pvoid_t) (~0UL)) /* mainly for use here, see below */
#define PPJERR ((PPvoid_t) (~0UL)) /* functions that return PPvoid_t */
// Convenience macro for when detailed error information (PJError_t) is not
// desired by the caller; a purposely short name:
#define PJE0 ((PJError_t) NULL)
// ****************************************************************************
// JUDY FUNCTIONS:
//
// P_JE is a shorthand for use below:
#define P_JE PJError_t PJError
// ****************************************************************************
// JUDY1 FUNCTIONS:
extern int Judy1Test( Pcvoid_t PArray, Word_t Index, P_JE);
extern int Judy1Set( PPvoid_t PPArray, Word_t Index, P_JE);
extern int Judy1SetArray( PPvoid_t PPArray, Word_t Count,
const Word_t * const PIndex,
P_JE);
extern int Judy1Unset( PPvoid_t PPArray, Word_t Index, P_JE);
extern Word_t Judy1Count( Pcvoid_t PArray, Word_t Index1,
Word_t Index2, P_JE);
extern int Judy1ByCount( Pcvoid_t PArray, Word_t Count,
Word_t * PIndex, P_JE);
extern Word_t Judy1FreeArray( PPvoid_t PPArray, P_JE);
extern Word_t Judy1MemUsed( Pcvoid_t PArray);
extern Word_t Judy1MemActive( Pcvoid_t PArray);
extern int Judy1First( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int Judy1Next( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int Judy1Last( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int Judy1Prev( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int Judy1FirstEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int Judy1NextEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int Judy1LastEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int Judy1PrevEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern PPvoid_t JudyLGet( Pcvoid_t PArray, Word_t Index, P_JE);
extern PPvoid_t JudyLIns( PPvoid_t PPArray, Word_t Index, P_JE);
extern int JudyLInsArray( PPvoid_t PPArray, Word_t Count,
const Word_t * const PIndex,
const Word_t * const PValue,
// ****************************************************************************
// JUDYL FUNCTIONS:
P_JE);
extern int JudyLDel( PPvoid_t PPArray, Word_t Index, P_JE);
extern Word_t JudyLCount( Pcvoid_t PArray, Word_t Index1,
Word_t Index2, P_JE);
extern PPvoid_t JudyLByCount( Pcvoid_t PArray, Word_t Count,
Word_t * PIndex, P_JE);
extern Word_t JudyLFreeArray( PPvoid_t PPArray, P_JE);
extern Word_t JudyLMemUsed( Pcvoid_t PArray);
extern Word_t JudyLMemActive( Pcvoid_t PArray);
extern PPvoid_t JudyLFirst( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern PPvoid_t JudyLNext( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern PPvoid_t JudyLLast( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern PPvoid_t JudyLPrev( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int JudyLFirstEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int JudyLNextEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int JudyLLastEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
extern int JudyLPrevEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
// ****************************************************************************
// JUDYSL FUNCTIONS:
extern PPvoid_t JudySLGet( Pcvoid_t, const uint8_t * Index, P_JE);
extern PPvoid_t JudySLIns( PPvoid_t, const uint8_t * Index, P_JE);
extern int JudySLDel( PPvoid_t, const uint8_t * Index, P_JE);
extern Word_t JudySLFreeArray( PPvoid_t, P_JE);
extern PPvoid_t JudySLFirst( Pcvoid_t, uint8_t * Index, P_JE);
extern PPvoid_t JudySLNext( Pcvoid_t, uint8_t * Index, P_JE);
extern PPvoid_t JudySLLast( Pcvoid_t, uint8_t * Index, P_JE);
extern PPvoid_t JudySLPrev( Pcvoid_t, uint8_t * Index, P_JE);
// ****************************************************************************
// JUDYHSL FUNCTIONS:
extern PPvoid_t JudyHSGet( Pcvoid_t, void *, Word_t);
extern PPvoid_t JudyHSIns( PPvoid_t, void *, Word_t, P_JE);
extern int JudyHSDel( PPvoid_t, void *, Word_t, P_JE);
extern Word_t JudyHSFreeArray( PPvoid_t, P_JE);
extern const char *Judy1MallocSizes;
extern const char *JudyLMallocSizes;
// ****************************************************************************
// JUDY memory interface to malloc() FUNCTIONS:
extern Word_t JudyMalloc(Word_t); // words reqd => words allocd.
extern Word_t JudyMallocVirtual(Word_t); // words reqd => words allocd.
extern void JudyFree(Pvoid_t, Word_t); // free, size in words.
extern void JudyFreeVirtual(Pvoid_t, Word_t); // free, size in words.
#define JLAP_INVALID 0x1 /* flag to mark pointer "not a Judy array" */
// ****************************************************************************
// MACRO EQUIVALENTS FOR JUDY FUNCTIONS:
//
// The following macros, such as J1T, are shorthands for calling Judy functions
// with parameter address-of and detailed error checking included. Since they
// are macros, the error checking code is replicated each time the macro is
// used, but it runs fast in the normal case of no error.
//
// If the caller does not like the way the default JUDYERROR macro handles
// errors (such as an exit(1) call when out of memory), they may define their
// own before the "#include <Judy.h>". A routine such as HandleJudyError
// could do checking on specific error numbers and print a different message
// dependent on the error. The following is one example:
//
// Note: the back-slashes are removed because some compilers will not accept
// them in comments.
//
// void HandleJudyError(uint8_t *, int, uint8_t *, int, int);
// #define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID)
// {
// HandleJudyError(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID);
// }
//
// The routine HandleJudyError could do checking on specific error numbers and
// print a different message dependent on the error.
//
// The macro receives five parameters that are:
//
// 1. CallerFile: Source filename where a Judy call returned a serious error.
// 2. CallerLine: Line number in that source file.
// 3. JudyFunc: Name of Judy function reporting the error.
// 4. JudyErrno: One of the JU_ERRNO* values enumerated above.
// 5. JudyErrID: The je_ErrID field described above.
#ifndef JUDYERROR_NOTEST
#ifndef JUDYERROR /* supply a default error macro */
#include <stdio.h>
#define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) \
{ \
(void) fprintf(stderr, "File '%s', line %d: %s(), " \
"JU_ERRNO_* == %d, ID == %d\n", \
CallerFile, CallerLine, \
JudyFunc, JudyErrno, JudyErrID); \
exit(1); \
}
#endif /* JUDYERROR */
#endif /* JUDYERROR_NOTEST */
// If the JUDYERROR macro is not desired at all, then the following eliminates
// it. However, the return code from each Judy function (that is, the first
// parameter of each macro) must be checked by the caller to assure that an
// error did not occur.
//
// Example:
//
// #define JUDYERROR_NOTEST 1
// #include <Judy.h>
//
// or use this cc option at compile time:
//
// cc -DJUDYERROR_NOTEST ...
//
// Example code:
//
// J1S(Rc, PArray, Index);
// if (Rc == JERR) goto ...error
//
// or:
//
// JLI(PValue, PArray, Index);
// if (PValue == PJERR) goto ...error
// Internal shorthand macros for writing the J1S, etc. macros:
#ifdef JUDYERROR_NOTEST /* ============================================ */
// "Judy Set Error":
#define J_SE(FuncName,Errno) ((void) 0)
// Note: In each J_*() case below, the digit is the number of key parameters
// to the Judy*() call. Just assign the Func result to the callers Rc value
// without a cast because none is required, and this keeps the API simpler.
// However, a family of different J_*() macros is needed to support the
// different numbers of key parameters (0,1,2) and the Func return type.
//
// In the names below, "I" = integer result; "P" = pointer result. Note, the
// Funcs for J_*P() return PPvoid_t, but cast this to a Pvoid_t for flexible,
// error-free assignment, and then compare to PJERR.
#define J_0I(Rc,PArray,Func,FuncName) \
{ (Rc) = Func(PArray, PJE0); }
#define J_1I(Rc,PArray,Index,Func,FuncName) \
{ (Rc) = Func(PArray, Index, PJE0); }
#define J_1P(PV,PArray,Index,Func,FuncName) \
{ (PV) = (Pvoid_t) Func(PArray, Index, PJE0); }
#define J_2I(Rc,PArray,Index,Arg2,Func,FuncName) \
{ (Rc) = Func(PArray, Index, Arg2, PJE0); }
#define J_2C(Rc,PArray,Index1,Index2,Func,FuncName) \
{ (Rc) = Func(PArray, Index1, Index2, PJE0); }
#define J_2P(PV,PArray,Index,Arg2,Func,FuncName) \
{ (PV) = (Pvoid_t) Func(PArray, Index, Arg2, PJE0); }
// Variations for Judy*Set/InsArray functions:
#define J_2AI(Rc,PArray,Count,PIndex,Func,FuncName) \
{ (Rc) = Func(PArray, Count, PIndex, PJE0); }
#define J_3AI(Rc,PArray,Count,PIndex,PValue,Func,FuncName) \
{ (Rc) = Func(PArray, Count, PIndex, PValue, PJE0); }
#else /* ================ ! JUDYERROR_NOTEST ============================= */
#define J_E(FuncName,PJE) \
JUDYERROR(__FILE__, __LINE__, FuncName, JU_ERRNO(PJE), JU_ERRID(PJE))
#define J_SE(FuncName,Errno) \
{ \
JError_t J_Error; \
JU_ERRNO(&J_Error) = (Errno); \
JU_ERRID(&J_Error) = __LINE__; \
J_E(FuncName, &J_Error); \
}
// Note: In each J_*() case below, the digit is the number of key parameters
// to the Judy*() call. Just assign the Func result to the callers Rc value
// without a cast because none is required, and this keeps the API simpler.
// However, a family of different J_*() macros is needed to support the
// different numbers of key parameters (0,1,2) and the Func return type.
//
// In the names below, "I" = integer result; "P" = pointer result. Note, the
// Funcs for J_*P() return PPvoid_t, but cast this to a Pvoid_t for flexible,
// error-free assignment, and then compare to PJERR.
#define J_0I(Rc,PArray,Func,FuncName) \
{ \
JError_t J_Error; \
if (((Rc) = Func(PArray, &J_Error)) == JERR) \
J_E(FuncName, &J_Error); \
}
#define J_1I(Rc,PArray,Index,Func,FuncName) \
{ \
JError_t J_Error; \
if (((Rc) = Func(PArray, Index, &J_Error)) == JERR) \
J_E(FuncName, &J_Error); \
}
#define J_1P(Rc,PArray,Index,Func,FuncName) \
{ \
JError_t J_Error; \
if (((Rc) = (Pvoid_t) Func(PArray, Index, &J_Error)) == PJERR) \
J_E(FuncName, &J_Error); \
}
#define J_2I(Rc,PArray,Index,Arg2,Func,FuncName) \
{ \
JError_t J_Error; \
if (((Rc) = Func(PArray, Index, Arg2, &J_Error)) == JERR) \
J_E(FuncName, &J_Error); \
}
// Variation for Judy*Count functions, which return 0, not JERR, for error (and
// also for other non-error cases):
//
// Note: JU_ERRNO_NFMAX should only apply to 32-bit Judy1, but this header
// file lacks the necessary ifdefs to make it go away otherwise, so always
// check against it.
#define J_2C(Rc,PArray,Index1,Index2,Func,FuncName) \
{ \
JError_t J_Error; \
if ((((Rc) = Func(PArray, Index1, Index2, &J_Error)) == 0) \
&& (JU_ERRNO(&J_Error) > JU_ERRNO_NFMAX)) \
{ \
J_E(FuncName, &J_Error); \
} \
}
#define J_2P(PV,PArray,Index,Arg2,Func,FuncName) \
{ \
JError_t J_Error; \
if (((PV) = (Pvoid_t) Func(PArray, Index, Arg2, &J_Error)) \
== PJERR) J_E(FuncName, &J_Error); \
}
// Variations for Judy*Set/InsArray functions:
#define J_2AI(Rc,PArray,Count,PIndex,Func,FuncName) \
{ \
JError_t J_Error; \
if (((Rc) = Func(PArray, Count, PIndex, &J_Error)) == JERR) \
J_E(FuncName, &J_Error); \
}
#define J_3AI(Rc,PArray,Count,PIndex,PValue,Func,FuncName) \
{ \
JError_t J_Error; \
if (((Rc) = Func(PArray, Count, PIndex, PValue, &J_Error)) \
== JERR) J_E(FuncName, &J_Error); \
}
#endif /* ================ ! JUDYERROR_NOTEST ============================= */
// Some of the macros are special cases that use inlined shortcuts for speed
// with root-level leaves:
// This is a slower version with current processors, but in the future...
#define J1T(Rc,PArray,Index) \
(Rc) = Judy1Test((Pvoid_t)(PArray), Index, PJE0)
#define J1S( Rc, PArray, Index) \
J_1I(Rc, (&(PArray)), Index, Judy1Set, "Judy1Set")
#define J1SA(Rc, PArray, Count, PIndex) \
J_2AI(Rc,(&(PArray)), Count, PIndex, Judy1SetArray, "Judy1SetArray")
#define J1U( Rc, PArray, Index) \
J_1I(Rc, (&(PArray)), Index, Judy1Unset, "Judy1Unset")
#define J1F( Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), Judy1First, "Judy1First")
#define J1N( Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), Judy1Next, "Judy1Next")
#define J1L( Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), Judy1Last, "Judy1Last")
#define J1P( Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), Judy1Prev, "Judy1Prev")
#define J1FE(Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), Judy1FirstEmpty, "Judy1FirstEmpty")
#define J1NE(Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), Judy1NextEmpty, "Judy1NextEmpty")
#define J1LE(Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), Judy1LastEmpty, "Judy1LastEmpty")
#define J1PE(Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), Judy1PrevEmpty, "Judy1PrevEmpty")
#define J1C( Rc, PArray, Index1, Index2) \
J_2C(Rc, PArray, Index1, Index2, Judy1Count, "Judy1Count")
#define J1BC(Rc, PArray, Count, Index) \
J_2I(Rc, PArray, Count, &(Index), Judy1ByCount, "Judy1ByCount")
#define J1FA(Rc, PArray) \
J_0I(Rc, (&(PArray)), Judy1FreeArray, "Judy1FreeArray")
#define J1MU(Rc, PArray) \
(Rc) = Judy1MemUsed(PArray)
#define JLG(PV,PArray,Index) \
(PV) = (Pvoid_t)JudyLGet((Pvoid_t)PArray, Index, PJE0)
#define JLI( PV, PArray, Index) \
J_1P(PV, (&(PArray)), Index, JudyLIns, "JudyLIns")
#define JLIA(Rc, PArray, Count, PIndex, PValue) \
J_3AI(Rc,(&(PArray)), Count, PIndex, PValue, JudyLInsArray, \
"JudyLInsArray")
#define JLD( Rc, PArray, Index) \
J_1I(Rc, (&(PArray)), Index, JudyLDel, "JudyLDel")
#define JLF( PV, PArray, Index) \
J_1P(PV, PArray, &(Index), JudyLFirst, "JudyLFirst")
#define JLN( PV, PArray, Index) \
J_1P(PV, PArray, &(Index), JudyLNext, "JudyLNext")
#define JLL( PV, PArray, Index) \
J_1P(PV, PArray, &(Index), JudyLLast, "JudyLLast")
#define JLP( PV, PArray, Index) \
J_1P(PV, PArray, &(Index), JudyLPrev, "JudyLPrev")
#define JLFE(Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), JudyLFirstEmpty, "JudyLFirstEmpty")
#define JLNE(Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), JudyLNextEmpty, "JudyLNextEmpty")
#define JLLE(Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), JudyLLastEmpty, "JudyLLastEmpty")
#define JLPE(Rc, PArray, Index) \
J_1I(Rc, PArray, &(Index), JudyLPrevEmpty, "JudyLPrevEmpty")
#define JLC( Rc, PArray, Index1, Index2) \
J_2C(Rc, PArray, Index1, Index2, JudyLCount, "JudyLCount")
#define JLBC(PV, PArray, Count, Index) \
J_2P(PV, PArray, Count, &(Index), JudyLByCount, "JudyLByCount")
#define JLFA(Rc, PArray) \
J_0I(Rc, (&(PArray)), JudyLFreeArray, "JudyLFreeArray")
#define JLMU(Rc, PArray) \
(Rc) = JudyLMemUsed(PArray)
#define JHSI(PV, PArray, PIndex, Count) \
J_2P(PV, (&(PArray)), PIndex, Count, JudyHSIns, "JudyHSIns")
#define JHSG(PV, PArray, PIndex, Count) \
(PV) = (Pvoid_t) JudyHSGet(PArray, PIndex, Count)
#define JHSD(Rc, PArray, PIndex, Count) \
J_2I(Rc, (&(PArray)), PIndex, Count, JudyHSDel, "JudyHSDel")
#define JHSFA(Rc, PArray) \
J_0I(Rc, (&(PArray)), JudyHSFreeArray, "JudyHSFreeArray")
#define JSLG( PV, PArray, Index) \
J_1P( PV, PArray, Index, JudySLGet, "JudySLGet")
#define JSLI( PV, PArray, Index) \
J_1P( PV, (&(PArray)), Index, JudySLIns, "JudySLIns")
#define JSLD( Rc, PArray, Index) \
J_1I( Rc, (&(PArray)), Index, JudySLDel, "JudySLDel")
#define JSLF( PV, PArray, Index) \
J_1P( PV, PArray, Index, JudySLFirst, "JudySLFirst")
#define JSLN( PV, PArray, Index) \
J_1P( PV, PArray, Index, JudySLNext, "JudySLNext")
#define JSLL( PV, PArray, Index) \
J_1P( PV, PArray, Index, JudySLLast, "JudySLLast")
#define JSLP( PV, PArray, Index) \
J_1P( PV, PArray, Index, JudySLPrev, "JudySLPrev")
#define JSLFA(Rc, PArray) \
J_0I( Rc, (&(PArray)), JudySLFreeArray, "JudySLFreeArray")
#ifdef __cplusplus
}
#endif
#endif /* ! _JUDY_INCLUDED */

View File

@@ -1,139 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.17 $ $Source: /judy/src/Judy.h.check.c $
//
// Fake "program" to test the exports in Judy.h by exercising each one. This
// program should compile OK (with libJudy.a) but does not run OK.
#include "Judy.h"
int
main()
{
Pvoid_t PArray = (Pvoid_t) NULL;
PPvoid_t PPArray = &PArray;
Word_t Index = 0;
PWord_t PIndex = &Index;
uint8_t *CIndex = NULL;
PPvoid_t PPvoid;
Word_t myword;
Word_t Length;
int myint;
// JUDY FUNCTIONS:
myint = Judy1Test ( PArray, Index, PJE0);
myint = Judy1Set (PPArray, Index, PJE0);
myint = Judy1SetArray (PPArray, Index, &Index, PJE0);
myint = Judy1Unset (PPArray, Index, PJE0);
myword = Judy1Count ( PArray, Index, Index, PJE0);
myint = Judy1ByCount ( PArray, Index, PIndex, PJE0);
myword = Judy1FreeArray (PPArray, PJE0);
myword = Judy1MemUsed ( PArray );
myword = Judy1MemActive ( PArray );
myint = Judy1First ( PArray, PIndex, PJE0);
myint = Judy1Next ( PArray, PIndex, PJE0);
myint = Judy1Last ( PArray, PIndex, PJE0);
myint = Judy1Prev ( PArray, PIndex, PJE0);
myint = Judy1FirstEmpty ( PArray, PIndex, PJE0);
myint = Judy1NextEmpty ( PArray, PIndex, PJE0);
myint = Judy1LastEmpty ( PArray, PIndex, PJE0);
myint = Judy1PrevEmpty ( PArray, PIndex, PJE0);
PPvoid = JudyLGet ( PArray, Index, PJE0);
PPvoid = JudyLIns (PPArray, Index, PJE0);
myint = JudyLInsArray (PPArray, Index, &Index, &Index, PJE0);
myint = JudyLDel (PPArray, Index, PJE0);
myword = JudyLCount ( PArray, Index, Index, PJE0);
PPvoid = JudyLByCount ( PArray, Index, PIndex, PJE0);
myword = JudyLFreeArray (PPArray, PJE0);
myword = JudyLMemUsed ( PArray );
myword = JudyLMemActive ( PArray );
PPvoid = JudyLFirst ( PArray, PIndex, PJE0);
PPvoid = JudyLNext ( PArray, PIndex, PJE0);
PPvoid = JudyLLast ( PArray, PIndex, PJE0);
PPvoid = JudyLPrev ( PArray, PIndex, PJE0);
myint = JudyLFirstEmpty ( PArray, PIndex, PJE0);
myint = JudyLNextEmpty ( PArray, PIndex, PJE0);
myint = JudyLLastEmpty ( PArray, PIndex, PJE0);
myint = JudyLPrevEmpty ( PArray, PIndex, PJE0);
PPvoid = JudySLGet ( PArray, CIndex, PJE0);
PPvoid = JudySLIns (PPArray, CIndex, PJE0);
myint = JudySLDel (PPArray, CIndex, PJE0);
myword = JudySLFreeArray (PPArray, PJE0);
PPvoid = JudySLFirst ( PArray, CIndex, PJE0);
PPvoid = JudySLNext ( PArray, CIndex, PJE0);
PPvoid = JudySLLast ( PArray, CIndex, PJE0);
PPvoid = JudySLPrev ( PArray, CIndex, PJE0);
PPvoid = JudyHSGet ( PArray, CIndex, Length);
PPvoid = JudyHSIns (PPArray, CIndex, Length, PJE0);
myint = JudyHSDel (PPArray, CIndex, Length, PJE0);
// MACRO EQUIVALENTS:
J1T (myint, PArray, Index);
J1S (myint, PArray, Index);
J1SA (myint, PArray, Index, &Index);
J1U (myint, PArray, Index);
J1F (myint, PArray, Index);
J1N (myint, PArray, Index);
J1L (myint, PArray, Index);
J1P (myint, PArray, Index);
J1FE (myint, PArray, Index);
J1NE (myint, PArray, Index);
J1LE (myint, PArray, Index);
J1PE (myint, PArray, Index);
J1C (myword, PArray, Index, Index);
J1BC (myint, PArray, Index, Index);
J1FA (myword, PArray);
JLG (PPvoid, PArray, Index);
JLI (PPvoid, PArray, Index);
JLIA (myint, PArray, Index, &Index, &Index);
JLD (myint, PArray, Index);
JLF (PPvoid, PArray, Index);
JLN (PPvoid, PArray, Index);
JLL (PPvoid, PArray, Index);
JLP (PPvoid, PArray, Index);
JLFE (myint, PArray, Index);
JLNE (myint, PArray, Index);
JLLE (myint, PArray, Index);
JLPE (myint, PArray, Index);
JLC (myword, PArray, Index, Index);
JLBC (PPvoid, PArray, myword, Index);
JLFA (myword, PArray);
JSLG (PPvoid, PArray, CIndex);
JSLI (PPvoid, PArray, CIndex);
JSLD (myint, PArray, CIndex);
JSLF (PPvoid, PArray, CIndex);
JSLN (PPvoid, PArray, CIndex);
JSLL (PPvoid, PArray, CIndex);
JSLP (PPvoid, PArray, CIndex);
JSLFA (myword, PArray);
JHSI (PPvoid, PArray, CIndex, Length);
JHSG (PPvoid, PArray, CIndex, Length);
JHSD (myint, PArray, CIndex, Length);
return(0);
} // main()

View File

@@ -1,551 +0,0 @@
#ifndef _JUDY1_INCLUDED
#define _JUDY1_INCLUDED
// _________________
//
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.76 $ $Source: /judy/src/Judy1/Judy1.h $
// ****************************************************************************
// JUDY1 -- SMALL/LARGE AND/OR CLUSTERED/SPARSE BIT ARRAYS
//
// -by-
//
// Douglas L. Baskins
// doug@sourcejudy.com
//
// Judy arrays are designed to be used instead of arrays. The performance
// suggests the reason why Judy arrays are thought of as arrays, instead of
// trees. They are remarkably memory efficient at all populations.
// Implemented as a hybrid digital tree (but really a state machine, see
// below), Judy arrays feature fast insert/retrievals, fast near neighbor
// searching, and contain a population tree for extremely fast ordinal related
// retrievals.
//
// CONVENTIONS:
//
// - The comments here refer to 32-bit [64-bit] systems.
//
// - BranchL, LeafL refer to linear branches and leaves (small populations),
// except LeafL does not actually appear as such; rather, Leaf1..3 [Leaf1..7]
// is used to represent leaf Index sizes, and LeafW refers to a Leaf with
// full (long) word Indexes, which is also a type of linear leaf. Note that
// root-level LeafW (Leaf4 [Leaf8]) leaves are also called LEAFW.
//
// - BranchB, LeafB1 refer to bitmap branches and leaves (intermediate
// populations).
//
// - BranchU refers to uncompressed branches. An uncompressed branch has 256
// JPs, some of which could be null. Note: All leaves are compressed (and
// sorted), or else an expanse is full (FullPopu), so there is no LeafU
// equivalent to BranchU.
//
// - "Popu" is short for "Population".
// - "Pop1" refers to actual population (base 1).
// - "Pop0" refers to Pop1 - 1 (base 0), the way populations are stored in data
// structures.
//
// - Branches and Leaves are both named by the number of bytes in their Pop0
// field. In the case of Leaves, the same number applies to the Index sizes.
//
// - The representation of many numbers as hex is a relatively safe and
// portable way to get desired bitpatterns as unsigned longs.
//
// - Some preprocessors cant handle single apostrophe characters within
// #ifndef code, so here, use delete all instead.
#include "JudyPrivate.h" // includes Judy.h in turn.
#include "JudyPrivateBranch.h"
// ****************************************************************************
// JUDY1 ROOT POINTER (JRP) AND JUDY1 POINTER (JP) TYPE FIELDS
// ****************************************************************************
//
// The following enum lists all possible JP Type fields.
typedef enum // uint8_t -- but C does not support this type of enum.
{
// JP NULL TYPES:
//
// There is a series of cJ1_JPNULL* Types because each one pre-records a
// different Index Size for when the first Index is inserted in the previously
// null JP. They must start >= 8 (three bits).
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPNULL1 = 1,
// Index Size 1[1] byte when 1 Index inserted.
cJ1_JPNULL2, // Index Size 2[2] bytes when 1 Index inserted.
cJ1_JPNULL3, // Index Size 3[3] bytes when 1 Index inserted.
#ifndef JU_64BIT
#define cJ1_JPNULLMAX cJ1_JPNULL3
#else
cJ1_JPNULL4, // Index Size 4[4] bytes when 1 Index inserted.
cJ1_JPNULL5, // Index Size 5[5] bytes when 1 Index inserted.
cJ1_JPNULL6, // Index Size 6[6] bytes when 1 Index inserted.
cJ1_JPNULL7, // Index Size 7[7] bytes when 1 Index inserted.
#define cJ1_JPNULLMAX cJ1_JPNULL7
#endif
// JP BRANCH TYPES:
//
// Note: There are no state-1 branches; only leaves reside at state 1.
// Linear branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_L2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_L3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_L4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_L5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_L6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_L7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_L, // note: DcdPopO field not used.
// Bitmap branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_B2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_B3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_B4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_B5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_B6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_B7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_B, // note: DcdPopO field not used.
// Uncompressed branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_U2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_U3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_U4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_U5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_U6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_U7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_U, // note: DcdPopO field not used.
// JP LEAF TYPES:
// Linear leaves:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
//
// Note: There is no cJ1_JPLEAF1 for 64-bit for a subtle reason. An immediate
// JP can hold 15 1-byte Indexes, and a bitmap leaf would be used for 17
// Indexes, so rather than support a linear leaf for only the case of exactly
// 16 Indexes, a bitmap leaf is used in that case. See also below regarding
// cJ1_LEAF1_MAXPOP1 on 64-bit systems.
//
// Note: There is no full-word (4-byte [8-byte]) Index leaf under a JP because
// non-root-state leaves only occur under branches that decode at least one
// byte. Full-word, root-state leaves are under a JRP, not a JP. However, in
// the code a "fake" JP can be created temporarily above a root-state leaf.
#ifndef JU_64BIT // 32-bit only; see above.
cJ1_JPLEAF1, // 1 byte Pop0, 2 bytes Dcd.
#endif
cJ1_JPLEAF2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPLEAF3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPLEAF4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPLEAF5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPLEAF6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPLEAF7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
// Bitmap leaf; Index Size == 1:
//
// Note: These are currently only supported at state 1. At other states the
// bitmap would grow from 256 to 256^2, 256^3, ... bits, which would not be
// efficient..
cJ1_JPLEAF_B1, // 1[1] byte Pop0, 2[6] bytes Dcd.
// Full population; Index Size == 1 virtual leaf:
//
// Note: These are currently only supported at state 1. At other states they
// could be used, but they would be rare and the savings are dubious.
cJ1_JPFULLPOPU1, // 1[1] byte Pop0, 2[6] bytes Dcd.
#ifdef notdef // for future enhancements
cJ1_JPFULLPOPU1m1, // Full Population - 1
cJ1_JPFULLPOPU1m2, // Full Population - 2
cJ1_JPFULLPOPU1m3, // Full Population - 3
cJ1_JPFULLPOPU1m4, // Full Population - 4
cJ1_JPFULLPOPU1m5, // Full Population - 5
cJ1_JPFULLPOPU1m6, // Full Population - 6
cJ1_JPFULLPOPU1m7, // Full Population - 7
#ifdef JU_64BIT
cJ1_JPFULLPOPU1m8, // Full Population - 8
cJ1_JPFULLPOPU1m9, // Full Population - 9
cJ1_JPFULLPOPU1m10, // Full Population - 10
cJ1_JPFULLPOPU1m11, // Full Population - 11
cJ1_JPFULLPOPU1m12, // Full Population - 12
cJ1_JPFULLPOPU1m13, // Full Population - 13
cJ1_JPFULLPOPU1m14, // Full Population - 14
cJ1_JPFULLPOPU1m15, // Full Population - 15
#endif
#endif // notdef -- for future enhancements
// JP IMMEDIATES; leaves (Indexes) stored inside a JP:
//
// The second numeric suffix is the Pop1 for each type. As the Index Size
// increases, the maximum possible population decreases.
//
// Note: These Types must be in sequential order in each group (Index Size),
// and the groups in correct order too, for doing relative calculations between
// them. For example, since these Types enumerate the Pop1 values (unlike
// other JP Types where there is a Pop0 value in the JP), the maximum Pop1 for
// each Index Size is computable.
cJ1_JPIMMED_1_01, // Index Size = 1, Pop1 = 1.
cJ1_JPIMMED_2_01, // Index Size = 2, Pop1 = 1.
cJ1_JPIMMED_3_01, // Index Size = 3, Pop1 = 1.
#ifdef JU_64BIT
cJ1_JPIMMED_4_01, // Index Size = 4, Pop1 = 1.
cJ1_JPIMMED_5_01, // Index Size = 5, Pop1 = 1.
cJ1_JPIMMED_6_01, // Index Size = 6, Pop1 = 1.
cJ1_JPIMMED_7_01, // Index Size = 7, Pop1 = 1.
#endif
cJ1_JPIMMED_1_02, // Index Size = 1, Pop1 = 2.
cJ1_JPIMMED_1_03, // Index Size = 1, Pop1 = 3.
cJ1_JPIMMED_1_04, // Index Size = 1, Pop1 = 4.
cJ1_JPIMMED_1_05, // Index Size = 1, Pop1 = 5.
cJ1_JPIMMED_1_06, // Index Size = 1, Pop1 = 6.
cJ1_JPIMMED_1_07, // Index Size = 1, Pop1 = 7.
#ifdef JU_64BIT
cJ1_JPIMMED_1_08, // Index Size = 1, Pop1 = 8.
cJ1_JPIMMED_1_09, // Index Size = 1, Pop1 = 9.
cJ1_JPIMMED_1_10, // Index Size = 1, Pop1 = 10.
cJ1_JPIMMED_1_11, // Index Size = 1, Pop1 = 11.
cJ1_JPIMMED_1_12, // Index Size = 1, Pop1 = 12.
cJ1_JPIMMED_1_13, // Index Size = 1, Pop1 = 13.
cJ1_JPIMMED_1_14, // Index Size = 1, Pop1 = 14.
cJ1_JPIMMED_1_15, // Index Size = 1, Pop1 = 15.
#endif
cJ1_JPIMMED_2_02, // Index Size = 2, Pop1 = 2.
cJ1_JPIMMED_2_03, // Index Size = 2, Pop1 = 3.
#ifdef JU_64BIT
cJ1_JPIMMED_2_04, // Index Size = 2, Pop1 = 4.
cJ1_JPIMMED_2_05, // Index Size = 2, Pop1 = 5.
cJ1_JPIMMED_2_06, // Index Size = 2, Pop1 = 6.
cJ1_JPIMMED_2_07, // Index Size = 2, Pop1 = 7.
#endif
cJ1_JPIMMED_3_02, // Index Size = 3, Pop1 = 2.
#ifdef JU_64BIT
cJ1_JPIMMED_3_03, // Index Size = 3, Pop1 = 3.
cJ1_JPIMMED_3_04, // Index Size = 3, Pop1 = 4.
cJ1_JPIMMED_3_05, // Index Size = 3, Pop1 = 5.
cJ1_JPIMMED_4_02, // Index Size = 4, Pop1 = 2.
cJ1_JPIMMED_4_03, // Index Size = 4, Pop1 = 3.
cJ1_JPIMMED_5_02, // Index Size = 5, Pop1 = 2.
cJ1_JPIMMED_5_03, // Index Size = 3, Pop1 = 3.
cJ1_JPIMMED_6_02, // Index Size = 6, Pop1 = 2.
cJ1_JPIMMED_7_02, // Index Size = 7, Pop1 = 2.
#endif
// This special Type is merely a sentinel for doing relative calculations.
// This value should not be used in switch statements (to avoid allocating code
// for it), which is also why it appears at the end of the enum list.
cJ1_JPIMMED_CAP
} jp1_Type_t;
// RELATED VALUES:
//
// Index Size (state) for leaf JP, and JP type based on Index Size (state):
#ifndef JU_64BIT // 32-bit
#define J1_LEAFINDEXSIZE(jpType) ((jpType) - cJ1_JPLEAF1 + 1)
#define J1_LEAFTYPE(IndexSize) ((IndexSize) + cJ1_JPLEAF1 - 1)
#else
#define J1_LEAFINDEXSIZE(jpType) ((jpType) - cJ1_JPLEAF2 + 2)
#define J1_LEAFTYPE(IndexSize) ((IndexSize) + cJ1_JPLEAF2 - 2)
#endif
// ****************************************************************************
// JUDY1 POINTER (JP) -- RELATED MACROS AND CONSTANTS
// ****************************************************************************
// MAXIMUM POPULATIONS OF LINEAR LEAVES:
//
// Allow up to 2 cache lines per leaf, with N bytes per index.
//
// J_1_MAXB is the maximum number of bytes (sort of) to allocate per leaf.
// ALLOCSIZES is defined here, not there, for single-point control of these key
// definitions. See JudyTables.c for "TERMINATOR".
#define J_1_MAXB (sizeof(Word_t) * 32)
#define ALLOCSIZES { 3, 5, 7, 11, 15, 23, 32, 47, 64, TERMINATOR } // in words.
#define cJ1_LEAF1_MAXWORDS 5 // Leaf1 max alloc size in words.
// Under JRP (root-state leaves):
//
// Includes a count (Population) word.
//
// Under JP (non-root-state leaves), which have no count (Population) words:
//
// When a 1-byte index leaf grows above cJ1_LEAF1_MAXPOP1 Indexes (bytes),
// the memory chunk required grows to a size where a bitmap is just as
// efficient, so use a bitmap instead for all greater Populations, on both
// 32-bit and 64-bit systems. However, on a 32-bit system this occurs upon
// going from 6 to 8 words (24 to 32 bytes) in the memory chunk, but on a
// 64-bit system this occurs upon going from 2 to 4 words (16 to 32 bytes). It
// would be silly to go from a 15-Index Immediate JP to a 16-Index linear leaf
// to a 17-Index bitmap leaf, so just use a bitmap leaf for 16+ Indexes, which
// means set cJ1_LEAF1_MAXPOP1 to cJ1_IMMED1_MAXPOP1 (15) to cause the
// transition at that point.
//
// Note: cJ1_LEAF1_MAXPOP1 is not used on 64-bit systems.
#ifndef JU_64BIT // 32-bit
#define cJ1_LEAF1_MAXPOP1 (cJ1_LEAF1_MAXWORDS * cJU_BYTESPERWORD)
#define cJ1_LEAF2_MAXPOP1 (J_1_MAXB / 2)
#define cJ1_LEAF3_MAXPOP1 (J_1_MAXB / 3)
#define cJ1_LEAFW_MAXPOP1 ((J_1_MAXB - cJU_BYTESPERWORD) / cJU_BYTESPERWORD)
#else // 64-bit
// #define cJ1_LEAF1_MAXPOP1 // no LEAF1 in 64-bit.
#define cJ1_LEAF2_MAXPOP1 (J_1_MAXB / 2)
#define cJ1_LEAF3_MAXPOP1 (J_1_MAXB / 3)
#define cJ1_LEAF4_MAXPOP1 (J_1_MAXB / 4)
#define cJ1_LEAF5_MAXPOP1 (J_1_MAXB / 5)
#define cJ1_LEAF6_MAXPOP1 (J_1_MAXB / 6)
#define cJ1_LEAF7_MAXPOP1 (J_1_MAXB / 7)
#define cJ1_LEAFW_MAXPOP1 ((J_1_MAXB - cJU_BYTESPERWORD) / cJU_BYTESPERWORD)
#endif
// MAXIMUM POPULATIONS OF IMMEDIATE JPs:
//
// These specify the maximum Population of immediate JPs with various Index
// Sizes (== sizes of remaining undecoded Index bits).
#define cJ1_IMMED1_MAXPOP1 ((sizeof(jp_t) - 1) / 1) // 7 [15].
#define cJ1_IMMED2_MAXPOP1 ((sizeof(jp_t) - 1) / 2) // 3 [7].
#define cJ1_IMMED3_MAXPOP1 ((sizeof(jp_t) - 1) / 3) // 2 [5].
#ifdef JU_64BIT
#define cJ1_IMMED4_MAXPOP1 ((sizeof(jp_t) - 1) / 4) // [3].
#define cJ1_IMMED5_MAXPOP1 ((sizeof(jp_t) - 1) / 5) // [3].
#define cJ1_IMMED6_MAXPOP1 ((sizeof(jp_t) - 1) / 6) // [2].
#define cJ1_IMMED7_MAXPOP1 ((sizeof(jp_t) - 1) / 7) // [2].
#endif
// ****************************************************************************
// JUDY1 BITMAP LEAF (J1LB) SUPPORT
// ****************************************************************************
#define J1_JLB_BITMAP(Pjlb,Subexp) ((Pjlb)->j1lb_Bitmap[Subexp])
typedef struct J__UDY1_BITMAP_LEAF
{
BITMAPL_t j1lb_Bitmap[cJU_NUMSUBEXPL];
} j1lb_t, * Pj1lb_t;
// ****************************************************************************
// MEMORY ALLOCATION SUPPORT
// ****************************************************************************
// ARRAY-GLOBAL INFORMATION:
//
// At the cost of an occasional additional cache fill, this object, which is
// pointed at by a JRP and in turn points to a JP_BRANCH*, carries array-global
// information about a Judy1 array that has sufficient population to amortize
// the cost. The jpm_Pop0 field prevents having to add up the total population
// for the array in insert, delete, and count code. The jpm_JP field prevents
// having to build a fake JP for entry to a state machine; however, the
// jp_DcdPopO field in jpm_JP, being one byte too small, is not used.
//
// Note: Struct fields are ordered to keep "hot" data in the first 8 words
// (see left-margin comments) for machines with 8-word cache lines, and to keep
// sub-word fields together for efficient packing.
typedef struct J_UDY1_POPULATION_AND_MEMORY
{
/* 1 */ Word_t jpm_Pop0; // total population-1 in array.
/* 2 */ jp_t jpm_JP; // JP to first branch; see above.
/* 4 */ Word_t jpm_LastUPop0; // last jpm_Pop0 when convert to BranchU
// Note: Field names match PJError_t for convenience in macros:
/* 7 */ char je_Errno; // one of the enums in Judy.h.
/* 7/8 */ int je_ErrID; // often an internal source line number.
/* 8/9 */ Word_t jpm_TotalMemWords; // words allocated in array.
} j1pm_t, *Pj1pm_t;
// TABLES FOR DETERMINING IF LEAVES HAVE ROOM TO GROW:
//
// These tables indicate if a given memory chunk can support growth of a given
// object into wasted (rounded-up) memory in the chunk. This violates the
// hiddenness of the JudyMalloc code.
//
// Also define macros to hide the details in the code using these tables.
#ifndef JU_64BIT
extern const uint8_t j__1_Leaf1PopToWords[cJ1_LEAF1_MAXPOP1 + 1];
#endif
extern const uint8_t j__1_Leaf2PopToWords[cJ1_LEAF2_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf3PopToWords[cJ1_LEAF3_MAXPOP1 + 1];
#ifdef JU_64BIT
extern const uint8_t j__1_Leaf4PopToWords[cJ1_LEAF4_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf5PopToWords[cJ1_LEAF5_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf6PopToWords[cJ1_LEAF6_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf7PopToWords[cJ1_LEAF7_MAXPOP1 + 1];
#endif
extern const uint8_t j__1_LeafWPopToWords[cJ1_LEAFW_MAXPOP1 + 1];
// Check if increase of population will fit in same leaf:
#ifndef JU_64BIT
#define J1_LEAF1GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF1_MAXPOP1, j__1_Leaf1PopToWords)
#endif
#define J1_LEAF2GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF2_MAXPOP1, j__1_Leaf2PopToWords)
#define J1_LEAF3GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF3_MAXPOP1, j__1_Leaf3PopToWords)
#ifdef JU_64BIT
#define J1_LEAF4GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF4_MAXPOP1, j__1_Leaf4PopToWords)
#define J1_LEAF5GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF5_MAXPOP1, j__1_Leaf5PopToWords)
#define J1_LEAF6GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF6_MAXPOP1, j__1_Leaf6PopToWords)
#define J1_LEAF7GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF7_MAXPOP1, j__1_Leaf7PopToWords)
#endif
#define J1_LEAFWGROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAFW_MAXPOP1, j__1_LeafWPopToWords)
#ifndef JU_64BIT
#define J1_LEAF1POPTOWORDS(Pop1) (j__1_Leaf1PopToWords[Pop1])
#endif
#define J1_LEAF2POPTOWORDS(Pop1) (j__1_Leaf2PopToWords[Pop1])
#define J1_LEAF3POPTOWORDS(Pop1) (j__1_Leaf3PopToWords[Pop1])
#ifdef JU_64BIT
#define J1_LEAF4POPTOWORDS(Pop1) (j__1_Leaf4PopToWords[Pop1])
#define J1_LEAF5POPTOWORDS(Pop1) (j__1_Leaf5PopToWords[Pop1])
#define J1_LEAF6POPTOWORDS(Pop1) (j__1_Leaf6PopToWords[Pop1])
#define J1_LEAF7POPTOWORDS(Pop1) (j__1_Leaf7PopToWords[Pop1])
#endif
#define J1_LEAFWPOPTOWORDS(Pop1) (j__1_LeafWPopToWords[Pop1])
// FUNCTIONS TO ALLOCATE OBJECTS:
Pj1pm_t j__udy1AllocJ1PM(void); // constant size.
Pjbl_t j__udy1AllocJBL( Pj1pm_t); // constant size.
Pjbb_t j__udy1AllocJBB( Pj1pm_t); // constant size.
Pjp_t j__udy1AllocJBBJP(Word_t, Pj1pm_t);
Pjbu_t j__udy1AllocJBU( Pj1pm_t); // constant size.
#ifndef JU_64BIT
Pjll_t j__udy1AllocJLL1( Word_t, Pj1pm_t);
#endif
Pjll_t j__udy1AllocJLL2( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL3( Word_t, Pj1pm_t);
#ifdef JU_64BIT
Pjll_t j__udy1AllocJLL4( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL5( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL6( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL7( Word_t, Pj1pm_t);
#endif
Pjlw_t j__udy1AllocJLW( Word_t ); // no Pj1pm needed.
Pj1lb_t j__udy1AllocJLB1( Pj1pm_t); // constant size.
// FUNCTIONS TO FREE OBJECTS:
void j__udy1FreeJ1PM( Pj1pm_t, Pj1pm_t); // constant size.
void j__udy1FreeJBL( Pjbl_t, Pj1pm_t); // constant size.
void j__udy1FreeJBB( Pjbb_t, Pj1pm_t); // constant size.
void j__udy1FreeJBBJP(Pjp_t, Word_t, Pj1pm_t);
void j__udy1FreeJBU( Pjbu_t, Pj1pm_t); // constant size.
#ifndef JU_64BIT
void j__udy1FreeJLL1( Pjll_t, Word_t, Pj1pm_t);
#endif
void j__udy1FreeJLL2( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL3( Pjll_t, Word_t, Pj1pm_t);
#ifdef JU_64BIT
void j__udy1FreeJLL4( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL5( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL6( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL7( Pjll_t, Word_t, Pj1pm_t);
#endif
void j__udy1FreeJLW( Pjlw_t, Word_t, Pj1pm_t);
void j__udy1FreeJLB1( Pj1lb_t, Pj1pm_t); // constant size.
void j__udy1FreeSM( Pjp_t, Pj1pm_t); // everything below Pjp.
#endif // ! _JUDY1_INCLUDED

View File

@@ -1,114 +0,0 @@
INCLUDES = -I. -I.. -I../JudyCommon/
AM_CFLAGS = -DJUDY1 @WARN_CFLAGS@
noinst_LTLIBRARIES = libJudy1.la libnext.la libprev.la libcount.la libinline.la
libJudy1_la_SOURCES = Judy1Test.c Judy1Tables.c Judy1Set.c Judy1SetArray.c Judy1Unset.c Judy1Cascade.c Judy1Count.c Judy1CreateBranch.c Judy1Decascade.c Judy1First.c Judy1FreeArray.c Judy1InsertBranch.c Judy1MallocIF.c Judy1MemActive.c Judy1MemUsed.c
libnext_la_SOURCES = Judy1Next.c Judy1NextEmpty.c
libnext_la_CFLAGS = $(AM_CFLAGS) -DJUDYNEXT
libprev_la_SOURCES = Judy1Prev.c Judy1PrevEmpty.c
libprev_la_CFLAGS = $(AM_CFLAGS) -DJUDYPREV
libcount_la_SOURCES = Judy1ByCount.c
libcount_la_CFLAGS = $(AM_CFLAGS) -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB
libinline_la_SOURCES = j__udy1Test.c
libinline_la_CFLAGS = $(AM_CFLAGS) -DJUDYGETINLINE
Judy1Tables.c: Judy1TablesGen.c
$(HOSTCC) $(INCLUDES) $(AM_CFLAGS)-DJU_64BIT $(HOSTCCFLAGS) -o Judy1TablesGen Judy1TablesGen.c; ./Judy1TablesGen
Judy1ByCount.c:../JudyCommon/JudyByCount.c
cp -f ../JudyCommon/JudyByCount.c Judy1ByCount.c
Judy1Cascade.c:../JudyCommon/JudyCascade.c
cp -f ../JudyCommon/JudyCascade.c Judy1Cascade.c
Judy1Count.c:../JudyCommon/JudyCount.c
cp -f ../JudyCommon/JudyCount.c Judy1Count.c
Judy1CreateBranch.c:../JudyCommon/JudyCreateBranch.c
cp -f ../JudyCommon/JudyCreateBranch.c Judy1CreateBranch.c
Judy1Decascade.c:../JudyCommon/JudyDecascade.c
cp -f ../JudyCommon/JudyDecascade.c Judy1Decascade.c
Judy1Unset.c:../JudyCommon/JudyDel.c
cp -f ../JudyCommon/JudyDel.c Judy1Unset.c
Judy1First.c:../JudyCommon/JudyFirst.c
cp -f ../JudyCommon/JudyFirst.c Judy1First.c
Judy1FreeArray.c:../JudyCommon/JudyFreeArray.c
cp -f ../JudyCommon/JudyFreeArray.c Judy1FreeArray.c
Judy1Test.c:../JudyCommon/JudyGet.c
cp -f ../JudyCommon/JudyGet.c Judy1Test.c
j__udy1Test.c:../JudyCommon/JudyGet.c
cp -f ../JudyCommon/JudyGet.c j__udy1Test.c
Judy1SetArray.c:../JudyCommon/JudyInsArray.c
cp -f ../JudyCommon/JudyInsArray.c Judy1SetArray.c
Judy1Set.c:../JudyCommon/JudyIns.c
cp -f ../JudyCommon/JudyIns.c Judy1Set.c
Judy1InsertBranch.c:../JudyCommon/JudyInsertBranch.c
cp -f ../JudyCommon/JudyInsertBranch.c Judy1InsertBranch.c
Judy1MallocIF.c:../JudyCommon/JudyMallocIF.c
cp -f ../JudyCommon/JudyMallocIF.c Judy1MallocIF.c
Judy1MemActive.c:../JudyCommon/JudyMemActive.c
cp -f ../JudyCommon/JudyMemActive.c Judy1MemActive.c
Judy1MemUsed.c:../JudyCommon/JudyMemUsed.c
cp -f ../JudyCommon/JudyMemUsed.c Judy1MemUsed.c
Judy1Next.c:../JudyCommon/JudyPrevNext.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Next.c
Judy1Prev.c:../JudyCommon/JudyPrevNext.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Prev.c
Judy1NextEmpty.c:../JudyCommon/JudyPrevNextEmpty.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1NextEmpty.c
Judy1PrevEmpty.c:../JudyCommon/JudyPrevNextEmpty.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1PrevEmpty.c
Judy1TablesGen.c:../JudyCommon/JudyTables.c
cp -f ../JudyCommon/JudyTables.c Judy1TablesGen.c
DISTCLEANFILES = .deps Makefile
CLEANFILES = Judy1ByCount.c \
Judy1Cascade.c \
Judy1Count.c \
Judy1CreateBranch.c \
Judy1Decascade.c \
Judy1Unset.c \
Judy1First.c \
Judy1FreeArray.c \
Judy1Test.c \
j__udy1Test.c \
Judy1SetArray.c \
Judy1Set.c \
Judy1InsertBranch.c \
Judy1MallocIF.c \
Judy1MemActive.c \
Judy1MemUsed.c \
Judy1Next.c \
Judy1Prev.c \
Judy1NextEmpty.c \
Judy1PrevEmpty.c \
Judy1TablesGen.c \
Judy1Tables.c \
.libs \
Judy1TablesGen \
*.o \
*.lo \
*.la

View File

@@ -1,11 +0,0 @@
# @(#) $Revision: 4.22 $ $Source: /judy/src/Judy1/README $
# This tree contains sources for the Judy1*() functions.
#
# Note: At one time, all of the Judy sources were split between Judy1/ and
# JudyL/ variants, but now most of them are merged in JudyCommon/ and this
# directory is vestigal.
Judy1.h header for following functions
lint.waivers see usage in makefile

View File

@@ -1,954 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.28 $ $Source: /judy/src/JudyCommon/JudyByCount.c $
//
// Judy*ByCount() function for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
//
// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a
// version with cache line optimizations deleted, for testing.
//
// Judy*ByCount() is a conceptual although not literal inverse of Judy*Count().
// Judy*Count() takes a pair of Indexes, and allows finding the ordinal of a
// given Index (that is, its position in the list of valid indexes from the
// beginning) as a degenerate case, because in general the count between two
// Indexes, inclusive, is not always just the difference in their ordinals.
// However, it suffices for Judy*ByCount() to simply be an ordinal-to-Index
// mapper.
//
// Note: Like Judy*Count(), this code must "count sideways" in branches, which
// can result in a lot of cache line fills. However, unlike Judy*Count(), this
// code does not receive a specific Index, hence digit, where to start in each
// branch, so it cant accurately calculate cache line fills required in each
// direction. The best it can do is an approximation based on the total
// population of the expanse (pop1 from Pjp) and the ordinal of the target
// Index (see SETOFFSET()) within the expanse.
//
// Compile with -DSMARTMETRICS to obtain global variables containing smart
// cache line metrics. Note: Dont turn this on simultaneously for this file
// and JudyCount.c because they export the same globals.
// ****************************************************************************
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// These are imported from JudyCount.c:
//
// TBD: Should this be in common code? Exported from a header file?
#ifdef JUDY1
extern Word_t j__udy1JPPop1(const Pjp_t Pjp);
#define j__udyJPPop1 j__udy1JPPop1
#else
extern Word_t j__udyLJPPop1(const Pjp_t Pjp);
#define j__udyJPPop1 j__udyLJPPop1
#endif
// Avoid duplicate symbols since this file is multi-compiled:
#ifdef SMARTMETRICS
#ifdef JUDY1
Word_t jbb_upward = 0; // counts of directions taken:
Word_t jbb_downward = 0;
Word_t jbu_upward = 0;
Word_t jbu_downward = 0;
Word_t jlb_upward = 0;
Word_t jlb_downward = 0;
#else
extern Word_t jbb_upward;
extern Word_t jbb_downward;
extern Word_t jbu_upward;
extern Word_t jbu_downward;
extern Word_t jlb_upward;
extern Word_t jlb_downward;
#endif
#endif
// ****************************************************************************
// J U D Y 1 B Y C O U N T
// J U D Y L B Y C O U N T
//
// See the manual entry.
#ifdef JUDY1
FUNCTION int Judy1ByCount
#else
FUNCTION PPvoid_t JudyLByCount
#endif
(
Pcvoid_t PArray, // root pointer to first branch/leaf in SM.
Word_t Count, // ordinal of Index to find, 1..MAX.
Word_t * PIndex, // to return found Index.
PJError_t PJError // optional, for returning error info.
)
{
Word_t Count0; // Count, base-0, to match pop0.
Word_t state; // current state in SM.
Word_t pop1; // of current branch or leaf, or of expanse.
Word_t pop1lower; // pop1 of expanses (JPs) below that for Count.
Word_t digit; // current word in branch.
Word_t jpcount; // JPs in a BranchB subexpanse.
long jpnum; // JP number in a branch (base 0).
long subexp; // for stepping through layer 1 (subexpanses).
int offset; // index ordinal within a leaf, base 0.
Pjp_t Pjp; // current JP in branch.
Pjll_t Pjll; // current Judy linear leaf.
// CHECK FOR EMPTY ARRAY OR NULL PINDEX:
if (PArray == (Pvoid_t) NULL) JU_RET_NOTFOUND;
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Convert Count to Count0; assume special case of Count = 0 maps to ~0, as
// desired, to represent the last index in a full array:
//
// Note: Think of Count0 as a reliable "number of Indexes below the target."
Count0 = Count - 1;
assert((Count || Count0 == ~0)); // ensure CPU is sane about 0 - 1.
pop1lower = 0;
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
if (Count0 > Pjlw[0]) JU_RET_NOTFOUND; // too high.
*PIndex = Pjlw[Count]; // Index, base 1.
JU_RET_FOUND_LEAFW(Pjlw, Pjlw[0] + 1, Count0);
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
if (Count0 > (Pjpm->jpm_Pop0)) JU_RET_NOTFOUND; // too high.
Pjp = &(Pjpm->jpm_JP);
pop1 = (Pjpm->jpm_Pop0) + 1;
// goto SMByCount;
}
// COMMON CODE:
//
// Prepare to handle a root-level or lower-level branch: Save the current
// state, obtain the total population for the branch in a state-dependent way,
// and then branch to common code for multiple cases.
//
// For root-level branches, the state is always cJU_ROOTSTATE, and the array
// population must already be set in pop1; it is not available in jp_DcdPopO.
//
// Note: The total population is only needed in cases where the common code
// "counts down" instead of up to minimize cache line fills. However, its
// available cheaply, and its better to do it with a constant shift (constant
// state value) instead of a variable shift later "when needed".
#define PREPB_ROOT(Next) \
state = cJU_ROOTSTATE; \
goto Next
// Use PREPB_DCD() to first copy the Dcd bytes to *PIndex if there are any
// (only if state < cJU_ROOTSTATE - 1):
#define PREPB_DCD(Pjp,cState,Next) \
JU_SETDCD(*PIndex, Pjp, cState); \
PREPB((Pjp), cState, Next)
#define PREPB(Pjp,cState,Next) \
state = (cState); \
pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \
goto Next
// Calculate whether the ordinal of an Index within a given expanse falls in
// the lower or upper half of the expanses population, taking care with
// unsigned math and boundary conditions:
//
// Note: Assume the ordinal falls within the expanses population, that is,
// 0 < (Count - Pop1lower) <= Pop1exp (assuming infinite math).
//
// Note: If the ordinal is the middle element, it doesnt matter whether
// LOWERHALF() is TRUE or FALSE.
#define LOWERHALF(Count0,Pop1lower,Pop1exp) \
(((Count0) - (Pop1lower)) < ((Pop1exp) / 2))
// Calculate the (signed) offset within a leaf to the desired ordinal (Count -
// Pop1lower; offset is one less), and optionally ensure its in range:
#define SETOFFSET(Offset,Count0,Pop1lower,Pjp) \
(Offset) = (Count0) - (Pop1lower); \
assert((Offset) >= 0); \
assert((Offset) <= JU_JPLEAF_POP0(Pjp))
// Variations for immediate indexes, with and without pop1-specific assertions:
#define SETOFFSET_IMM_CK(Offset,Count0,Pop1lower,cPop1) \
(Offset) = (Count0) - (Pop1lower); \
assert((Offset) >= 0); \
assert((Offset) < (cPop1))
#define SETOFFSET_IMM(Offset,Count0,Pop1lower) \
(Offset) = (Count0) - (Pop1lower)
// STATE MACHINE -- TRAVERSE TREE:
//
// In branches, look for the expanse (digit), if any, where the total pop1
// below or at that expanse would meet or exceed Count, meaning the Index must
// be in this expanse.
SMByCount: // return here for next branch/leaf.
switch (JU_JPTYPE(Pjp))
{
// ----------------------------------------------------------------------------
// LINEAR BRANCH; count populations in JPs in the JBL upwards until finding the
// expanse (digit) containing Count, and "recurse".
//
// Note: There are no null JPs in a JBL; watch out for pop1 == 0.
//
// Note: A JBL should always fit in one cache line => no need to count up
// versus down to save cache line fills.
//
// TBD: The previous is no longer true. Consider enhancing this code to count
// up/down, but it can wait for a later tuning phase. In the meantime, PREPB()
// sets pop1 for the whole array, but that value is not used here. 001215:
// Maybe its true again?
case cJU_JPBRANCH_L2: PREPB_DCD(Pjp, 2, BranchL);
#ifndef JU_64BIT
case cJU_JPBRANCH_L3: PREPB( Pjp, 3, BranchL);
#else
case cJU_JPBRANCH_L3: PREPB_DCD(Pjp, 3, BranchL);
case cJU_JPBRANCH_L4: PREPB_DCD(Pjp, 4, BranchL);
case cJU_JPBRANCH_L5: PREPB_DCD(Pjp, 5, BranchL);
case cJU_JPBRANCH_L6: PREPB_DCD(Pjp, 6, BranchL);
case cJU_JPBRANCH_L7: PREPB( Pjp, 7, BranchL);
#endif
case cJU_JPBRANCH_L: PREPB_ROOT( BranchL);
{
Pjbl_t Pjbl;
// Common code (state-independent) for all cases of linear branches:
BranchL:
Pjbl = P_JBL(Pjp->jp_Addr);
for (jpnum = 0; jpnum < (Pjbl->jbl_NumJPs); ++jpnum)
{
if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, so do not subtract 1 and compare
// >=, but instead use the following expression:
if (pop1lower + pop1 > Count0) // Index is in this expanse.
{
JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[jpnum], state);
Pjp = (Pjbl->jbl_jp) + jpnum;
goto SMByCount; // look under this expanse.
}
pop1lower += pop1; // add this JPs pop1.
}
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_L
// ----------------------------------------------------------------------------
// BITMAP BRANCH; count populations in JPs in the JBB upwards or downwards
// until finding the expanse (digit) containing Count, and "recurse".
//
// Note: There are no null JPs in a JBB; watch out for pop1 == 0.
case cJU_JPBRANCH_B2: PREPB_DCD(Pjp, 2, BranchB);
#ifndef JU_64BIT
case cJU_JPBRANCH_B3: PREPB( Pjp, 3, BranchB);
#else
case cJU_JPBRANCH_B3: PREPB_DCD(Pjp, 3, BranchB);
case cJU_JPBRANCH_B4: PREPB_DCD(Pjp, 4, BranchB);
case cJU_JPBRANCH_B5: PREPB_DCD(Pjp, 5, BranchB);
case cJU_JPBRANCH_B6: PREPB_DCD(Pjp, 6, BranchB);
case cJU_JPBRANCH_B7: PREPB( Pjp, 7, BranchB);
#endif
case cJU_JPBRANCH_B: PREPB_ROOT( BranchB);
{
Pjbb_t Pjbb;
// Common code (state-independent) for all cases of bitmap branches:
BranchB:
Pjbb = P_JBB(Pjp->jp_Addr);
// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch:
//
// Note: BMPJP0 exists separately to support assertions.
#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp)))
#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum))
// Common code for descending through a JP:
//
// Determine the digit for the expanse and save it in *PIndex; then "recurse".
#define JBB_FOUNDEXPANSE \
{ \
JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb,subexp), jpnum); \
JU_SETDIGIT(*PIndex, digit, state); \
Pjp = BMPJP(subexp, jpnum); \
goto SMByCount; \
}
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
// in JPs upwards, or subtracting the pop1s in JPs downwards:
//
// See header comments about limitations of this for Judy*ByCount().
#endif
// COUNT UPWARD, adding each "below" JPs pop1:
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jbb_upward;
#endif
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,subexp)))
&& (BMPJP0(subexp) == (Pjp_t) NULL))
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
for (jpnum = 0; jpnum < jpcount; ++jpnum)
{
if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
JBB_FOUNDEXPANSE; // Index is in this expanse.
pop1lower += pop1; // add this JPs pop1.
}
}
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting each "above" JPs pop1 from the whole expanses
// pop1:
else
{
#ifdef SMARTMETRICS
++jbb_downward;
#endif
pop1lower += pop1; // add whole branch to start.
for (subexp = cJU_NUMSUBEXPB - 1; subexp >= 0; --subexp)
{
if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)))
&& (BMPJP0(subexp) == (Pjp_t) NULL))
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
for (jpnum = jpcount - 1; jpnum >= 0; --jpnum)
{
if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
pop1lower -= pop1;
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
JBB_FOUNDEXPANSE; // Index is in this expanse.
}
}
}
#endif // NOSMARTJBB
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_B
// ----------------------------------------------------------------------------
// UNCOMPRESSED BRANCH; count populations in JPs in the JBU upwards or
// downwards until finding the expanse (digit) containing Count, and "recurse".
case cJU_JPBRANCH_U2: PREPB_DCD(Pjp, 2, BranchU);
#ifndef JU_64BIT
case cJU_JPBRANCH_U3: PREPB( Pjp, 3, BranchU);
#else
case cJU_JPBRANCH_U3: PREPB_DCD(Pjp, 3, BranchU);
case cJU_JPBRANCH_U4: PREPB_DCD(Pjp, 4, BranchU);
case cJU_JPBRANCH_U5: PREPB_DCD(Pjp, 5, BranchU);
case cJU_JPBRANCH_U6: PREPB_DCD(Pjp, 6, BranchU);
case cJU_JPBRANCH_U7: PREPB( Pjp, 7, BranchU);
#endif
case cJU_JPBRANCH_U: PREPB_ROOT( BranchU);
{
Pjbu_t Pjbu;
// Common code (state-independent) for all cases of uncompressed branches:
BranchU:
Pjbu = P_JBU(Pjp->jp_Addr);
// Common code for descending through a JP:
//
// Save the digit for the expanse in *PIndex, then "recurse".
#define JBU_FOUNDEXPANSE \
{ \
JU_SETDIGIT(*PIndex, jpnum, state); \
Pjp = (Pjbu->jbu_jp) + jpnum; \
goto SMByCount; \
}
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
// in JPs upwards, or subtracting the pop1s in JPs downwards:
//
// See header comments about limitations of this for Judy*ByCount().
#endif
// COUNT UPWARD, simply adding the pop1 of each JP:
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jbu_upward;
#endif
for (jpnum = 0; jpnum < cJU_BRANCHUNUMJPS; ++jpnum)
{
// shortcut, save a function call:
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
continue;
if ((pop1 = j__udyJPPop1((Pjbu->jbu_jp) + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
JBU_FOUNDEXPANSE; // Index is in this expanse.
pop1lower += pop1; // add this JPs pop1.
}
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting the pop1 of each JP above from the whole
// expanses pop1:
else
{
#ifdef SMARTMETRICS
++jbu_downward;
#endif
pop1lower += pop1; // add whole branch to start.
for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum >= 0; --jpnum)
{
// shortcut, save a function call:
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
continue;
if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
pop1lower -= pop1;
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
JBU_FOUNDEXPANSE; // Index is in this expanse.
}
}
#endif // NOSMARTJBU
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_U
// ----------------------------------------------------------------------------
// LINEAR LEAF:
//
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf. First
// copy Dcd bytes, if there are any (only if state < cJU_ROOTSTATE - 1), to
// *PIndex.
//
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
// (linear leaf) as a side-effect, but dont depend on that (for JUDYL, which
// is the only cases that need it anyway).
#define PREPL_DCD(cState) \
JU_SETDCD(*PIndex, Pjp, cState); \
PREPL
#ifdef JUDY1
#define PREPL_SETPOP1 // not needed in any cases.
#else
#define PREPL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1
#endif
#define PREPL \
Pjll = P_JLL(Pjp->jp_Addr); \
PREPL_SETPOP1; \
SETOFFSET(offset, Count0, pop1lower, Pjp)
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1:
PREPL_DCD(1);
JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
#endif
case cJU_JPLEAF2:
PREPL_DCD(2);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
| ((uint16_t *) Pjll)[offset];
JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
#ifndef JU_64BIT
case cJU_JPLEAF3:
{
Word_t lsb;
PREPL;
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
}
#else
case cJU_JPLEAF3:
{
Word_t lsb;
PREPL_DCD(3);
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
}
case cJU_JPLEAF4:
PREPL_DCD(4);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
| ((uint32_t *) Pjll)[offset];
JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
case cJU_JPLEAF5:
{
Word_t lsb;
PREPL_DCD(5);
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
}
case cJU_JPLEAF6:
{
Word_t lsb;
PREPL_DCD(6);
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
}
case cJU_JPLEAF7:
{
Word_t lsb;
PREPL;
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
}
#endif
// ----------------------------------------------------------------------------
// BITMAP LEAF:
//
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf by
// counting bits. First copy Dcd bytes (always present since state 1 <
// cJU_ROOTSTATE) to *PIndex.
//
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
// (bitmap leaf) as a side-effect, but dont depend on that.
case cJU_JPLEAF_B1:
{
Pjlb_t Pjlb;
JU_SETDCD(*PIndex, Pjp, 1);
Pjlb = P_JLB(Pjp->jp_Addr);
pop1 = JU_JPLEAF_POP0(Pjp) + 1;
// COUNT UPWARD, adding the pop1 of each subexpanse:
//
// The entire bitmap should fit in one cache line, but still try to save some
// CPU time by counting the fewest possible number of subexpanses from the
// bitmap.
//
// See header comments about limitations of this for Judy*ByCount().
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jlb_upward;
#endif
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
{
pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
goto LeafB1; // Index is in this subexpanse.
pop1lower += pop1; // add this subexpanses pop1.
}
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting each "above" subexpanses pop1 from the whole
// expanses pop1:
else
{
#ifdef SMARTMETRICS
++jlb_downward;
#endif
pop1lower += pop1; // add whole leaf to start.
for (subexp = cJU_NUMSUBEXPL - 1; subexp >= 0; --subexp)
{
pop1lower -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
goto LeafB1; // Index is in this subexpanse.
}
}
#endif // NOSMARTJLB
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
// RETURN INDEX FOUND:
//
// Come here with subexp set to the correct subexpanse, and pop1lower set to
// the sum for all lower expanses and subexpanses in the Judy tree. Calculate
// and save in *PIndex the digit corresponding to the ordinal in this
// subexpanse.
LeafB1:
SETOFFSET(offset, Count0, pop1lower, Pjp);
JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
JU_SETDIGIT1(*PIndex, digit);
JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + offset))
} // case cJU_JPLEAF_B1
#ifdef JUDY1
// ----------------------------------------------------------------------------
// FULL POPULATION:
//
// Copy Dcd bytes (always present since state 1 < cJU_ROOTSTATE) to *PIndex,
// then set the appropriate digit for the ordinal (see SETOFFSET()) in the leaf
// as the LSB in *PIndex.
case cJ1_JPFULLPOPU1:
JU_SETDCD(*PIndex, Pjp, 1);
SETOFFSET(offset, Count0, pop1lower, Pjp);
assert(offset >= 0);
assert(offset <= cJU_JPFULLPOPU1_POP0);
JU_SETDIGIT1(*PIndex, offset);
JU_RET_FOUND_FULLPOPU1;
#endif
// ----------------------------------------------------------------------------
// IMMEDIATE:
//
// Locate the Index with the proper ordinal (see SETOFFSET()) in the Immediate,
// depending on leaf Index Size and pop1. Note: There are no Dcd bytes in an
// Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the least bytes
// of the immediate Index.
#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState)
case cJU_JPIMMED_1_01: SET_01(1); goto Imm_01;
case cJU_JPIMMED_2_01: SET_01(2); goto Imm_01;
case cJU_JPIMMED_3_01: SET_01(3); goto Imm_01;
#ifdef JU_64BIT
case cJU_JPIMMED_4_01: SET_01(4); goto Imm_01;
case cJU_JPIMMED_5_01: SET_01(5); goto Imm_01;
case cJU_JPIMMED_6_01: SET_01(6); goto Imm_01;
case cJU_JPIMMED_7_01: SET_01(7); goto Imm_01;
#endif
Imm_01:
DBGCODE(SETOFFSET_IMM_CK(offset, Count0, pop1lower, 1);)
JU_RET_FOUND_IMM_01(Pjp);
// Shorthand for where to find start of Index bytes array:
#ifdef JUDY1
#define PJI (Pjp->jp_1Index)
#else
#define PJI (Pjp->jp_LIndex)
#endif
// Optional code to check the remaining ordinal (see SETOFFSET_IMM()) against
// the Index Size of the Immediate:
#ifndef DEBUG // simple placeholder:
#define IMM(cPop1,Next) \
goto Next
#else // extra pop1-specific checking:
#define IMM(cPop1,Next) \
SETOFFSET_IMM_CK(offset, Count0, pop1lower, cPop1); \
goto Next
#endif
case cJU_JPIMMED_1_02: IMM( 2, Imm1);
case cJU_JPIMMED_1_03: IMM( 3, Imm1);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_1_04: IMM( 4, Imm1);
case cJU_JPIMMED_1_05: IMM( 5, Imm1);
case cJU_JPIMMED_1_06: IMM( 6, Imm1);
case cJU_JPIMMED_1_07: IMM( 7, Imm1);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_1_08: IMM( 8, Imm1);
case cJ1_JPIMMED_1_09: IMM( 9, Imm1);
case cJ1_JPIMMED_1_10: IMM(10, Imm1);
case cJ1_JPIMMED_1_11: IMM(11, Imm1);
case cJ1_JPIMMED_1_12: IMM(12, Imm1);
case cJ1_JPIMMED_1_13: IMM(13, Imm1);
case cJ1_JPIMMED_1_14: IMM(14, Imm1);
case cJ1_JPIMMED_1_15: IMM(15, Imm1);
#endif
Imm1: SETOFFSET_IMM(offset, Count0, pop1lower);
JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
JU_RET_FOUND_IMM(Pjp, offset);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_2_02: IMM(2, Imm2);
case cJU_JPIMMED_2_03: IMM(3, Imm2);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_2_04: IMM(4, Imm2);
case cJ1_JPIMMED_2_05: IMM(5, Imm2);
case cJ1_JPIMMED_2_06: IMM(6, Imm2);
case cJ1_JPIMMED_2_07: IMM(7, Imm2);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
Imm2: SETOFFSET_IMM(offset, Count0, pop1lower);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
| ((uint16_t *) PJI)[offset];
JU_RET_FOUND_IMM(Pjp, offset);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_3_02: IMM(2, Imm3);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_3_03: IMM(3, Imm3);
case cJ1_JPIMMED_3_04: IMM(4, Imm3);
case cJ1_JPIMMED_3_05: IMM(5, Imm3);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
Imm3:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_4_02: IMM(2, Imm4);
case cJ1_JPIMMED_4_03: IMM(3, Imm4);
Imm4: SETOFFSET_IMM(offset, Count0, pop1lower);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
| ((uint32_t *) PJI)[offset];
JU_RET_FOUND_IMM(Pjp, offset);
case cJ1_JPIMMED_5_02: IMM(2, Imm5);
case cJ1_JPIMMED_5_03: IMM(3, Imm5);
Imm5:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
case cJ1_JPIMMED_6_02: IMM(2, Imm6);
Imm6:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
case cJ1_JPIMMED_7_02: IMM(2, Imm7);
Imm7:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
#endif // (JUDY1 && JU_64BIT)
// ----------------------------------------------------------------------------
// UNEXPECTED JP TYPES:
default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // SMByCount switch.
/*NOTREACHED*/
} // Judy1ByCount() / JudyLByCount()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,314 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.26 $ $Source: /judy/src/JudyCommon/JudyCreateBranch.c $
// Branch creation functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// ****************************************************************************
// J U D Y C R E A T E B R A N C H L
//
// Build a BranchL from an array of JPs and associated 1 byte digits
// (expanses). Return with Pjp pointing to the BranchL. Caller must
// deallocate passed arrays, if necessary.
//
// We have no idea what kind of BranchL it is, so caller must set the jp_Type.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchL(
Pjp_t Pjp, // Build JPs from this place
Pjp_t PJPs, // Array of JPs to put into Bitmap branch
uint8_t Exp[], // Array of expanses to put into bitmap
Word_t ExpCnt, // Number of above JPs and Expanses
Pvoid_t Pjpm)
{
Pjbl_t PjblRaw; // pointer to linear branch.
Pjbl_t Pjbl;
assert(ExpCnt <= cJU_BRANCHLMAXJPS);
PjblRaw = j__udyAllocJBL(Pjpm);
if (PjblRaw == (Pjbl_t) NULL) return(-1);
Pjbl = P_JBL(PjblRaw);
// Build a Linear Branch
Pjbl->jbl_NumJPs = ExpCnt;
// Copy from the Linear branch from splayed leaves
JU_COPYMEM(Pjbl->jbl_Expanse, Exp, ExpCnt);
JU_COPYMEM(Pjbl->jbl_jp, PJPs, ExpCnt);
// Pass back new pointer to the Linear branch in JP
Pjp->jp_Addr = (Word_t) PjblRaw;
return(1);
} // j__udyCreateBranchL()
// ****************************************************************************
// J U D Y C R E A T E B R A N C H B
//
// Build a BranchB from an array of JPs and associated 1 byte digits
// (expanses). Return with Pjp pointing to the BranchB. Caller must
// deallocate passed arrays, if necessary.
//
// We have no idea what kind of BranchB it is, so caller must set the jp_Type.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchB(
Pjp_t Pjp, // Build JPs from this place
Pjp_t PJPs, // Array of JPs to put into Bitmap branch
uint8_t Exp[], // Array of expanses to put into bitmap
Word_t ExpCnt, // Number of above JPs and Expanses
Pvoid_t Pjpm)
{
Pjbb_t PjbbRaw; // pointer to bitmap branch.
Pjbb_t Pjbb;
Word_t ii, jj; // Temps
uint8_t CurrSubExp; // Current sub expanse for BM
// This assertion says the number of populated subexpanses is not too large.
// This function is only called when a BranchL overflows to a BranchB or when a
// cascade occurs, meaning a leaf overflows. Either way ExpCnt cant be very
// large, in fact a lot smaller than cJU_BRANCHBMAXJPS. (Otherwise a BranchU
// would be used.) Popping this assertion means something (unspecified) has
// gone very wrong, or else Judys design criteria have changed, although in
// fact there should be no HARM in creating a BranchB with higher actual
// fanout.
assert(ExpCnt <= cJU_BRANCHBMAXJPS);
// Get memory for a Bitmap branch
PjbbRaw = j__udyAllocJBB(Pjpm);
if (PjbbRaw == (Pjbb_t) NULL) return(-1);
Pjbb = P_JBB(PjbbRaw);
// Get 1st "sub" expanse (0..7) of bitmap branch
CurrSubExp = Exp[0] / cJU_BITSPERSUBEXPB;
// Index thru all 1 byte sized expanses:
for (jj = ii = 0; ii <= ExpCnt; ii++)
{
Word_t SubExp; // Cannot be a uint8_t
// Make sure we cover the last one
if (ii == ExpCnt)
{
SubExp = cJU_ALLONES; // Force last one
}
else
{
// Calculate the "sub" expanse of the byte expanse
SubExp = Exp[ii] / cJU_BITSPERSUBEXPB; // Bits 5..7.
// Set the bit that represents the expanse in Exp[]
JU_JBB_BITMAP(Pjbb, SubExp) |= JU_BITPOSMASKB(Exp[ii]);
}
// Check if a new "sub" expanse range needed
if (SubExp != CurrSubExp)
{
// Get number of JPs in this sub expanse
Word_t NumJP = ii - jj;
Pjp_t PjpRaw;
Pjp_t Pjp;
PjpRaw = j__udyAllocJBBJP(NumJP, Pjpm);
Pjp = P_JP(PjpRaw);
if (PjpRaw == (Pjp_t) NULL) // out of memory.
{
// Free any previous allocations:
while(CurrSubExp--)
{
NumJP = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,
CurrSubExp));
if (NumJP)
{
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb,
CurrSubExp), NumJP, Pjpm);
}
}
j__udyFreeJBB(PjbbRaw, Pjpm);
return(-1);
}
// Place the array of JPs in bitmap branch:
JU_JBB_PJP(Pjbb, CurrSubExp) = PjpRaw;
// Copy the JPs to new leaf:
JU_COPYMEM(Pjp, PJPs + jj, NumJP);
// On to the next bitmap branch "sub" expanse:
jj = ii;
CurrSubExp = SubExp;
}
} // for each 1-byte expanse
// Pass back some of the JP to the new Bitmap branch:
Pjp->jp_Addr = (Word_t) PjbbRaw;
return(1);
} // j__udyCreateBranchB()
// ****************************************************************************
// J U D Y C R E A T E B R A N C H U
//
// Build a BranchU from a BranchB. Return with Pjp pointing to the BranchU.
// Free the BranchB and its JP subarrays.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchU(
Pjp_t Pjp,
Pvoid_t Pjpm)
{
jp_t JPNull;
Pjbu_t PjbuRaw;
Pjbu_t Pjbu;
Pjbb_t PjbbRaw;
Pjbb_t Pjbb;
Word_t ii, jj;
BITMAPB_t BitMap;
Pjp_t PDstJP;
#ifdef JU_STAGED_EXP
jbu_t BranchU; // Staged uncompressed branch
#else
// Allocate memory for a BranchU:
PjbuRaw = j__udyAllocJBU(Pjpm);
if (PjbuRaw == (Pjbu_t) NULL) return(-1);
Pjbu = P_JBU(PjbuRaw);
#endif
JU_JPSETADT(&JPNull, 0, 0, JU_JPTYPE(Pjp) - cJU_JPBRANCH_B2 + cJU_JPNULL1);
// Get the pointer to the BranchB:
PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
Pjbb = P_JBB(PjbbRaw);
// Set the pointer to the Uncompressed branch
#ifdef JU_STAGED_EXP
PDstJP = BranchU.jbu_jp;
#else
PDstJP = Pjbu->jbu_jp;
#endif
for (ii = 0; ii < cJU_NUMSUBEXPB; ii++)
{
Pjp_t PjpA;
Pjp_t PjpB;
PjpB = PjpA = P_JP(JU_JBB_PJP(Pjbb, ii));
// Get the bitmap for this subexpanse
BitMap = JU_JBB_BITMAP(Pjbb, ii);
// NULL empty subexpanses
if (BitMap == 0)
{
// But, fill with NULLs
for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
{
PDstJP[jj] = JPNull;
}
PDstJP += cJU_BITSPERSUBEXPB;
continue;
}
// Check if Uncompressed subexpanse
if (BitMap == cJU_FULLBITMAPB)
{
// Copy subexpanse to the Uncompressed branch intact
JU_COPYMEM(PDstJP, PjpA, cJU_BITSPERSUBEXPB);
// Bump to next subexpanse
PDstJP += cJU_BITSPERSUBEXPB;
// Set length of subexpanse
jj = cJU_BITSPERSUBEXPB;
}
else
{
for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
{
// Copy JP or NULLJP depending on bit
if (BitMap & 1) { *PDstJP = *PjpA++; }
else { *PDstJP = JPNull; }
PDstJP++; // advance to next JP
BitMap >>= 1;
}
jj = PjpA - PjpB;
}
// Free the subexpanse:
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, ii), jj, Pjpm);
} // for each JP in BranchU
#ifdef JU_STAGED_EXP
// Allocate memory for a BranchU:
PjbuRaw = j__udyAllocJBU(Pjpm);
if (PjbuRaw == (Pjbu_t) NULL) return(-1);
Pjbu = P_JBU(PjbuRaw);
// Copy staged branch to newly allocated branch:
//
// TBD: I think this code is broken.
*Pjbu = BranchU;
#endif // JU_STAGED_EXP
// Finally free the BranchB and put the BranchU in its place:
j__udyFreeJBB(PjbbRaw, Pjpm);
Pjp->jp_Addr = (Word_t) PjbuRaw;
Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_B;
return(1);
} // j__udyCreateBranchU()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,213 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.12 $ $Source: /judy/src/JudyCommon/JudyFirst.c $
//
// Judy*First[Empty]() and Judy*Last[Empty]() routines for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
//
// These are inclusive versions of Judy*Next[Empty]() and Judy*Prev[Empty]().
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
// ****************************************************************************
// J U D Y 1 F I R S T
// J U D Y L F I R S T
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1First
#else
FUNCTION PPvoid_t JudyLFirst
#endif
(
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError // optional, for returning error info.
)
{
if (PIndex == (PWord_t) NULL) // caller error:
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 1: return(1); // found *PIndex itself.
case 0: return(Judy1Next(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(PPJERR);
if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
return(JudyLNext(PArray, PIndex, PJError));
}
#endif
} // Judy1First() / JudyLFirst()
// ****************************************************************************
// J U D Y 1 L A S T
// J U D Y L L A S T
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1Last(
#else
FUNCTION PPvoid_t JudyLLast(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 1: return(1); // found *PIndex itself.
case 0: return(Judy1Prev(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(PPJERR);
if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
return(JudyLPrev(PArray, PIndex, PJError));
}
#endif
} // Judy1Last() / JudyLLast()
// ****************************************************************************
// J U D Y 1 F I R S T E M P T Y
// J U D Y L F I R S T E M P T Y
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1FirstEmpty(
#else
FUNCTION int JudyLFirstEmpty(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL) // caller error:
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
return(JERRI);
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 0: return(1); // found *PIndex itself.
case 1: return(Judy1NextEmpty(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(JERRI);
if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
return(JudyLNextEmpty(PArray, PIndex, PJError));
}
#endif
} // Judy1FirstEmpty() / JudyLFirstEmpty()
// ****************************************************************************
// J U D Y 1 L A S T E M P T Y
// J U D Y L L A S T E M P T Y
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1LastEmpty(
#else
FUNCTION int JudyLLastEmpty(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
return(JERRI);
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 0: return(1); // found *PIndex itself.
case 1: return(Judy1PrevEmpty(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(JERRI);
if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
return(JudyLPrevEmpty(PArray, PIndex, PJError));
}
#endif
} // Judy1LastEmpty() / JudyLLastEmpty()

View File

@@ -1,363 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.51 $ $Source: /judy/src/JudyCommon/JudyFreeArray.c $
//
// Judy1FreeArray() and JudyLFreeArray() functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
// Return the number of bytes freed from the array.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
// ****************************************************************************
// J U D Y 1 F R E E A R R A Y
// J U D Y L F R E E A R R A Y
//
// See the Judy*(3C) manual entry for details.
//
// This code is written recursively, at least at first, because thats much
// simpler. Hope its fast enough.
#ifdef JUDY1
FUNCTION Word_t Judy1FreeArray
#else
FUNCTION Word_t JudyLFreeArray
#endif
(
PPvoid_t PPArray, // array to free.
PJError_t PJError // optional, for returning error info.
)
{
jpm_t jpm; // local to accumulate free statistics.
// CHECK FOR NULL POINTER (error by caller):
if (PPArray == (PPvoid_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
return(JERR);
}
DBGCODE(JudyCheckPop(*PPArray);)
// Zero jpm.jpm_Pop0 (meaning the array will be empty in a moment) for accurate
// logging in TRACEMI2.
jpm.jpm_Pop0 = 0; // see above.
jpm.jpm_TotalMemWords = 0; // initialize memory freed.
// Empty array:
if (P_JLW(*PPArray) == (Pjlw_t) NULL) return(0);
// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAF:
if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
j__udyFreeJLW(Pjlw, Pjlw[0] + 1, &jpm);
*PPArray = (Pvoid_t) NULL; // make an empty array.
return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD)); // see above.
}
else
// Rootstate leaves: just free the leaf:
// Common code for returning the amount of memory freed.
//
// Note: In a an ordinary LEAFW, pop0 = *PPArray[0].
//
// Accumulate (negative) words freed, while freeing objects.
// Return the positive bytes freed.
{
Pjpm_t Pjpm = P_JPM(*PPArray);
Word_t TotalMem = Pjpm->jpm_TotalMemWords;
j__udyFreeSM(&(Pjpm->jpm_JP), &jpm); // recurse through tree.
j__udyFreeJPM(Pjpm, &jpm);
// Verify the array was not corrupt. This means that amount of memory freed
// (which is negative) is equal to the initial amount:
if (TotalMem + jpm.jpm_TotalMemWords)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
return(JERR);
}
*PPArray = (Pvoid_t) NULL; // make an empty array.
return (TotalMem * cJU_BYTESPERWORD);
}
} // Judy1FreeArray() / JudyLFreeArray()
// ****************************************************************************
// __ J U D Y F R E E S M
//
// Given a pointer to a JP, recursively visit and free (depth first) all nodes
// in a Judy array BELOW the JP, but not the JP itself. Accumulate in *Pjpm
// the total words freed (as a negative value). "SM" = State Machine.
//
// Note: Corruption is not detected at this level because during a FreeArray,
// if the code hasnt already core dumped, its better to remain silent, even
// if some memory has not been freed, than to bother the caller about the
// corruption. TBD: Is this true? If not, must list all legitimate JPNULL
// and JPIMMED above first, and revert to returning bool_t (see 4.34).
FUNCTION void j__udyFreeSM(
Pjp_t Pjp, // top of Judy (top-state).
Pjpm_t Pjpm) // to return words freed.
{
Word_t Pop1;
switch (JU_JPTYPE(Pjp))
{
#ifdef JUDY1
// FULL EXPANSE -- nothing to free for this jp_Type.
case cJ1_JPFULLPOPU1:
break;
#endif
// JUDY BRANCH -- free the sub-tree depth first:
// LINEAR BRANCH -- visit each JP in the JBLs list, then free the JBL:
//
// Note: There are no null JPs in a JBL.
case cJU_JPBRANCH_L:
case cJU_JPBRANCH_L2:
case cJU_JPBRANCH_L3:
#ifdef JU_64BIT
case cJU_JPBRANCH_L4:
case cJU_JPBRANCH_L5:
case cJU_JPBRANCH_L6:
case cJU_JPBRANCH_L7:
#endif // JU_64BIT
{
Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
Word_t offset;
for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
j__udyFreeSM((Pjbl->jbl_jp) + offset, Pjpm);
j__udyFreeJBL((Pjbl_t) (Pjp->jp_Addr), Pjpm);
break;
}
// BITMAP BRANCH -- visit each JP in the JBBs list based on the bitmap, also
//
// Note: There are no null JPs in a JBB.
case cJU_JPBRANCH_B:
case cJU_JPBRANCH_B2:
case cJU_JPBRANCH_B3:
#ifdef JU_64BIT
case cJU_JPBRANCH_B4:
case cJU_JPBRANCH_B5:
case cJU_JPBRANCH_B6:
case cJU_JPBRANCH_B7:
#endif // JU_64BIT
{
Word_t subexp;
Word_t offset;
Word_t jpcount;
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
if (jpcount)
{
for (offset = 0; offset < jpcount; ++offset)
{
j__udyFreeSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + offset,
Pjpm);
}
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, subexp), jpcount, Pjpm);
}
}
j__udyFreeJBB((Pjbb_t) (Pjp->jp_Addr), Pjpm);
break;
}
// UNCOMPRESSED BRANCH -- visit each JP in the JBU array, then free the JBU
// itself:
//
// Note: Null JPs are handled during recursion at a lower state.
case cJU_JPBRANCH_U:
case cJU_JPBRANCH_U2:
case cJU_JPBRANCH_U3:
#ifdef JU_64BIT
case cJU_JPBRANCH_U4:
case cJU_JPBRANCH_U5:
case cJU_JPBRANCH_U6:
case cJU_JPBRANCH_U7:
#endif // JU_64BIT
{
Word_t offset;
Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
j__udyFreeSM((Pjbu->jbu_jp) + offset, Pjpm);
j__udyFreeJBU((Pjbu_t) (Pjp->jp_Addr), Pjpm);
break;
}
// -- Cases below here terminate and do not recurse. --
// LINEAR LEAF -- just free the leaf; size is computed from jp_Type:
//
// Note: cJU_JPLEAF1 is a special case, see discussion in ../Judy1/Judy1.h
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#endif
case cJU_JPLEAF2:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF3:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#ifdef JU_64BIT
case cJU_JPLEAF4:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF5:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF6:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF7:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#endif // JU_64BIT
// BITMAP LEAF -- free sub-expanse arrays of JPs, then free the JBB.
case cJU_JPLEAF_B1:
{
#ifdef JUDYL
Word_t subexp;
Word_t jpcount;
Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr);
// Free the value areas in the bitmap leaf:
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
{
jpcount = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
if (jpcount)
j__udyLFreeJV(JL_JLB_PVALUE(Pjlb, subexp), jpcount, Pjpm);
}
#endif // JUDYL
j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm);
break;
} // case cJU_JPLEAF_B1
#ifdef JUDYL
// IMMED*:
//
// For JUDYL, all non JPIMMED_*_01s have a LeafV which must be freed:
case cJU_JPIMMED_1_02:
case cJU_JPIMMED_1_03:
#ifdef JU_64BIT
case cJU_JPIMMED_1_04:
case cJU_JPIMMED_1_05:
case cJU_JPIMMED_1_06:
case cJU_JPIMMED_1_07:
#endif
Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2;
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#ifdef JU_64BIT
case cJU_JPIMMED_2_02:
case cJU_JPIMMED_2_03:
Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2;
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPIMMED_3_02:
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), 2, Pjpm);
break;
#endif // JU_64BIT
#endif // JUDYL
// OTHER JPNULL, JPIMMED, OR UNEXPECTED TYPE -- nothing to free for this type:
//
// Note: Lump together no-op and invalid JP types; see function header
// comments.
default: break;
} // switch (JU_JPTYPE(Pjp))
} // j__udyFreeSM()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,135 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.17 $ $Source: /judy/src/JudyCommon/JudyInsertBranch.c $
// BranchL insertion functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
extern int j__udyCreateBranchL(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
// ****************************************************************************
// __ J U D Y I N S E R T B R A N C H
//
// Insert 2-element BranchL in between Pjp and Pjp->jp_Addr.
//
// Return -1 if out of memory, otherwise return 1.
FUNCTION int j__udyInsertBranch(
Pjp_t Pjp, // JP containing narrow pointer.
Word_t Index, // outlier to Pjp.
Word_t BranchLevel, // of what JP points to, mapped from JP type.
Pjpm_t Pjpm) // for global accounting.
{
jp_t JP2 [2];
jp_t JP;
Pjp_t PjpNull;
Word_t XorExp;
Word_t Inew, Iold;
Word_t DCDMask; // initially for original BranchLevel.
int Ret;
uint8_t Exp2[2];
uint8_t DecodeByteN, DecodeByteO;
// Get the current mask for the DCD digits:
DCDMask = cJU_DCDMASK(BranchLevel);
// Obtain Dcd bits that differ between Index and JP, shifted so the
// digit for BranchLevel is the LSB:
XorExp = ((Index ^ JU_JPDCDPOP0(Pjp)) & (cJU_ALLONES >> cJU_BITSPERBYTE))
>> (BranchLevel * cJU_BITSPERBYTE);
assert(XorExp); // Index must be an outlier.
// Count levels between object under narrow pointer and the level at which
// the outlier diverges from it, which is always at least initial
// BranchLevel + 1, to end up with the level (JP type) at which to insert
// the new intervening BranchL:
do { ++BranchLevel; } while ((XorExp >>= cJU_BITSPERBYTE));
assert((BranchLevel > 1) && (BranchLevel < cJU_ROOTSTATE));
// Get the MSB (highest digit) that differs between the old expanse and
// the new Index to insert:
DecodeByteO = JU_DIGITATSTATE(JU_JPDCDPOP0(Pjp), BranchLevel);
DecodeByteN = JU_DIGITATSTATE(Index, BranchLevel);
assert(DecodeByteO != DecodeByteN);
// Determine sorted order for old expanse and new Index digits:
if (DecodeByteN > DecodeByteO) { Iold = 0; Inew = 1; }
else { Iold = 1; Inew = 0; }
// Copy old JP into staging area for new Branch
JP2 [Iold] = *Pjp;
Exp2[Iold] = DecodeByteO;
Exp2[Inew] = DecodeByteN;
// Create a 2 Expanse Linear branch
//
// Note: Pjp->jp_Addr is set by j__udyCreateBranchL()
Ret = j__udyCreateBranchL(Pjp, JP2, Exp2, 2, Pjpm);
if (Ret == -1) return(-1);
// Get Pjp to the NULL of where to do insert
PjpNull = ((P_JBL(Pjp->jp_Addr))->jbl_jp) + Inew;
// Convert to a cJU_JPIMMED_*_01 at the correct level:
// Build JP and set type below to: cJU_JPIMMED_X_01
JU_JPSETADT(PjpNull, 0, Index, cJU_JPIMMED_1_01 - 2 + BranchLevel);
// Return pointer to Value area in cJU_JPIMMED_X_01
JUDYLCODE(Pjpm->jpm_PValue = (Pjv_t) PjpNull;)
// The old JP now points to a BranchL that is at higher level. Therefore
// it contains excess DCD bits (in the least significant position) that
// must be removed (zeroed); that is, they become part of the Pop0
// subfield. Note that the remaining (lower) bytes in the Pop0 field do
// not change.
//
// Take from the old DCDMask, which went "down" to a lower BranchLevel,
// and zero any high bits that are still in the mask at the new, higher
// BranchLevel; then use this mask to zero the bits in jp_DcdPopO:
// Set old JP to a BranchL at correct level
Pjp->jp_Type = cJU_JPBRANCH_L2 - 2 + BranchLevel;
DCDMask ^= cJU_DCDMASK(BranchLevel);
DCDMask = ~DCDMask & JU_JPDCDPOP0(Pjp);
JP = *Pjp;
JU_JPSETADT(Pjp, JP.jp_Addr, DCDMask, JP.jp_Type);
return(1);
} // j__udyInsertBranch()

View File

@@ -1,87 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.33 $ $Source: /judy/src/JudyCommon/JudyMalloc.c $
// ************************************************************************ //
// JUDY - Memory Allocater //
// -by- //
// Douglas L. Baskins //
// Hewlett Packard //
// Fort Collins, Co //
// (970) 229-2027 //
// //
// ************************************************************************ //
// JUDY INCLUDE FILES
#include "Judy.h"
// ****************************************************************************
// J U D Y M A L L O C
//
// Allocate RAM. This is the single location in Judy code that calls
// malloc(3C). Note: JPM accounting occurs at a higher level.
Word_t JudyMalloc(
Word_t Words)
{
Word_t Addr;
Addr = (Word_t) malloc(Words * sizeof(Word_t));
return(Addr);
} // JudyMalloc()
// ****************************************************************************
// J U D Y F R E E
void JudyFree(
void * PWord,
Word_t Words)
{
(void) Words;
free(PWord);
} // JudyFree()
// ****************************************************************************
// J U D Y M A L L O C
//
// Higher-level "wrapper" for allocating objects that need not be in RAM,
// although at this time they are in fact only in RAM. Later we hope that some
// entire subtrees (at a JPM or branch) can be "virtual", so their allocations
// and frees should go through this level.
Word_t JudyMallocVirtual(
Word_t Words)
{
return(JudyMalloc(Words));
} // JudyMallocVirtual()
// ****************************************************************************
// J U D Y F R E E
void JudyFreeVirtual(
void * PWord,
Word_t Words)
{
JudyFree(PWord, Words);
} // JudyFreeVirtual()

View File

@@ -1,782 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.45 $ $Source: /judy/src/JudyCommon/JudyMallocIF.c $
//
// Judy malloc/free interface functions for Judy1 and JudyL.
//
// Compile with one of -DJUDY1 or -DJUDYL.
//
// Compile with -DTRACEMI (Malloc Interface) to turn on tracing of malloc/free
// calls at the interface level. (See also TRACEMF in lower-level code.)
// Use -DTRACEMI2 for a terser format suitable for trace analysis.
//
// There can be malloc namespace bits in the LSBs of "raw" addresses from most,
// but not all, of the j__udy*Alloc*() functions; see also JudyPrivate.h. To
// test the Judy code, compile this file with -DMALLOCBITS and use debug flavor
// only (for assertions). This test ensures that (a) all callers properly mask
// the namespace bits out before dereferencing a pointer (or else a core dump
// occurs), and (b) all callers send "raw" (unmasked) addresses to
// j__udy*Free*() calls.
//
// Note: Currently -DDEBUG turns on MALLOCBITS automatically.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// Set "hidden" global j__uMaxWords to the maximum number of words to allocate
// to any one array (large enough to have a JPM, otherwise j__uMaxWords is
// ignored), to trigger a fake malloc error when the number is exceeded. Note,
// this code is always executed, not #ifdefd, because its virtually free.
//
// Note: To keep the MALLOC macro faster and simpler, set j__uMaxWords to
// MAXINT, not zero, by default.
Word_t j__uMaxWords = ~0UL;
// This macro hides the faking of a malloc failure:
//
// Note: To keep this fast, just compare WordsPrev to j__uMaxWords without the
// complexity of first adding WordsNow, meaning the trigger point is not
// exactly where you might assume, but it shouldnt matter.
#define MALLOC(MallocFunc,WordsPrev,WordsNow) \
(((WordsPrev) > j__uMaxWords) ? 0UL : MallocFunc(WordsNow))
// Clear words starting at address:
//
// Note: Only use this for objects that care; in other cases, it doesnt
// matter if the objects memory is pre-zeroed.
#define ZEROWORDS(Addr,Words) \
{ \
Word_t Words__ = (Words); \
PWord_t Addr__ = (PWord_t) (Addr); \
while (Words__--) *Addr__++ = 0UL; \
}
#ifdef TRACEMI
// TRACING SUPPORT:
//
// Note: For TRACEMI, use a format for address printing compatible with other
// tracing facilities; in particular, %x not %lx, to truncate the "noisy" high
// part on 64-bit systems.
//
// TBD: The trace macros need fixing for alternate address types.
//
// Note: TRACEMI2 supports trace analysis no matter the underlying malloc/free
// engine used.
#include <stdio.h>
static Word_t j__udyMemSequence = 0L; // event sequence number.
#define TRACE_ALLOC5(a,b,c,d,e) (void) printf(a, (b), c, d)
#define TRACE_FREE5( a,b,c,d,e) (void) printf(a, (b), c, d)
#define TRACE_ALLOC6(a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
#define TRACE_FREE6( a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
#else
#ifdef TRACEMI2
#include <stdio.h>
#define b_pw cJU_BYTESPERWORD
#define TRACE_ALLOC5(a,b,c,d,e) \
(void) printf("a %lx %lx %lx\n", (b), (d) * b_pw, e)
#define TRACE_FREE5( a,b,c,d,e) \
(void) printf("f %lx %lx %lx\n", (b), (d) * b_pw, e)
#define TRACE_ALLOC6(a,b,c,d,e,f) \
(void) printf("a %lx %lx %lx\n", (b), (e) * b_pw, f)
#define TRACE_FREE6( a,b,c,d,e,f) \
(void) printf("f %lx %lx %lx\n", (b), (e) * b_pw, f)
static Word_t j__udyMemSequence = 0L; // event sequence number.
#else
#define TRACE_ALLOC5(a,b,c,d,e) // null.
#define TRACE_FREE5( a,b,c,d,e) // null.
#define TRACE_ALLOC6(a,b,c,d,e,f) // null.
#define TRACE_FREE6( a,b,c,d,e,f) // null.
#endif // ! TRACEMI2
#endif // ! TRACEMI
// MALLOC NAMESPACE SUPPORT:
#if (defined(DEBUG) && (! defined(MALLOCBITS))) // for now, DEBUG => MALLOCBITS:
#define MALLOCBITS 1
#endif
#ifdef MALLOCBITS
#define MALLOCBITS_VALUE 0x3 // bit pattern to use.
#define MALLOCBITS_MASK 0x7 // note: matches mask__ in JudyPrivate.h.
#define MALLOCBITS_SET( Type,Addr) \
((Addr) = (Type) ((Word_t) (Addr) | MALLOCBITS_VALUE))
#define MALLOCBITS_TEST(Type,Addr) \
assert((((Word_t) (Addr)) & MALLOCBITS_MASK) == MALLOCBITS_VALUE); \
((Addr) = (Type) ((Word_t) (Addr) & ~MALLOCBITS_VALUE))
#else
#define MALLOCBITS_SET( Type,Addr) // null.
#define MALLOCBITS_TEST(Type,Addr) // null.
#endif
// SAVE ERROR INFORMATION IN A Pjpm:
//
// "Small" (invalid) Addr values are used to distinguish overrun and no-mem
// errors. (TBD, non-zero invalid values are no longer returned from
// lower-level functions, that is, JU_ERRNO_OVERRUN is no longer detected.)
#define J__UDYSETALLOCERROR(Addr) \
{ \
JU_ERRID(Pjpm) = __LINE__; \
if ((Word_t) (Addr) > 0) JU_ERRNO(Pjpm) = JU_ERRNO_OVERRUN; \
else JU_ERRNO(Pjpm) = JU_ERRNO_NOMEM; \
return(0); \
}
// ****************************************************************************
// ALLOCATION FUNCTIONS:
//
// To help the compiler catch coding errors, each function returns a specific
// object type.
//
// Note: Only j__udyAllocJPM() and j__udyAllocJLW() return multiple values <=
// sizeof(Word_t) to indicate the type of memory allocation failure. Other
// allocation functions convert this failure to a JU_ERRNO.
// Note: Unlike other j__udyAlloc*() functions, Pjpms are returned non-raw,
// that is, without malloc namespace or root pointer type bits:
FUNCTION Pjpm_t j__udyAllocJPM(void)
{
Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD;
Pjpm_t Pjpm = (Pjpm_t) MALLOC(JudyMalloc, Words, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jpm_t));
if ((Word_t) Pjpm > sizeof(Word_t))
{
ZEROWORDS(Pjpm, Words);
Pjpm->jpm_TotalMemWords = Words;
}
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJPM(), Words = %lu\n",
Pjpm, j__udyMemSequence++, Words, cJU_LEAFW_MAXPOP1 + 1);
// MALLOCBITS_SET(Pjpm_t, Pjpm); // see above.
return(Pjpm);
} // j__udyAllocJPM()
FUNCTION Pjbl_t j__udyAllocJBL(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
Pjbl_t PjblRaw = (Pjbl_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbl_t));
if ((Word_t) PjblRaw > sizeof(Word_t))
{
ZEROWORDS(P_JBL(PjblRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjblRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBL(), Words = %lu\n", PjblRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbl_t, PjblRaw);
return(PjblRaw);
} // j__udyAllocJBL()
FUNCTION Pjbb_t j__udyAllocJBB(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
Pjbb_t PjbbRaw = (Pjbb_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbb_t));
if ((Word_t) PjbbRaw > sizeof(Word_t))
{
ZEROWORDS(P_JBB(PjbbRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjbbRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBB(), Words = %lu\n", PjbbRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbb_t, PjbbRaw);
return(PjbbRaw);
} // j__udyAllocJBB()
FUNCTION Pjp_t j__udyAllocJBBJP(Word_t NumJPs, Pjpm_t Pjpm)
{
Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
Pjp_t PjpRaw;
PjpRaw = (Pjp_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjpRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjpRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJBBJP(%lu), Words = %lu\n", PjpRaw,
j__udyMemSequence++, NumJPs, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjp_t, PjpRaw);
return(PjpRaw);
} // j__udyAllocJBBJP()
FUNCTION Pjbu_t j__udyAllocJBU(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
Pjbu_t PjbuRaw = (Pjbu_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbu_t));
if ((Word_t) PjbuRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjbuRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBU(), Words = %lu\n", PjbuRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbu_t, PjbuRaw);
return(PjbuRaw);
} // j__udyAllocJBU()
#if (defined(JUDYL) || (! defined(JU_64BIT)))
FUNCTION Pjll_t j__udyAllocJLL1(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL1(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL1()
#endif // (JUDYL || (! JU_64BIT))
FUNCTION Pjll_t j__udyAllocJLL2(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL2(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL2()
FUNCTION Pjll_t j__udyAllocJLL3(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL3(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL3()
#ifdef JU_64BIT
FUNCTION Pjll_t j__udyAllocJLL4(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL4(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL4()
FUNCTION Pjll_t j__udyAllocJLL5(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL5(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL5()
FUNCTION Pjll_t j__udyAllocJLL6(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL6(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL6()
FUNCTION Pjll_t j__udyAllocJLL7(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL7(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL7()
#endif // JU_64BIT
// Note: Root-level leaf addresses are always whole words (Pjlw_t), and unlike
// other j__udyAlloc*() functions, they are returned non-raw, that is, without
// malloc namespace or root pointer type bits (the latter are added later by
// the caller):
FUNCTION Pjlw_t j__udyAllocJLW(Word_t Pop1)
{
Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
Pjlw_t Pjlw = (Pjlw_t) MALLOC(JudyMalloc, Words, Words);
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLW(%lu), Words = %lu\n", Pjlw,
j__udyMemSequence++, Pop1, Words, Pop1);
// MALLOCBITS_SET(Pjlw_t, Pjlw); // see above.
return(Pjlw);
} // j__udyAllocJLW()
FUNCTION Pjlb_t j__udyAllocJLB1(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
Pjlb_t PjlbRaw;
PjlbRaw = (Pjlb_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jlb_t));
if ((Word_t) PjlbRaw > sizeof(Word_t))
{
ZEROWORDS(P_JLB(PjlbRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjlbRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJLB1(), Words = %lu\n", PjlbRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjlb_t, PjlbRaw);
return(PjlbRaw);
} // j__udyAllocJLB1()
#ifdef JUDYL
FUNCTION Pjv_t j__udyLAllocJV(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
Pjv_t PjvRaw;
PjvRaw = (Pjv_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjvRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjvRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyLAllocJV(%lu), Words = %lu\n", PjvRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjv_t, PjvRaw);
return(PjvRaw);
} // j__udyLAllocJV()
#endif // JUDYL
// ****************************************************************************
// FREE FUNCTIONS:
//
// To help the compiler catch coding errors, each function takes a specific
// object type to free.
// Note: j__udyFreeJPM() receives a root pointer with NO root pointer type
// bits present, that is, they must be stripped by the caller using P_JPM():
FUNCTION void j__udyFreeJPM(Pjpm_t PjpmFree, Pjpm_t PjpmStats)
{
Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD;
// MALLOCBITS_TEST(Pjpm_t, PjpmFree); // see above.
JudyFree((Pvoid_t) PjpmFree, Words);
if (PjpmStats != (Pjpm_t) NULL) PjpmStats->jpm_TotalMemWords -= Words;
// Note: Log PjpmFree->jpm_Pop0, similar to other j__udyFree*() functions, not
// an assumed value of cJU_LEAFW_MAXPOP1, for when the caller is
// Judy*FreeArray(), jpm_Pop0 is set to 0, and the population after the free
// really will be 0, not cJU_LEAFW_MAXPOP1.
TRACE_FREE6("0x%x %8lu = j__udyFreeJPM(%lu), Words = %lu\n", PjpmFree,
j__udyMemSequence++, Words, Words, PjpmFree->jpm_Pop0);
} // j__udyFreeJPM()
FUNCTION void j__udyFreeJBL(Pjbl_t Pjbl, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbl_t, Pjbl);
JudyFreeVirtual((Pvoid_t) Pjbl, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBL(), Words = %lu\n", Pjbl,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBL()
FUNCTION void j__udyFreeJBB(Pjbb_t Pjbb, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbb_t, Pjbb);
JudyFreeVirtual((Pvoid_t) Pjbb, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBB(), Words = %lu\n", Pjbb,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBB()
FUNCTION void j__udyFreeJBBJP(Pjp_t Pjp, Word_t NumJPs, Pjpm_t Pjpm)
{
Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
MALLOCBITS_TEST(Pjp_t, Pjp);
JudyFree((Pvoid_t) Pjp, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJBBJP(%lu), Words = %lu\n", Pjp,
j__udyMemSequence++, NumJPs, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBBJP()
FUNCTION void j__udyFreeJBU(Pjbu_t Pjbu, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbu_t, Pjbu);
JudyFreeVirtual((Pvoid_t) Pjbu, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBU(), Words = %lu\n", Pjbu,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBU()
#if (defined(JUDYL) || (! defined(JU_64BIT)))
FUNCTION void j__udyFreeJLL1(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL1(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL1()
#endif // (JUDYL || (! JU_64BIT))
FUNCTION void j__udyFreeJLL2(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL2(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL2()
FUNCTION void j__udyFreeJLL3(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL3(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL3()
#ifdef JU_64BIT
FUNCTION void j__udyFreeJLL4(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL4(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL4()
FUNCTION void j__udyFreeJLL5(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL5(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL5()
FUNCTION void j__udyFreeJLL6(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL6(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL6()
FUNCTION void j__udyFreeJLL7(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL7(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL7()
#endif // JU_64BIT
// Note: j__udyFreeJLW() receives a root pointer with NO root pointer type
// bits present, that is, they are stripped by P_JLW():
FUNCTION void j__udyFreeJLW(Pjlw_t Pjlw, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
// MALLOCBITS_TEST(Pjlw_t, Pjlw); // see above.
JudyFree((Pvoid_t) Pjlw, Words);
if (Pjpm) Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLW(%lu), Words = %lu\n", Pjlw,
j__udyMemSequence++, Pop1, Words, Pop1 - 1);
} // j__udyFreeJLW()
FUNCTION void j__udyFreeJLB1(Pjlb_t Pjlb, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjlb_t, Pjlb);
JudyFree((Pvoid_t) Pjlb, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJLB1(), Words = %lu\n", Pjlb,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLB1()
#ifdef JUDYL
FUNCTION void j__udyLFreeJV(Pjv_t Pjv, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjv_t, Pjv);
JudyFree((Pvoid_t) Pjv, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyLFreeJV(%lu), Words = %lu\n", Pjv,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyLFreeJV()
#endif // JUDYL

View File

@@ -1,259 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.7 $ $Source: /judy/src/JudyCommon/JudyMemActive.c $
//
// Return number of bytes of memory used to support a Judy1/L array.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
FUNCTION static Word_t j__udyGetMemActive(Pjp_t);
// ****************************************************************************
// J U D Y 1 M E M A C T I V E
// J U D Y L M E M A C T I V E
#ifdef JUDY1
FUNCTION Word_t Judy1MemActive
#else
FUNCTION Word_t JudyLMemActive
#endif
(
Pcvoid_t PArray // from which to retrieve.
)
{
if (PArray == (Pcvoid_t)NULL) return(0);
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
Word_t Words = Pjlw[0] + 1; // population.
#ifdef JUDY1
return((Words + 1) * sizeof(Word_t));
#else
return(((Words * 2) + 1) * sizeof(Word_t));
#endif
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
return(j__udyGetMemActive(&Pjpm->jpm_JP) + sizeof(jpm_t));
}
} // JudyMemActive()
// ****************************************************************************
// __ J U D Y G E T M E M A C T I V E
FUNCTION static Word_t j__udyGetMemActive(
Pjp_t Pjp) // top of subtree.
{
Word_t offset; // in a branch.
Word_t Bytes = 0; // actual bytes used at this level.
Word_t IdxSz; // bytes per index in leaves
switch (JU_JPTYPE(Pjp))
{
case cJU_JPBRANCH_L2:
case cJU_JPBRANCH_L3:
#ifdef JU_64BIT
case cJU_JPBRANCH_L4:
case cJU_JPBRANCH_L5:
case cJU_JPBRANCH_L6:
case cJU_JPBRANCH_L7:
#endif
case cJU_JPBRANCH_L:
{
Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
Bytes += j__udyGetMemActive((Pjbl->jbl_jp) + offset);
return(Bytes + sizeof(jbl_t));
}
case cJU_JPBRANCH_B2:
case cJU_JPBRANCH_B3:
#ifdef JU_64BIT
case cJU_JPBRANCH_B4:
case cJU_JPBRANCH_B5:
case cJU_JPBRANCH_B6:
case cJU_JPBRANCH_B7:
#endif
case cJU_JPBRANCH_B:
{
Word_t subexp;
Word_t jpcount;
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
Bytes += jpcount * sizeof(jp_t);
for (offset = 0; offset < jpcount; ++offset)
{
Bytes += j__udyGetMemActive(P_JP(JU_JBB_PJP(Pjbb, subexp))
+ offset);
}
}
return(Bytes + sizeof(jbb_t));
}
case cJU_JPBRANCH_U2:
case cJU_JPBRANCH_U3:
#ifdef JU_64BIT
case cJU_JPBRANCH_U4:
case cJU_JPBRANCH_U5:
case cJU_JPBRANCH_U6:
case cJU_JPBRANCH_U7:
#endif
case cJU_JPBRANCH_U:
{
Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
{
if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
&& ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
{
continue; // skip null JP to save time.
}
Bytes += j__udyGetMemActive(Pjbu->jbu_jp + offset);
}
return(Bytes + sizeof(jbu_t));
}
// -- Cases below here terminate and do not recurse. --
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1: IdxSz = 1; goto LeafWords;
#endif
case cJU_JPLEAF2: IdxSz = 2; goto LeafWords;
case cJU_JPLEAF3: IdxSz = 3; goto LeafWords;
#ifdef JU_64BIT
case cJU_JPLEAF4: IdxSz = 4; goto LeafWords;
case cJU_JPLEAF5: IdxSz = 5; goto LeafWords;
case cJU_JPLEAF6: IdxSz = 6; goto LeafWords;
case cJU_JPLEAF7: IdxSz = 7; goto LeafWords;
#endif
LeafWords:
#ifdef JUDY1
return(IdxSz * (JU_JPLEAF_POP0(Pjp) + 1));
#else
return((IdxSz + sizeof(Word_t))
* (JU_JPLEAF_POP0(Pjp) + 1));
#endif
case cJU_JPLEAF_B1:
{
#ifdef JUDY1
return(sizeof(jlb_t));
#else
Bytes = (JU_JPLEAF_POP0(Pjp) + 1) * sizeof(Word_t);
return(Bytes + sizeof(jlb_t));
#endif
}
JUDY1CODE(case cJ1_JPFULLPOPU1: return(0);)
#ifdef JUDY1
#define J__Mpy 0
#else
#define J__Mpy sizeof(Word_t)
#endif
case cJU_JPIMMED_1_01: return(0);
case cJU_JPIMMED_2_01: return(0);
case cJU_JPIMMED_3_01: return(0);
#ifdef JU_64BIT
case cJU_JPIMMED_4_01: return(0);
case cJU_JPIMMED_5_01: return(0);
case cJU_JPIMMED_6_01: return(0);
case cJU_JPIMMED_7_01: return(0);
#endif
case cJU_JPIMMED_1_02: return(J__Mpy * 2);
case cJU_JPIMMED_1_03: return(J__Mpy * 3);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_1_04: return(J__Mpy * 4);
case cJU_JPIMMED_1_05: return(J__Mpy * 5);
case cJU_JPIMMED_1_06: return(J__Mpy * 6);
case cJU_JPIMMED_1_07: return(J__Mpy * 7);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_1_08: return(0);
case cJ1_JPIMMED_1_09: return(0);
case cJ1_JPIMMED_1_10: return(0);
case cJ1_JPIMMED_1_11: return(0);
case cJ1_JPIMMED_1_12: return(0);
case cJ1_JPIMMED_1_13: return(0);
case cJ1_JPIMMED_1_14: return(0);
case cJ1_JPIMMED_1_15: return(0);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_2_02: return(J__Mpy * 2);
case cJU_JPIMMED_2_03: return(J__Mpy * 3);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_2_04: return(0);
case cJ1_JPIMMED_2_05: return(0);
case cJ1_JPIMMED_2_06: return(0);
case cJ1_JPIMMED_2_07: return(0);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_3_02: return(J__Mpy * 2);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_3_03: return(0);
case cJ1_JPIMMED_3_04: return(0);
case cJ1_JPIMMED_3_05: return(0);
case cJ1_JPIMMED_4_02: return(0);
case cJ1_JPIMMED_4_03: return(0);
case cJ1_JPIMMED_5_02: return(0);
case cJ1_JPIMMED_5_03: return(0);
case cJ1_JPIMMED_6_02: return(0);
case cJ1_JPIMMED_7_02: return(0);
#endif
} // switch (JU_JPTYPE(Pjp))
return(0); // to make some compilers happy.
} // j__udyGetMemActive()

View File

@@ -1,61 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.5 $ $Source: /judy/src/JudyCommon/JudyMemUsed.c $
//
// Return number of bytes of memory used to support a Judy1/L array.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
#ifdef JUDY1
FUNCTION Word_t Judy1MemUsed
#else // JUDYL
FUNCTION Word_t JudyLMemUsed
#endif
(
Pcvoid_t PArray // from which to retrieve.
)
{
Word_t Words = 0;
if (PArray == (Pcvoid_t) NULL) return(0);
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
Words = JU_LEAFWPOPTOWORDS(Pjlw[0] + 1); // based on pop1.
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
Words = Pjpm->jpm_TotalMemWords;
}
return(Words * sizeof(Word_t)); // convert to bytes.
} // Judy1MemUsed() / JudyLMemUsed()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,401 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.13 $ $Source: /judy/src/JudyCommon/JudyPrintJP.c $
//
// JudyPrintJP() debugging/tracing function for Judy1 or JudyL code.
// The caller should #include this file, with its static function (replicated
// in each compilation unit), in another *.c file, and compile with one of
// -DJUDY1 or -DJUDYL.
//
// The caller can set j__udyIndex and/or j__udyPopulation non-zero to have
// those values reported, and also to control trace-enabling (see below).
//
// Tracing is disabled by default unless one or both of two env parameters is
// set (regardless of value). If either value is set but null or evaluates to
// zero, tracing is immediately enabled. To disable tracing until a particular
// j__udy*Index value is seen, set STARTINDEX=<hex-index> in the env. To
// disable it until a particular j__udy*Population value is seen, set
// STARTPOP=<decimal-population> in the env. Once either condition is met,
// tracing "latches on".
//
// Example:
//
// STARTPOP=0 // immediate tracing.
// STARTINDEX=f35430a8 // not until one of these is met.
// STARTPOP=1000000
//
// Note: Trace-enabling does nothing unless the caller sets the appropriate
// global variable non-zero.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#include <stdlib.h> // for getenv() and strtoul().
// GLOBALS FROM CALLER:
//
// Note: This storage is declared once in each compilation unit that includes
// this file, but the linker should merge all cases into single locations, but
// ONLY if these are uninitialized, so ASSUME they are 0 to start.
Word_t j__udyIndex; // current Index itself, optional from caller.
Word_t j__udyPopulation; // Indexes in array, optional from caller.
// Other globals:
static Word_t startindex = 0; // see usage below.
static Word_t startpop = 0;
static bool_t enabled = FALSE; // by default, unless env params set.
// Shorthand for announcing JP addresses, Desc (in context), and JP types:
//
// Note: Width is at least one blank wider than any JP type name, and the line
// is left unfinished.
//
// Note: Use a format for address printing compatible with other tracing
// facilities; in particular, %x not %lx, to truncate the "noisy" high part on
// 64-bit systems.
#define JPTYPE(Type) printf("0x%lx %s %-17s", (Word_t) Pjp, Desc, Type)
// Shorthands for announcing expanse populations from DcdPopO fields:
#define POP0 printf("Pop1 = 0 ")
#define POP1 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xff) + 1))
#define POP2 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffff) + 1))
#define POP3 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffff) + 1))
#ifdef JU_64BIT
#define POP4 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffffff) + 1))
#define POP5 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffffffff) + 1))
#define POP6 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffffffffff) + 1))
#define POP7 printf("Pop1 = %ld ", (Word_t) ((JU_JPDCDPOP0(Pjp) & 0xffffffffffffff) + 1))
#endif
// Shorthands for announcing populations of Immeds:
//
// Note: Line up the small populations that often occur together, but beyond
// that, dont worry about it because populations can get arbitrarily large.
#define POP_1 printf("Pop1 = 1 ")
#define POP_2 printf("Pop1 = 2 ")
#define POP_3 printf("Pop1 = 3 ")
#define POP_4 printf("Pop1 = 4 ")
#define POP_5 printf("Pop1 = 5 ")
#define POP_6 printf("Pop1 = 6 ")
#define POP_7 printf("Pop1 = 7 ")
#define POP_8 printf("Pop1 = 8 ")
#define POP_9 printf("Pop1 = 8 ")
#define POP_10 printf("Pop1 = 10 ")
#define POP_11 printf("Pop1 = 11 ")
#define POP_12 printf("Pop1 = 12 ")
#define POP_13 printf("Pop1 = 13 ")
#define POP_14 printf("Pop1 = 14 ")
#define POP_15 printf("Pop1 = 15 ")
// Shorthands for other announcements:
#define NUMJPSL printf("NumJPs = %d ", P_JBL(Pjp->jp_Addr)->jbl_NumJPs)
#define OOPS printf("-- OOPS, invalid Type\n"); exit(1)
// This is harder to compute:
#define NUMJPSB \
{ \
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr); \
Word_t subexp; \
int numJPs = 0; \
\
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) \
numJPs += j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));\
\
printf("NumJPs = %d ", numJPs); \
}
// ****************************************************************************
// J U D Y P R I N T J P
//
// Dump information about a JP, at least its address, type, population, and
// number of JPs, as appropriate. Error out upon any unexpected JP type.
//
// TBD: Dump more detailed information about the JP?
FUNCTION static void JudyPrintJP(
Pjp_t Pjp, // JP to describe.
char * Desc, // brief description of caller, such as "i".
int Line) // callers source line number.
{
static bool_t checked = FALSE; // set upon first entry and check for params.
char * value; // for getenv().
// CHECK FOR EXTERNAL ENABLING:
//
// If a parameter is set, report the value, even if it is null or otherwise
// evaluates to zero, in which case enable tracing immediately; otherwise wait
// for the value to be hit.
#define GETENV(Name,Value,Base) \
if ((value = getenv (Name)) != (char *) NULL) \
{ \
(Value) = strtoul (value, (char **) NULL, Base); \
enabled |= ((Value) == 0); /* see above */ \
\
(void) printf ("JudyPrintJP(\"%s\"): $%s = %lu\n", \
Desc, Name, Value); \
}
if (! checked) // only check once.
{
checked = TRUE;
GETENV ("STARTINDEX", startindex, 16);
GETENV ("STARTPOP", startpop, 10);
(void) printf ("JudyPrintJP(\"%s\"): Tracing present %s\n", Desc,
enabled ? "and immediately enabled" :
(startindex || startpop) ?
"but disabled until start condition met" :
"but not enabled by env parameter");
}
if (! enabled) // check repeatedly until latched enabled:
{
if (startindex && (startindex == j__udyIndex))
{
(void) printf ("=== TRACING ENABLED (\"%s\"), "
"startindex = 0x%lx\n", Desc, startindex);
enabled = TRUE;
}
else if (startpop && (startpop == j__udyPopulation))
{
(void) printf ("=== TRACING ENABLED (\"%s\"), "
"startpop = %lu\n", Desc, startpop);
enabled = TRUE;
}
else
{
return; // print nothing this time.
}
}
// SWITCH ON JP TYPE:
switch (JU_JPTYPE(Pjp))
{
// Note: The following COULD be merged more tightly between Judy1 and JudyL,
// but we decided that the output should say cJ1*/cJL*, not cJU*, to be more
// specific.
#ifdef JUDY1
case cJ1_JPNULL1: JPTYPE("cJ1_JPNULL1"); POP0; break;
case cJ1_JPNULL2: JPTYPE("cJ1_JPNULL2"); POP0; break;
case cJ1_JPNULL3: JPTYPE("cJ1_JPNULL3"); POP0; break;
#ifdef JU_64BIT
case cJ1_JPNULL4: JPTYPE("cJ1_JPNULL4"); POP0; break;
case cJ1_JPNULL5: JPTYPE("cJ1_JPNULL5"); POP0; break;
case cJ1_JPNULL6: JPTYPE("cJ1_JPNULL6"); POP0; break;
case cJ1_JPNULL7: JPTYPE("cJ1_JPNULL7"); POP0; break;
#endif
case cJ1_JPBRANCH_L2: JPTYPE("cJ1_JPBRANCH_L2"); POP2;NUMJPSL;break;
case cJ1_JPBRANCH_L3: JPTYPE("cJ1_JPBRANCH_L3"); POP3;NUMJPSL;break;
#ifdef JU_64BIT
case cJ1_JPBRANCH_L4: JPTYPE("cJ1_JPBRANCH_L4"); POP4;NUMJPSL;break;
case cJ1_JPBRANCH_L5: JPTYPE("cJ1_JPBRANCH_L5"); POP5;NUMJPSL;break;
case cJ1_JPBRANCH_L6: JPTYPE("cJ1_JPBRANCH_L6"); POP6;NUMJPSL;break;
case cJ1_JPBRANCH_L7: JPTYPE("cJ1_JPBRANCH_L7"); POP7;NUMJPSL;break;
#endif
case cJ1_JPBRANCH_L: JPTYPE("cJ1_JPBRANCH_L"); NUMJPSL;break;
case cJ1_JPBRANCH_B2: JPTYPE("cJ1_JPBRANCH_B2"); POP2;NUMJPSB;break;
case cJ1_JPBRANCH_B3: JPTYPE("cJ1_JPBRANCH_B3"); POP3;NUMJPSB;break;
#ifdef JU_64BIT
case cJ1_JPBRANCH_B4: JPTYPE("cJ1_JPBRANCH_B4"); POP4;NUMJPSB;break;
case cJ1_JPBRANCH_B5: JPTYPE("cJ1_JPBRANCH_B5"); POP5;NUMJPSB;break;
case cJ1_JPBRANCH_B6: JPTYPE("cJ1_JPBRANCH_B6"); POP6;NUMJPSB;break;
case cJ1_JPBRANCH_B7: JPTYPE("cJ1_JPBRANCH_B7"); POP7;NUMJPSB;break;
#endif
case cJ1_JPBRANCH_B: JPTYPE("cJ1_JPBRANCH_B"); NUMJPSB;break;
case cJ1_JPBRANCH_U2: JPTYPE("cJ1_JPBRANCH_U2"); POP2; break;
case cJ1_JPBRANCH_U3: JPTYPE("cJ1_JPBRANCH_U3"); POP3; break;
#ifdef JU_64BIT
case cJ1_JPBRANCH_U4: JPTYPE("cJ1_JPBRANCH_U4"); POP4; break;
case cJ1_JPBRANCH_U5: JPTYPE("cJ1_JPBRANCH_U5"); POP5; break;
case cJ1_JPBRANCH_U6: JPTYPE("cJ1_JPBRANCH_U6"); POP6; break;
case cJ1_JPBRANCH_U7: JPTYPE("cJ1_JPBRANCH_U7"); POP7; break;
#endif
case cJ1_JPBRANCH_U: JPTYPE("cJ1_JPBRANCH_U"); break;
#ifndef JU_64BIT
case cJ1_JPLEAF1: JPTYPE("cJ1_JPLEAF1"); POP1; break;
#endif
case cJ1_JPLEAF2: JPTYPE("cJ1_JPLEAF2"); POP2; break;
case cJ1_JPLEAF3: JPTYPE("cJ1_JPLEAF3"); POP3; break;
#ifdef JU_64BIT
case cJ1_JPLEAF4: JPTYPE("cJ1_JPLEAF4"); POP4; break;
case cJ1_JPLEAF5: JPTYPE("cJ1_JPLEAF5"); POP5; break;
case cJ1_JPLEAF6: JPTYPE("cJ1_JPLEAF6"); POP6; break;
case cJ1_JPLEAF7: JPTYPE("cJ1_JPLEAF7"); POP7; break;
#endif
case cJ1_JPLEAF_B1: JPTYPE("cJ1_JPLEAF_B1"); POP1; break;
case cJ1_JPFULLPOPU1: JPTYPE("cJ1_JPFULLPOPU1"); POP1; break;
case cJ1_JPIMMED_1_01: JPTYPE("cJ1_JPIMMED_1_01"); POP_1; break;
case cJ1_JPIMMED_2_01: JPTYPE("cJ1_JPIMMED_2_01"); POP_1; break;
case cJ1_JPIMMED_3_01: JPTYPE("cJ1_JPIMMED_3_01"); POP_1; break;
#ifdef JU_64BIT
case cJ1_JPIMMED_4_01: JPTYPE("cJ1_JPIMMED_4_01"); POP_1; break;
case cJ1_JPIMMED_5_01: JPTYPE("cJ1_JPIMMED_5_01"); POP_1; break;
case cJ1_JPIMMED_6_01: JPTYPE("cJ1_JPIMMED_6_01"); POP_1; break;
case cJ1_JPIMMED_7_01: JPTYPE("cJ1_JPIMMED_7_01"); POP_1; break;
#endif
case cJ1_JPIMMED_1_02: JPTYPE("cJ1_JPIMMED_1_02"); POP_2; break;
case cJ1_JPIMMED_1_03: JPTYPE("cJ1_JPIMMED_1_03"); POP_3; break;
case cJ1_JPIMMED_1_04: JPTYPE("cJ1_JPIMMED_1_04"); POP_4; break;
case cJ1_JPIMMED_1_05: JPTYPE("cJ1_JPIMMED_1_05"); POP_5; break;
case cJ1_JPIMMED_1_06: JPTYPE("cJ1_JPIMMED_1_06"); POP_6; break;
case cJ1_JPIMMED_1_07: JPTYPE("cJ1_JPIMMED_1_07"); POP_7; break;
#ifdef JU_64BIT
case cJ1_JPIMMED_1_08: JPTYPE("cJ1_JPIMMED_1_08"); POP_8; break;
case cJ1_JPIMMED_1_09: JPTYPE("cJ1_JPIMMED_1_09"); POP_9; break;
case cJ1_JPIMMED_1_10: JPTYPE("cJ1_JPIMMED_1_10"); POP_10; break;
case cJ1_JPIMMED_1_11: JPTYPE("cJ1_JPIMMED_1_11"); POP_11; break;
case cJ1_JPIMMED_1_12: JPTYPE("cJ1_JPIMMED_1_12"); POP_12; break;
case cJ1_JPIMMED_1_13: JPTYPE("cJ1_JPIMMED_1_13"); POP_13; break;
case cJ1_JPIMMED_1_14: JPTYPE("cJ1_JPIMMED_1_14"); POP_14; break;
case cJ1_JPIMMED_1_15: JPTYPE("cJ1_JPIMMED_1_15"); POP_15; break;
#endif
case cJ1_JPIMMED_2_02: JPTYPE("cJ1_JPIMMED_2_02"); POP_2; break;
case cJ1_JPIMMED_2_03: JPTYPE("cJ1_JPIMMED_2_03"); POP_3; break;
#ifdef JU_64BIT
case cJ1_JPIMMED_2_04: JPTYPE("cJ1_JPIMMED_2_04"); POP_4; break;
case cJ1_JPIMMED_2_05: JPTYPE("cJ1_JPIMMED_2_05"); POP_5; break;
case cJ1_JPIMMED_2_06: JPTYPE("cJ1_JPIMMED_2_06"); POP_6; break;
case cJ1_JPIMMED_2_07: JPTYPE("cJ1_JPIMMED_2_07"); POP_7; break;
#endif
case cJ1_JPIMMED_3_02: JPTYPE("cJ1_JPIMMED_3_02"); POP_2; break;
#ifdef JU_64BIT
case cJ1_JPIMMED_3_03: JPTYPE("cJ1_JPIMMED_3_03"); POP_3; break;
case cJ1_JPIMMED_3_04: JPTYPE("cJ1_JPIMMED_3_04"); POP_4; break;
case cJ1_JPIMMED_3_05: JPTYPE("cJ1_JPIMMED_3_05"); POP_5; break;
case cJ1_JPIMMED_4_02: JPTYPE("cJ1_JPIMMED_4_02"); POP_2; break;
case cJ1_JPIMMED_4_03: JPTYPE("cJ1_JPIMMED_4_03"); POP_3; break;
case cJ1_JPIMMED_5_02: JPTYPE("cJ1_JPIMMED_5_02"); POP_2; break;
case cJ1_JPIMMED_5_03: JPTYPE("cJ1_JPIMMED_5_03"); POP_3; break;
case cJ1_JPIMMED_6_02: JPTYPE("cJ1_JPIMMED_6_02"); POP_2; break;
case cJ1_JPIMMED_7_02: JPTYPE("cJ1_JPIMMED_7_02"); POP_2; break;
#endif
case cJ1_JPIMMED_CAP: JPTYPE("cJ1_JPIMMED_CAP"); OOPS;
#else // JUDYL ===============================================================
case cJL_JPNULL1: JPTYPE("cJL_JPNULL1"); POP0; break;
case cJL_JPNULL2: JPTYPE("cJL_JPNULL2"); POP0; break;
case cJL_JPNULL3: JPTYPE("cJL_JPNULL3"); POP0; break;
#ifdef JU_64BIT
case cJL_JPNULL4: JPTYPE("cJL_JPNULL4"); POP0; break;
case cJL_JPNULL5: JPTYPE("cJL_JPNULL5"); POP0; break;
case cJL_JPNULL6: JPTYPE("cJL_JPNULL6"); POP0; break;
case cJL_JPNULL7: JPTYPE("cJL_JPNULL7"); POP0; break;
#endif
case cJL_JPBRANCH_L2: JPTYPE("cJL_JPBRANCH_L2"); POP2;NUMJPSL;break;
case cJL_JPBRANCH_L3: JPTYPE("cJL_JPBRANCH_L3"); POP3;NUMJPSL;break;
#ifdef JU_64BIT
case cJL_JPBRANCH_L4: JPTYPE("cJL_JPBRANCH_L4"); POP4;NUMJPSL;break;
case cJL_JPBRANCH_L5: JPTYPE("cJL_JPBRANCH_L5"); POP5;NUMJPSL;break;
case cJL_JPBRANCH_L6: JPTYPE("cJL_JPBRANCH_L6"); POP6;NUMJPSL;break;
case cJL_JPBRANCH_L7: JPTYPE("cJL_JPBRANCH_L7"); POP7;NUMJPSL;break;
#endif
case cJL_JPBRANCH_L: JPTYPE("cJL_JPBRANCH_L"); NUMJPSL;break;
case cJL_JPBRANCH_B2: JPTYPE("cJL_JPBRANCH_B2"); POP2;NUMJPSB;break;
case cJL_JPBRANCH_B3: JPTYPE("cJL_JPBRANCH_B3"); POP3;NUMJPSB;break;
#ifdef JU_64BIT
case cJL_JPBRANCH_B4: JPTYPE("cJL_JPBRANCH_B4"); POP4;NUMJPSB;break;
case cJL_JPBRANCH_B5: JPTYPE("cJL_JPBRANCH_B5"); POP5;NUMJPSB;break;
case cJL_JPBRANCH_B6: JPTYPE("cJL_JPBRANCH_B6"); POP6;NUMJPSB;break;
case cJL_JPBRANCH_B7: JPTYPE("cJL_JPBRANCH_B7"); POP7;NUMJPSB;break;
#endif
case cJL_JPBRANCH_B: JPTYPE("cJL_JPBRANCH_B"); NUMJPSB;break;
case cJL_JPBRANCH_U2: JPTYPE("cJL_JPBRANCH_U2"); POP2; break;
case cJL_JPBRANCH_U3: JPTYPE("cJL_JPBRANCH_U3"); POP3; break;
#ifdef JU_64BIT
case cJL_JPBRANCH_U4: JPTYPE("cJL_JPBRANCH_U4"); POP4; break;
case cJL_JPBRANCH_U5: JPTYPE("cJL_JPBRANCH_U5"); POP5; break;
case cJL_JPBRANCH_U6: JPTYPE("cJL_JPBRANCH_U6"); POP6; break;
case cJL_JPBRANCH_U7: JPTYPE("cJL_JPBRANCH_U7"); POP7; break;
#endif
case cJL_JPBRANCH_U: JPTYPE("cJL_JPBRANCH_U"); break;
case cJL_JPLEAF1: JPTYPE("cJL_JPLEAF1"); POP1; break;
case cJL_JPLEAF2: JPTYPE("cJL_JPLEAF2"); POP2; break;
case cJL_JPLEAF3: JPTYPE("cJL_JPLEAF3"); POP3; break;
#ifdef JU_64BIT
case cJL_JPLEAF4: JPTYPE("cJL_JPLEAF4"); POP4; break;
case cJL_JPLEAF5: JPTYPE("cJL_JPLEAF5"); POP5; break;
case cJL_JPLEAF6: JPTYPE("cJL_JPLEAF6"); POP6; break;
case cJL_JPLEAF7: JPTYPE("cJL_JPLEAF7"); POP7; break;
#endif
case cJL_JPLEAF_B1: JPTYPE("cJL_JPLEAF_B1"); POP1; break;
case cJL_JPIMMED_1_01: JPTYPE("cJL_JPIMMED_1_01"); POP_1; break;
case cJL_JPIMMED_2_01: JPTYPE("cJL_JPIMMED_2_01"); POP_1; break;
case cJL_JPIMMED_3_01: JPTYPE("cJL_JPIMMED_3_01"); POP_1; break;
#ifdef JU_64BIT
case cJL_JPIMMED_4_01: JPTYPE("cJL_JPIMMED_4_01"); POP_1; break;
case cJL_JPIMMED_5_01: JPTYPE("cJL_JPIMMED_5_01"); POP_1; break;
case cJL_JPIMMED_6_01: JPTYPE("cJL_JPIMMED_6_01"); POP_1; break;
case cJL_JPIMMED_7_01: JPTYPE("cJL_JPIMMED_7_01"); POP_1; break;
#endif
case cJL_JPIMMED_1_02: JPTYPE("cJL_JPIMMED_1_02"); POP_2; break;
case cJL_JPIMMED_1_03: JPTYPE("cJL_JPIMMED_1_03"); POP_3; break;
#ifdef JU_64BIT
case cJL_JPIMMED_1_04: JPTYPE("cJL_JPIMMED_1_04"); POP_4; break;
case cJL_JPIMMED_1_05: JPTYPE("cJL_JPIMMED_1_05"); POP_5; break;
case cJL_JPIMMED_1_06: JPTYPE("cJL_JPIMMED_1_06"); POP_6; break;
case cJL_JPIMMED_1_07: JPTYPE("cJL_JPIMMED_1_07"); POP_7; break;
case cJL_JPIMMED_2_02: JPTYPE("cJL_JPIMMED_2_02"); POP_2; break;
case cJL_JPIMMED_2_03: JPTYPE("cJL_JPIMMED_2_03"); POP_3; break;
case cJL_JPIMMED_3_02: JPTYPE("cJL_JPIMMED_3_02"); POP_2; break;
#endif
case cJL_JPIMMED_CAP: JPTYPE("cJL_JPIMMED_CAP"); OOPS;
#endif // JUDYL
default: printf("Unknown Type = %d", JU_JPTYPE(Pjp)); OOPS;
}
if (j__udyIndex) printf("Index = 0x%lx", j__udyIndex);
if (j__udyPopulation) printf("Pop = %lu", j__udyPopulation);
printf("line = %d\n", Line);
} // JudyPrintJP()

File diff suppressed because it is too large Load Diff

View File

@@ -1,485 +0,0 @@
#ifndef _JUDYPRIVATE1L_INCLUDED
#define _JUDYPRIVATE1L_INCLUDED
// _________________
//
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 4.31 $ $Source: /judy/src/JudyCommon/JudyPrivate1L.h $
// ****************************************************************************
// Declare common cJU_* names for JP Types that occur in both Judy1 and JudyL,
// for use by code that ifdefs JUDY1 and JUDYL. Only JP Types common to both
// Judy1 and JudyL are #defined here with equivalent cJU_* names. JP Types
// unique to only Judy1 or JudyL are listed in comments, so the type lists
// match the Judy1.h and JudyL.h files.
//
// This file also defines cJU_* for other JP-related constants and functions
// that some shared JUDY1/JUDYL code finds handy.
//
// At least in principle this file should be included AFTER Judy1.h or JudyL.h.
//
// WARNING: This file must be kept consistent with the enums in Judy1.h and
// JudyL.h.
//
// TBD: You might think, why not define common cJU_* enums in, say,
// JudyPrivate.h, and then inherit them into superset enums in Judy1.h and
// JudyL.h? The problem is that the enum lists for each class (cJ1_* and
// cJL_*) must be numerically "packed" into the correct order, for two reasons:
// (1) allow the compiler to generate "tight" switch statements with no wasted
// slots (although this is not very big), and (2) allow calculations using the
// enum values, although this is also not an issue if the calculations are only
// within each cJ*_JPIMMED_*_* class and the members are packed within the
// class.
#ifdef JUDY1
#define cJU_JRPNULL cJ1_JRPNULL
#define cJU_JPNULL1 cJ1_JPNULL1
#define cJU_JPNULL2 cJ1_JPNULL2
#define cJU_JPNULL3 cJ1_JPNULL3
#ifdef JU_64BIT
#define cJU_JPNULL4 cJ1_JPNULL4
#define cJU_JPNULL5 cJ1_JPNULL5
#define cJU_JPNULL6 cJ1_JPNULL6
#define cJU_JPNULL7 cJ1_JPNULL7
#endif
#define cJU_JPNULLMAX cJ1_JPNULLMAX
#define cJU_JPBRANCH_L2 cJ1_JPBRANCH_L2
#define cJU_JPBRANCH_L3 cJ1_JPBRANCH_L3
#ifdef JU_64BIT
#define cJU_JPBRANCH_L4 cJ1_JPBRANCH_L4
#define cJU_JPBRANCH_L5 cJ1_JPBRANCH_L5
#define cJU_JPBRANCH_L6 cJ1_JPBRANCH_L6
#define cJU_JPBRANCH_L7 cJ1_JPBRANCH_L7
#endif
#define cJU_JPBRANCH_L cJ1_JPBRANCH_L
#define j__U_BranchBJPPopToWords j__1_BranchBJPPopToWords
#define cJU_JPBRANCH_B2 cJ1_JPBRANCH_B2
#define cJU_JPBRANCH_B3 cJ1_JPBRANCH_B3
#ifdef JU_64BIT
#define cJU_JPBRANCH_B4 cJ1_JPBRANCH_B4
#define cJU_JPBRANCH_B5 cJ1_JPBRANCH_B5
#define cJU_JPBRANCH_B6 cJ1_JPBRANCH_B6
#define cJU_JPBRANCH_B7 cJ1_JPBRANCH_B7
#endif
#define cJU_JPBRANCH_B cJ1_JPBRANCH_B
#define cJU_JPBRANCH_U2 cJ1_JPBRANCH_U2
#define cJU_JPBRANCH_U3 cJ1_JPBRANCH_U3
#ifdef JU_64BIT
#define cJU_JPBRANCH_U4 cJ1_JPBRANCH_U4
#define cJU_JPBRANCH_U5 cJ1_JPBRANCH_U5
#define cJU_JPBRANCH_U6 cJ1_JPBRANCH_U6
#define cJU_JPBRANCH_U7 cJ1_JPBRANCH_U7
#endif
#define cJU_JPBRANCH_U cJ1_JPBRANCH_U
#ifndef JU_64BIT
#define cJU_JPLEAF1 cJ1_JPLEAF1
#endif
#define cJU_JPLEAF2 cJ1_JPLEAF2
#define cJU_JPLEAF3 cJ1_JPLEAF3
#ifdef JU_64BIT
#define cJU_JPLEAF4 cJ1_JPLEAF4
#define cJU_JPLEAF5 cJ1_JPLEAF5
#define cJU_JPLEAF6 cJ1_JPLEAF6
#define cJU_JPLEAF7 cJ1_JPLEAF7
#endif
#define cJU_JPLEAF_B1 cJ1_JPLEAF_B1
// cJ1_JPFULLPOPU1
#define cJU_JPIMMED_1_01 cJ1_JPIMMED_1_01
#define cJU_JPIMMED_2_01 cJ1_JPIMMED_2_01
#define cJU_JPIMMED_3_01 cJ1_JPIMMED_3_01
#ifdef JU_64BIT
#define cJU_JPIMMED_4_01 cJ1_JPIMMED_4_01
#define cJU_JPIMMED_5_01 cJ1_JPIMMED_5_01
#define cJU_JPIMMED_6_01 cJ1_JPIMMED_6_01
#define cJU_JPIMMED_7_01 cJ1_JPIMMED_7_01
#endif
#define cJU_JPIMMED_1_02 cJ1_JPIMMED_1_02
#define cJU_JPIMMED_1_03 cJ1_JPIMMED_1_03
#define cJU_JPIMMED_1_04 cJ1_JPIMMED_1_04
#define cJU_JPIMMED_1_05 cJ1_JPIMMED_1_05
#define cJU_JPIMMED_1_06 cJ1_JPIMMED_1_06
#define cJU_JPIMMED_1_07 cJ1_JPIMMED_1_07
#ifdef JU_64BIT
// cJ1_JPIMMED_1_08
// cJ1_JPIMMED_1_09
// cJ1_JPIMMED_1_10
// cJ1_JPIMMED_1_11
// cJ1_JPIMMED_1_12
// cJ1_JPIMMED_1_13
// cJ1_JPIMMED_1_14
// cJ1_JPIMMED_1_15
#endif
#define cJU_JPIMMED_2_02 cJ1_JPIMMED_2_02
#define cJU_JPIMMED_2_03 cJ1_JPIMMED_2_03
#ifdef JU_64BIT
// cJ1_JPIMMED_2_04
// cJ1_JPIMMED_2_05
// cJ1_JPIMMED_2_06
// cJ1_JPIMMED_2_07
#endif
#define cJU_JPIMMED_3_02 cJ1_JPIMMED_3_02
#ifdef JU_64BIT
// cJ1_JPIMMED_3_03
// cJ1_JPIMMED_3_04
// cJ1_JPIMMED_3_05
// cJ1_JPIMMED_4_02
// cJ1_JPIMMED_4_03
// cJ1_JPIMMED_5_02
// cJ1_JPIMMED_5_03
// cJ1_JPIMMED_6_02
// cJ1_JPIMMED_7_02
#endif
#define cJU_JPIMMED_CAP cJ1_JPIMMED_CAP
#else // JUDYL ****************************************************************
#define cJU_JRPNULL cJL_JRPNULL
#define cJU_JPNULL1 cJL_JPNULL1
#define cJU_JPNULL2 cJL_JPNULL2
#define cJU_JPNULL3 cJL_JPNULL3
#ifdef JU_64BIT
#define cJU_JPNULL4 cJL_JPNULL4
#define cJU_JPNULL5 cJL_JPNULL5
#define cJU_JPNULL6 cJL_JPNULL6
#define cJU_JPNULL7 cJL_JPNULL7
#endif
#define cJU_JPNULLMAX cJL_JPNULLMAX
#define cJU_JPBRANCH_L2 cJL_JPBRANCH_L2
#define cJU_JPBRANCH_L3 cJL_JPBRANCH_L3
#ifdef JU_64BIT
#define cJU_JPBRANCH_L4 cJL_JPBRANCH_L4
#define cJU_JPBRANCH_L5 cJL_JPBRANCH_L5
#define cJU_JPBRANCH_L6 cJL_JPBRANCH_L6
#define cJU_JPBRANCH_L7 cJL_JPBRANCH_L7
#endif
#define cJU_JPBRANCH_L cJL_JPBRANCH_L
#define j__U_BranchBJPPopToWords j__L_BranchBJPPopToWords
#define cJU_JPBRANCH_B2 cJL_JPBRANCH_B2
#define cJU_JPBRANCH_B3 cJL_JPBRANCH_B3
#ifdef JU_64BIT
#define cJU_JPBRANCH_B4 cJL_JPBRANCH_B4
#define cJU_JPBRANCH_B5 cJL_JPBRANCH_B5
#define cJU_JPBRANCH_B6 cJL_JPBRANCH_B6
#define cJU_JPBRANCH_B7 cJL_JPBRANCH_B7
#endif
#define cJU_JPBRANCH_B cJL_JPBRANCH_B
#define cJU_JPBRANCH_U2 cJL_JPBRANCH_U2
#define cJU_JPBRANCH_U3 cJL_JPBRANCH_U3
#ifdef JU_64BIT
#define cJU_JPBRANCH_U4 cJL_JPBRANCH_U4
#define cJU_JPBRANCH_U5 cJL_JPBRANCH_U5
#define cJU_JPBRANCH_U6 cJL_JPBRANCH_U6
#define cJU_JPBRANCH_U7 cJL_JPBRANCH_U7
#endif
#define cJU_JPBRANCH_U cJL_JPBRANCH_U
#define cJU_JPLEAF1 cJL_JPLEAF1
#define cJU_JPLEAF2 cJL_JPLEAF2
#define cJU_JPLEAF3 cJL_JPLEAF3
#ifdef JU_64BIT
#define cJU_JPLEAF4 cJL_JPLEAF4
#define cJU_JPLEAF5 cJL_JPLEAF5
#define cJU_JPLEAF6 cJL_JPLEAF6
#define cJU_JPLEAF7 cJL_JPLEAF7
#endif
#define cJU_JPLEAF_B1 cJL_JPLEAF_B1
#define cJU_JPIMMED_1_01 cJL_JPIMMED_1_01
#define cJU_JPIMMED_2_01 cJL_JPIMMED_2_01
#define cJU_JPIMMED_3_01 cJL_JPIMMED_3_01
#ifdef JU_64BIT
#define cJU_JPIMMED_4_01 cJL_JPIMMED_4_01
#define cJU_JPIMMED_5_01 cJL_JPIMMED_5_01
#define cJU_JPIMMED_6_01 cJL_JPIMMED_6_01
#define cJU_JPIMMED_7_01 cJL_JPIMMED_7_01
#endif
#define cJU_JPIMMED_1_02 cJL_JPIMMED_1_02
#define cJU_JPIMMED_1_03 cJL_JPIMMED_1_03
#ifdef JU_64BIT
#define cJU_JPIMMED_1_04 cJL_JPIMMED_1_04
#define cJU_JPIMMED_1_05 cJL_JPIMMED_1_05
#define cJU_JPIMMED_1_06 cJL_JPIMMED_1_06
#define cJU_JPIMMED_1_07 cJL_JPIMMED_1_07
#define cJU_JPIMMED_2_02 cJL_JPIMMED_2_02
#define cJU_JPIMMED_2_03 cJL_JPIMMED_2_03
#define cJU_JPIMMED_3_02 cJL_JPIMMED_3_02
#endif
#define cJU_JPIMMED_CAP cJL_JPIMMED_CAP
#endif // JUDYL
// ****************************************************************************
// cJU*_ other than JP types:
#ifdef JUDY1
#define cJU_LEAFW_MAXPOP1 cJ1_LEAFW_MAXPOP1
#ifndef JU_64BIT
#define cJU_LEAF1_MAXPOP1 cJ1_LEAF1_MAXPOP1
#endif
#define cJU_LEAF2_MAXPOP1 cJ1_LEAF2_MAXPOP1
#define cJU_LEAF3_MAXPOP1 cJ1_LEAF3_MAXPOP1
#ifdef JU_64BIT
#define cJU_LEAF4_MAXPOP1 cJ1_LEAF4_MAXPOP1
#define cJU_LEAF5_MAXPOP1 cJ1_LEAF5_MAXPOP1
#define cJU_LEAF6_MAXPOP1 cJ1_LEAF6_MAXPOP1
#define cJU_LEAF7_MAXPOP1 cJ1_LEAF7_MAXPOP1
#endif
#define cJU_IMMED1_MAXPOP1 cJ1_IMMED1_MAXPOP1
#define cJU_IMMED2_MAXPOP1 cJ1_IMMED2_MAXPOP1
#define cJU_IMMED3_MAXPOP1 cJ1_IMMED3_MAXPOP1
#ifdef JU_64BIT
#define cJU_IMMED4_MAXPOP1 cJ1_IMMED4_MAXPOP1
#define cJU_IMMED5_MAXPOP1 cJ1_IMMED5_MAXPOP1
#define cJU_IMMED6_MAXPOP1 cJ1_IMMED6_MAXPOP1
#define cJU_IMMED7_MAXPOP1 cJ1_IMMED7_MAXPOP1
#endif
#define JU_LEAF1POPTOWORDS(Pop1) J1_LEAF1POPTOWORDS(Pop1)
#define JU_LEAF2POPTOWORDS(Pop1) J1_LEAF2POPTOWORDS(Pop1)
#define JU_LEAF3POPTOWORDS(Pop1) J1_LEAF3POPTOWORDS(Pop1)
#ifdef JU_64BIT
#define JU_LEAF4POPTOWORDS(Pop1) J1_LEAF4POPTOWORDS(Pop1)
#define JU_LEAF5POPTOWORDS(Pop1) J1_LEAF5POPTOWORDS(Pop1)
#define JU_LEAF6POPTOWORDS(Pop1) J1_LEAF6POPTOWORDS(Pop1)
#define JU_LEAF7POPTOWORDS(Pop1) J1_LEAF7POPTOWORDS(Pop1)
#endif
#define JU_LEAFWPOPTOWORDS(Pop1) J1_LEAFWPOPTOWORDS(Pop1)
#ifndef JU_64BIT
#define JU_LEAF1GROWINPLACE(Pop1) J1_LEAF1GROWINPLACE(Pop1)
#endif
#define JU_LEAF2GROWINPLACE(Pop1) J1_LEAF2GROWINPLACE(Pop1)
#define JU_LEAF3GROWINPLACE(Pop1) J1_LEAF3GROWINPLACE(Pop1)
#ifdef JU_64BIT
#define JU_LEAF4GROWINPLACE(Pop1) J1_LEAF4GROWINPLACE(Pop1)
#define JU_LEAF5GROWINPLACE(Pop1) J1_LEAF5GROWINPLACE(Pop1)
#define JU_LEAF6GROWINPLACE(Pop1) J1_LEAF6GROWINPLACE(Pop1)
#define JU_LEAF7GROWINPLACE(Pop1) J1_LEAF7GROWINPLACE(Pop1)
#endif
#define JU_LEAFWGROWINPLACE(Pop1) J1_LEAFWGROWINPLACE(Pop1)
#define j__udyCreateBranchL j__udy1CreateBranchL
#define j__udyCreateBranchB j__udy1CreateBranchB
#define j__udyCreateBranchU j__udy1CreateBranchU
#define j__udyCascade1 j__udy1Cascade1
#define j__udyCascade2 j__udy1Cascade2
#define j__udyCascade3 j__udy1Cascade3
#ifdef JU_64BIT
#define j__udyCascade4 j__udy1Cascade4
#define j__udyCascade5 j__udy1Cascade5
#define j__udyCascade6 j__udy1Cascade6
#define j__udyCascade7 j__udy1Cascade7
#endif
#define j__udyCascadeL j__udy1CascadeL
#define j__udyInsertBranch j__udy1InsertBranch
#define j__udyBranchBToBranchL j__udy1BranchBToBranchL
#ifndef JU_64BIT
#define j__udyLeafB1ToLeaf1 j__udy1LeafB1ToLeaf1
#endif
#define j__udyLeaf1ToLeaf2 j__udy1Leaf1ToLeaf2
#define j__udyLeaf2ToLeaf3 j__udy1Leaf2ToLeaf3
#ifndef JU_64BIT
#define j__udyLeaf3ToLeafW j__udy1Leaf3ToLeafW
#else
#define j__udyLeaf3ToLeaf4 j__udy1Leaf3ToLeaf4
#define j__udyLeaf4ToLeaf5 j__udy1Leaf4ToLeaf5
#define j__udyLeaf5ToLeaf6 j__udy1Leaf5ToLeaf6
#define j__udyLeaf6ToLeaf7 j__udy1Leaf6ToLeaf7
#define j__udyLeaf7ToLeafW j__udy1Leaf7ToLeafW
#endif
#define jpm_t j1pm_t
#define Pjpm_t Pj1pm_t
#define jlb_t j1lb_t
#define Pjlb_t Pj1lb_t
#define JU_JLB_BITMAP J1_JLB_BITMAP
#define j__udyAllocJPM j__udy1AllocJ1PM
#define j__udyAllocJBL j__udy1AllocJBL
#define j__udyAllocJBB j__udy1AllocJBB
#define j__udyAllocJBBJP j__udy1AllocJBBJP
#define j__udyAllocJBU j__udy1AllocJBU
#ifndef JU_64BIT
#define j__udyAllocJLL1 j__udy1AllocJLL1
#endif
#define j__udyAllocJLL2 j__udy1AllocJLL2
#define j__udyAllocJLL3 j__udy1AllocJLL3
#ifdef JU_64BIT
#define j__udyAllocJLL4 j__udy1AllocJLL4
#define j__udyAllocJLL5 j__udy1AllocJLL5
#define j__udyAllocJLL6 j__udy1AllocJLL6
#define j__udyAllocJLL7 j__udy1AllocJLL7
#endif
#define j__udyAllocJLW j__udy1AllocJLW
#define j__udyAllocJLB1 j__udy1AllocJLB1
#define j__udyFreeJPM j__udy1FreeJ1PM
#define j__udyFreeJBL j__udy1FreeJBL
#define j__udyFreeJBB j__udy1FreeJBB
#define j__udyFreeJBBJP j__udy1FreeJBBJP
#define j__udyFreeJBU j__udy1FreeJBU
#ifndef JU_64BIT
#define j__udyFreeJLL1 j__udy1FreeJLL1
#endif
#define j__udyFreeJLL2 j__udy1FreeJLL2
#define j__udyFreeJLL3 j__udy1FreeJLL3
#ifdef JU_64BIT
#define j__udyFreeJLL4 j__udy1FreeJLL4
#define j__udyFreeJLL5 j__udy1FreeJLL5
#define j__udyFreeJLL6 j__udy1FreeJLL6
#define j__udyFreeJLL7 j__udy1FreeJLL7
#endif
#define j__udyFreeJLW j__udy1FreeJLW
#define j__udyFreeJLB1 j__udy1FreeJLB1
#define j__udyFreeSM j__udy1FreeSM
#define j__uMaxWords j__u1MaxWords
#ifdef DEBUG
#define JudyCheckPop Judy1CheckPop
#endif
#else // JUDYL ****************************************************************
#define cJU_LEAFW_MAXPOP1 cJL_LEAFW_MAXPOP1
#define cJU_LEAF1_MAXPOP1 cJL_LEAF1_MAXPOP1
#define cJU_LEAF2_MAXPOP1 cJL_LEAF2_MAXPOP1
#define cJU_LEAF3_MAXPOP1 cJL_LEAF3_MAXPOP1
#ifdef JU_64BIT
#define cJU_LEAF4_MAXPOP1 cJL_LEAF4_MAXPOP1
#define cJU_LEAF5_MAXPOP1 cJL_LEAF5_MAXPOP1
#define cJU_LEAF6_MAXPOP1 cJL_LEAF6_MAXPOP1
#define cJU_LEAF7_MAXPOP1 cJL_LEAF7_MAXPOP1
#endif
#define cJU_IMMED1_MAXPOP1 cJL_IMMED1_MAXPOP1
#define cJU_IMMED2_MAXPOP1 cJL_IMMED2_MAXPOP1
#define cJU_IMMED3_MAXPOP1 cJL_IMMED3_MAXPOP1
#ifdef JU_64BIT
#define cJU_IMMED4_MAXPOP1 cJL_IMMED4_MAXPOP1
#define cJU_IMMED5_MAXPOP1 cJL_IMMED5_MAXPOP1
#define cJU_IMMED6_MAXPOP1 cJL_IMMED6_MAXPOP1
#define cJU_IMMED7_MAXPOP1 cJL_IMMED7_MAXPOP1
#endif
#define JU_LEAF1POPTOWORDS(Pop1) JL_LEAF1POPTOWORDS(Pop1)
#define JU_LEAF2POPTOWORDS(Pop1) JL_LEAF2POPTOWORDS(Pop1)
#define JU_LEAF3POPTOWORDS(Pop1) JL_LEAF3POPTOWORDS(Pop1)
#ifdef JU_64BIT
#define JU_LEAF4POPTOWORDS(Pop1) JL_LEAF4POPTOWORDS(Pop1)
#define JU_LEAF5POPTOWORDS(Pop1) JL_LEAF5POPTOWORDS(Pop1)
#define JU_LEAF6POPTOWORDS(Pop1) JL_LEAF6POPTOWORDS(Pop1)
#define JU_LEAF7POPTOWORDS(Pop1) JL_LEAF7POPTOWORDS(Pop1)
#endif
#define JU_LEAFWPOPTOWORDS(Pop1) JL_LEAFWPOPTOWORDS(Pop1)
#define JU_LEAF1GROWINPLACE(Pop1) JL_LEAF1GROWINPLACE(Pop1)
#define JU_LEAF2GROWINPLACE(Pop1) JL_LEAF2GROWINPLACE(Pop1)
#define JU_LEAF3GROWINPLACE(Pop1) JL_LEAF3GROWINPLACE(Pop1)
#ifdef JU_64BIT
#define JU_LEAF4GROWINPLACE(Pop1) JL_LEAF4GROWINPLACE(Pop1)
#define JU_LEAF5GROWINPLACE(Pop1) JL_LEAF5GROWINPLACE(Pop1)
#define JU_LEAF6GROWINPLACE(Pop1) JL_LEAF6GROWINPLACE(Pop1)
#define JU_LEAF7GROWINPLACE(Pop1) JL_LEAF7GROWINPLACE(Pop1)
#endif
#define JU_LEAFWGROWINPLACE(Pop1) JL_LEAFWGROWINPLACE(Pop1)
#define j__udyCreateBranchL j__udyLCreateBranchL
#define j__udyCreateBranchB j__udyLCreateBranchB
#define j__udyCreateBranchU j__udyLCreateBranchU
#define j__udyCascade1 j__udyLCascade1
#define j__udyCascade2 j__udyLCascade2
#define j__udyCascade3 j__udyLCascade3
#ifdef JU_64BIT
#define j__udyCascade4 j__udyLCascade4
#define j__udyCascade5 j__udyLCascade5
#define j__udyCascade6 j__udyLCascade6
#define j__udyCascade7 j__udyLCascade7
#endif
#define j__udyCascadeL j__udyLCascadeL
#define j__udyInsertBranch j__udyLInsertBranch
#define j__udyBranchBToBranchL j__udyLBranchBToBranchL
#define j__udyLeafB1ToLeaf1 j__udyLLeafB1ToLeaf1
#define j__udyLeaf1ToLeaf2 j__udyLLeaf1ToLeaf2
#define j__udyLeaf2ToLeaf3 j__udyLLeaf2ToLeaf3
#ifndef JU_64BIT
#define j__udyLeaf3ToLeafW j__udyLLeaf3ToLeafW
#else
#define j__udyLeaf3ToLeaf4 j__udyLLeaf3ToLeaf4
#define j__udyLeaf4ToLeaf5 j__udyLLeaf4ToLeaf5
#define j__udyLeaf5ToLeaf6 j__udyLLeaf5ToLeaf6
#define j__udyLeaf6ToLeaf7 j__udyLLeaf6ToLeaf7
#define j__udyLeaf7ToLeafW j__udyLLeaf7ToLeafW
#endif
#define jpm_t jLpm_t
#define Pjpm_t PjLpm_t
#define jlb_t jLlb_t
#define Pjlb_t PjLlb_t
#define JU_JLB_BITMAP JL_JLB_BITMAP
#define j__udyAllocJPM j__udyLAllocJLPM
#define j__udyAllocJBL j__udyLAllocJBL
#define j__udyAllocJBB j__udyLAllocJBB
#define j__udyAllocJBBJP j__udyLAllocJBBJP
#define j__udyAllocJBU j__udyLAllocJBU
#define j__udyAllocJLL1 j__udyLAllocJLL1
#define j__udyAllocJLL2 j__udyLAllocJLL2
#define j__udyAllocJLL3 j__udyLAllocJLL3
#ifdef JU_64BIT
#define j__udyAllocJLL4 j__udyLAllocJLL4
#define j__udyAllocJLL5 j__udyLAllocJLL5
#define j__udyAllocJLL6 j__udyLAllocJLL6
#define j__udyAllocJLL7 j__udyLAllocJLL7
#endif
#define j__udyAllocJLW j__udyLAllocJLW
#define j__udyAllocJLB1 j__udyLAllocJLB1
// j__udyLAllocJV
#define j__udyFreeJPM j__udyLFreeJLPM
#define j__udyFreeJBL j__udyLFreeJBL
#define j__udyFreeJBB j__udyLFreeJBB
#define j__udyFreeJBBJP j__udyLFreeJBBJP
#define j__udyFreeJBU j__udyLFreeJBU
#define j__udyFreeJLL1 j__udyLFreeJLL1
#define j__udyFreeJLL2 j__udyLFreeJLL2
#define j__udyFreeJLL3 j__udyLFreeJLL3
#ifdef JU_64BIT
#define j__udyFreeJLL4 j__udyLFreeJLL4
#define j__udyFreeJLL5 j__udyLFreeJLL5
#define j__udyFreeJLL6 j__udyLFreeJLL6
#define j__udyFreeJLL7 j__udyLFreeJLL7
#endif
#define j__udyFreeJLW j__udyLFreeJLW
#define j__udyFreeJLB1 j__udyLFreeJLB1
#define j__udyFreeSM j__udyLFreeSM
// j__udyLFreeJV
#define j__uMaxWords j__uLMaxWords
#ifdef DEBUG
#define JudyCheckPop JudyLCheckPop
#endif
#endif // JUDYL
#endif // _JUDYPRIVATE1L_INCLUDED

View File

@@ -1,788 +0,0 @@
#ifndef _JUDY_PRIVATE_BRANCH_INCLUDED
#define _JUDY_PRIVATE_BRANCH_INCLUDED
// _________________
//
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision: 1.2 $ $Source: /home/doug/judy-1.0.5_min/test/../src/JudyCommon/RCS/JudyPrivateBranch.h,v $
//
// Header file for all Judy sources, for global but private (non-exported)
// declarations specific to branch support.
//
// See also the "Judy Shop Manual" (try judy/doc/int/JudyShopManual.*).
// ****************************************************************************
// JUDY POINTER (JP) SUPPORT
// ****************************************************************************
//
// This "rich pointer" object is pivotal to Judy execution.
//
// JP CONTAINING OTHER THAN IMMEDIATE INDEXES:
//
// If the JP points to a linear or bitmap leaf, jp_DcdPopO contains the
// Population-1 in LSbs and Decode (Dcd) bytes in the MSBs. (In practice the
// Decode bits are masked off while accessing the Pop0 bits.)
//
// The Decode Size, the number of Dcd bytes available, is encoded in jpo_Type.
// It can also be thought of as the number of states "skipped" in the SM, where
// each state decodes 8 bits = 1 byte.
//
// TBD: Dont need two structures, except possibly to force jp_Type to highest
// address!
//
// Note: The jpo_u union is not required by HP-UX or Linux but Win32 because
// the cl.exe compiler otherwise refuses to pack a bitfield (DcdPopO) with
// anything else, even with the -Zp option. This is pretty ugly, but
// fortunately portable, and its all hide-able by macros (see below).
typedef struct J_UDY_POINTER_OTHERS // JPO.
{
Word_t j_po_Addr; // first word: Pjp_t, Word_t, etc.
union {
Word_t j_po_Addr1;
uint8_t j_po_DcdP0[sizeof(Word_t) - 1];
uint8_t j_po_Bytes[sizeof(Word_t)]; // last byte = jp_Type.
} jpo_u;
} jpo_t;
// JP CONTAINING IMMEDIATE INDEXES:
//
// j_pi_1Index[] plus j_pi_LIndex[] together hold as many N-byte (1..3-byte
// [1..7-byte]) Indexes as will fit in sizeof(jpi_t) less 1 byte for j_pi_Type
// (that is, 7..1 [15..1] Indexes).
//
// For Judy1, j_pi_1Index[] is used and j_pi_LIndex[] is not used.
// For JudyL, j_pi_LIndex[] is used and j_pi_1Index[] is not used.
//
// Note: Actually when Pop1 = 1, jpi_t is not used, and the least bytes of the
// single Index are stored in j_po_DcdPopO, for both Judy1 and JudyL, so for
// JudyL the j_po_Addr field can hold the target value.
//
// TBD: Revise this structure to not overload j_po_DcdPopO this way? The
// current arrangement works, its just confusing.
typedef struct _JUDY_POINTER_IMMEDL
{
Word_t j_pL_Addr;
uint8_t j_pL_LIndex[sizeof(Word_t) - 1]; // see above.
uint8_t j_pL_Type;
} jpL_t;
typedef struct _JUDY_POINTER_IMMED1
{
uint8_t j_p1_1Index[(2 * sizeof(Word_t)) - 1];
uint8_t j_p1_Type;
} jp1_t;
// UNION OF JP TYPES:
//
// A branch is an array of cJU_BRANCHUNUMJPS (256) of this object, or an
// alternate data type such as: A linear branch which is a list of 2..7 JPs,
// or a bitmap branch which contains 8 lists of 0..32 JPs. JPs reside only in
// branches of a Judy SM.
typedef union J_UDY_POINTER // JP.
{
jpo_t j_po; // other than immediate indexes.
jpL_t j_pL; // immediate indexes.
jp1_t j_p1; // immediate indexes.
} jp_t, *Pjp_t;
// For coding convenience:
//
// Note, jp_Type has the same bits in jpo_t jpL_t and jp1_t.
#define jp_1Index j_p1.j_p1_1Index // for storing Indexes in first word.
#define jp_LIndex j_pL.j_pL_LIndex // for storing Indexes in second word.
#define jp_Addr j_po.j_po_Addr
#define jp_Addr1 j_po.jpo_u.j_po_Addr1
//#define jp_DcdPop0 j_po.jpo_u.j_po_DcdPop0
#define jp_Addr1 j_po.jpo_u.j_po_Addr1
//#define jp_Type j_po.jpo_u.j_po_Bytes[sizeof(Word_t) - 1]
#define jp_Type j_p1.j_p1_Type
#define jp_DcdP0 j_po.jpo_u.j_po_DcdP0
// ****************************************************************************
// JUDY POINTER (JP) -- RELATED MACROS AND CONSTANTS
// ****************************************************************************
// EXTRACT VALUES FROM JP:
//
// Masks for the bytes in the Dcd and Pop0 parts of jp_DcdPopO:
//
// cJU_DCDMASK() consists of a mask that excludes the (LSb) Pop0 bytes and
// also, just to be safe, the top byte of the word, since jp_DcdPopO is 1 byte
// less than a full word.
//
// Note: These are constant macros (cJU) because cPopBytes should be a
// constant. Also note cPopBytes == state in the SM.
#define cJU_POP0MASK(cPopBytes) JU_LEASTBYTESMASK(cPopBytes)
#define cJU_DCDMASK(cPopBytes) \
((cJU_ALLONES >> cJU_BITSPERBYTE) & (~cJU_POP0MASK(cPopBytes)))
// Mask off the high byte from INDEX to it can be compared to DcdPopO:
#define JU_TRIMTODCDSIZE(INDEX) ((cJU_ALLONES >> cJU_BITSPERBYTE) & (INDEX))
// Get from jp_DcdPopO the Pop0 for various branch JP Types:
//
// Note: There are no simple macros for cJU_BRANCH* Types because their
// populations must be added up and dont reside in an already-calculated
// place.
#define JU_JPBRANCH_POP0(PJP,cPopBytes) \
(JU_JPDCDPOP0(PJP) & cJU_POP0MASK(cPopBytes))
// METHOD FOR DETERMINING IF OBJECTS HAVE ROOM TO GROW:
//
// J__U_GROWCK() is a generic method to determine if an object can grow in
// place, based on whether the next population size (one more) would use the
// same space.
#define J__U_GROWCK(POP1,MAXPOP1,POPTOWORDS) \
(((POP1) != (MAXPOP1)) && (POPTOWORDS[POP1] == POPTOWORDS[(POP1) + 1]))
#define JU_BRANCHBJPGROWINPLACE(NumJPs) \
J__U_GROWCK(NumJPs, cJU_BITSPERSUBEXPB, j__U_BranchBJPPopToWords)
// DETERMINE IF AN INDEX IS (NOT) IN A JPS EXPANSE:
#define JU_DCDNOTMATCHINDEX(INDEX,PJP,POP0BYTES) \
(((INDEX) ^ JU_JPDCDPOP0(PJP)) & cJU_DCDMASK(POP0BYTES))
// NUMBER OF JPs IN AN UNCOMPRESSED BRANCH:
//
// An uncompressed branch is simply an array of 256 Judy Pointers (JPs). It is
// a minimum cacheline fill object. Define it here before its first needed.
#define cJU_BRANCHUNUMJPS cJU_SUBEXPPERSTATE
// ****************************************************************************
// JUDY BRANCH LINEAR (JBL) SUPPORT
// ****************************************************************************
//
// A linear branch is a way of compressing empty expanses (null JPs) out of an
// uncompressed 256-way branch, when the number of populated expanses is so
// small that even a bitmap branch is excessive.
//
// The maximum number of JPs in a Judy linear branch:
//
// Note: This number results in a 1-cacheline sized structure. Previous
// versions had a larger struct so a linear branch didnt become a bitmap
// branch until the memory consumed was even, but for speed, its better to
// switch "sooner" and keep a linear branch fast.
#define cJU_BRANCHLMAXJPS 7
// LINEAR BRANCH STRUCT:
//
// 1-byte count, followed by array of byte-sized expanses, followed by JPs.
typedef struct J__UDY_BRANCH_LINEAR
{
uint8_t jbl_NumJPs; // num of JPs (Pjp_t), 1..N.
uint8_t jbl_Expanse[cJU_BRANCHLMAXJPS]; // 1..7 MSbs of pop exps.
jp_t jbl_jp [cJU_BRANCHLMAXJPS]; // JPs for populated exps.
} jbl_t, * Pjbl_t;
// ****************************************************************************
// JUDY BRANCH BITMAP (JBB) SUPPORT
// ****************************************************************************
//
// A bitmap branch is a way of compressing empty expanses (null JPs) out of
// uncompressed 256-way branch. This costs 1 additional cache line fill, but
// can save a lot of memory when it matters most, near the leaves, and
// typically there will be only one at most in the path to any Index (leaf).
//
// The bitmap indicates which of the cJU_BRANCHUNUMJPS (256) JPs in the branch
// are NOT null, that is, their expanses are populated. The jbb_t also
// contains N pointers to "mini" Judy branches ("subexpanses") of up to M JPs
// each (see BITMAP_BRANCHMxN, for example, BITMAP_BRANCH32x8), where M x N =
// cJU_BRANCHUNUMJPS. These are dynamically allocated and never contain
// cJ*_JPNULL* jp_Types. An empty subexpanse is represented by no bit sets in
// the corresponding subexpanse bitmap, in which case the corresponding
// jbbs_Pjp pointers value is unused.
//
// Note that the number of valid JPs in each 1-of-N subexpanses is determined
// by POPULATION rather than by EXPANSE -- the desired outcome to save memory
// when near the leaves. Note that the memory required for 185 JPs is about as
// much as an uncompressed 256-way branch, therefore 184 is set as the maximum.
// However, it is expected that a conversion to an uncompressed 256-way branch
// will normally take place before this limit is reached for other reasons,
// such as improving performance when the "wasted" memory is well amortized by
// the population under the branch, preserving an acceptable overall
// bytes/Index in the Judy array.
//
// The number of pointers to arrays of JPs in the Judy bitmap branch:
//
// Note: The numbers below are the same in both 32 and 64 bit systems.
#define cJU_BRANCHBMAXJPS 184 // maximum JPs for bitmap branches.
// Convenience wrappers for referencing BranchB bitmaps or JP subarray
// pointers:
//
// Note: JU_JBB_PJP produces a "raw" memory address that must pass through
// P_JP before use, except when freeing memory:
#define JU_JBB_BITMAP(Pjbb, SubExp) ((Pjbb)->jbb_jbbs[SubExp].jbbs_Bitmap)
#define JU_JBB_PJP( Pjbb, SubExp) ((Pjbb)->jbb_jbbs[SubExp].jbbs_Pjp)
#define JU_SUBEXPB(Digit) (((Digit) / cJU_BITSPERSUBEXPB) & (cJU_NUMSUBEXPB-1))
#define JU_BITMAPTESTB(Pjbb, Index) \
(JU_JBB_BITMAP(Pjbb, JU_SUBEXPB(Index)) & JU_BITPOSMASKB(Index))
#define JU_BITMAPSETB(Pjbb, Index) \
(JU_JBB_BITMAP(Pjbb, JU_SUBEXPB(Index)) |= JU_BITPOSMASKB(Index))
// Note: JU_BITMAPCLEARB is not defined because the code does it a faster way.
typedef struct J__UDY_BRANCH_BITMAP_SUBEXPANSE
{
BITMAPB_t jbbs_Bitmap;
Pjp_t jbbs_Pjp;
} jbbs_t;
typedef struct J__UDY_BRANCH_BITMAP
{
jbbs_t jbb_jbbs [cJU_NUMSUBEXPB];
#ifdef SUBEXPCOUNTS
Word_t jbb_subPop1[cJU_NUMSUBEXPB];
#endif
} jbb_t, * Pjbb_t;
#define JU_BRANCHJP_NUMJPSTOWORDS(NumJPs) (j__U_BranchBJPPopToWords[NumJPs])
#ifdef SUBEXPCOUNTS
#define cJU_NUMSUBEXPU 16 // number of subexpanse counts.
#endif
// ****************************************************************************
// JUDY BRANCH UNCOMPRESSED (JBU) SUPPORT
// ****************************************************************************
// Convenience wrapper for referencing BranchU JPs:
//
// Note: This produces a non-"raw" address already passed through P_JBU().
#define JU_JBU_PJP(Pjp,Index,Level) \
(&((P_JBU((Pjp)->jp_Addr))->jbu_jp[JU_DIGITATSTATE(Index, Level)]))
#define JU_JBU_PJP0(Pjp) \
(&((P_JBU((Pjp)->jp_Addr))->jbu_jp[0]))
typedef struct J__UDY_BRANCH_UNCOMPRESSED
{
jp_t jbu_jp [cJU_BRANCHUNUMJPS]; // JPs for populated exp.
#ifdef SUBEXPCOUNTS
Word_t jbu_subPop1[cJU_NUMSUBEXPU];
#endif
} jbu_t, * Pjbu_t;
// ****************************************************************************
// OTHER SUPPORT FOR JUDY STATE MACHINES (SMs)
// ****************************************************************************
// OBJECT SIZES IN WORDS:
//
// Word_ts per various JudyL structures that have constant sizes.
// cJU_WORDSPERJP should always be 2; this is fundamental to the Judy
// structures.
#define cJU_WORDSPERJP (sizeof(jp_t) / cJU_BYTESPERWORD)
#define cJU_WORDSPERCL (cJU_BYTESPERCL / cJU_BYTESPERWORD)
// OPPORTUNISTIC UNCOMPRESSION:
//
// Define populations at which a BranchL or BranchB must convert to BranchU.
// Earlier conversion is possible with good memory efficiency -- see below.
#ifndef NO_BRANCHU
// Max population below BranchL, then convert to BranchU:
#define JU_BRANCHL_MAX_POP 1000
// Minimum global population increment before next conversion of a BranchB to a
// BranchU:
//
// This is was done to allow malloc() to coalesce memory before the next big
// (~512 words) allocation.
#define JU_BTOU_POP_INCREMENT 300
// Min/max population below BranchB, then convert to BranchU:
#define JU_BRANCHB_MIN_POP 135
#define JU_BRANCHB_MAX_POP 750
#else // NO_BRANCHU
// These are set up to have conservative conversion schedules to BranchU:
#define JU_BRANCHL_MAX_POP (-1UL)
#define JU_BTOU_POP_INCREMENT 300
#define JU_BRANCHB_MIN_POP 1000
#define JU_BRANCHB_MAX_POP (-1UL)
#endif // NO_BRANCHU
// MISCELLANEOUS MACROS:
// Get N most significant bits from the shifted Index word:
//
// As Index words are decoded, they are shifted left so only relevant,
// undecoded Index bits remain.
#define JU_BITSFROMSFTIDX(SFTIDX, N) ((SFTIDX) >> (cJU_BITSPERWORD - (N)))
// TBD: I have my doubts about the necessity of these macros (dlb):
// Produce 1-digit mask at specified state:
#define cJU_MASKATSTATE(State) (0xffL << (((State) - 1) * cJU_BITSPERBYTE))
// Get byte (digit) from Index at the specified state, right justified:
//
// Note: State must be 1..cJU_ROOTSTATE, and Digits must be 1..(cJU_ROOTSTATE
// - 1), but theres no way to assert these within an expression.
#define JU_DIGITATSTATE(Index,cState) \
((uint8_t)((Index) >> (((cState) - 1) * cJU_BITSPERBYTE)))
// Similarly, place byte (digit) at correct position for the specified state:
//
// Note: Cast digit to a Word_t first so there are no complaints or problems
// about shifting it more than 32 bits on a 64-bit system, say, when it is a
// uint8_t from jbl_Expanse[]. (Believe it or not, the C standard says to
// promote an unsigned char to a signed int; -Ac does not do this, but -Ae
// does.)
//
// Also, to make lint happy, cast the whole result again because apparently
// shifting a Word_t does not result in a Word_t!
#define JU_DIGITTOSTATE(Digit,cState) \
((Word_t) (((Word_t) (Digit)) << (((cState) - 1) * cJU_BITSPERBYTE)))
#endif // ! _JUDY_PRIVATE_BRANCH_INCLUDED
#ifdef TEST_INSDEL
// ****************************************************************************
// TEST CODE FOR INSERT/DELETE MACROS
// ****************************************************************************
//
// To use this, compile a temporary *.c file containing:
//
// #define DEBUG
// #define JUDY_ASSERT
// #define TEST_INSDEL
// #include "JudyPrivate.h"
// #include "JudyPrivateBranch.h"
//
// Use a command like this: cc -Ae +DD64 -I. -I JudyCommon -o t t.c
// For best results, include +DD64 on a 64-bit system.
//
// This test code exercises some tricky macros, but the output must be studied
// manually to verify it. Assume that for even-index testing, whole words
// (Word_t) suffices.
#include <stdio.h>
#define INDEXES 3 // in each array.
// ****************************************************************************
// I N I T
//
// Set up variables for next test. See usage.
FUNCTION void Init (
int base,
PWord_t PeIndex,
PWord_t PoIndex,
PWord_t Peleaf, // always whole words.
#ifndef JU_64BIT
uint8_t * Poleaf3)
#else
uint8_t * Poleaf3,
uint8_t * Poleaf5,
uint8_t * Poleaf6,
uint8_t * Poleaf7)
#endif
{
int offset;
*PeIndex = 99;
for (offset = 0; offset <= INDEXES; ++offset)
Peleaf[offset] = base + offset;
for (offset = 0; offset < (INDEXES + 1) * 3; ++offset)
Poleaf3[offset] = base + offset;
#ifndef JU_64BIT
*PoIndex = (91 << 24) | (92 << 16) | (93 << 8) | 94;
#else
*PoIndex = (91L << 56) | (92L << 48) | (93L << 40) | (94L << 32)
| (95L << 24) | (96L << 16) | (97L << 8) | 98L;
for (offset = 0; offset < (INDEXES + 1) * 5; ++offset)
Poleaf5[offset] = base + offset;
for (offset = 0; offset < (INDEXES + 1) * 6; ++offset)
Poleaf6[offset] = base + offset;
for (offset = 0; offset < (INDEXES + 1) * 7; ++offset)
Poleaf7[offset] = base + offset;
#endif
} // Init()
// ****************************************************************************
// P R I N T L E A F
//
// Print the byte values in a leaf.
FUNCTION void PrintLeaf (
char * Label, // for output.
int IOffset, // insertion offset in array.
int Indsize, // index size in bytes.
uint8_t * PLeaf) // array of Index bytes.
{
int offset; // in PLeaf.
int byte; // in one word.
(void) printf("%s %u: ", Label, IOffset);
for (offset = 0; offset <= INDEXES; ++offset)
{
for (byte = 0; byte < Indsize; ++byte)
(void) printf("%2d", PLeaf[(offset * Indsize) + byte]);
(void) printf(" ");
}
(void) printf("\n");
} // PrintLeaf()
// ****************************************************************************
// M A I N
//
// Test program.
FUNCTION main()
{
Word_t eIndex; // even, to insert.
Word_t oIndex; // odd, to insert.
Word_t eleaf [ INDEXES + 1]; // even leaf, index size 4.
uint8_t oleaf3[(INDEXES + 1) * 3]; // odd leaf, index size 3.
#ifdef JU_64BIT
uint8_t oleaf5[(INDEXES + 1) * 5]; // odd leaf, index size 5.
uint8_t oleaf6[(INDEXES + 1) * 6]; // odd leaf, index size 6.
uint8_t oleaf7[(INDEXES + 1) * 7]; // odd leaf, index size 7.
#endif
Word_t eleaf_2 [ INDEXES + 1]; // same, but second arrays:
uint8_t oleaf3_2[(INDEXES + 1) * 3];
#ifdef JU_64BIT
uint8_t oleaf5_2[(INDEXES + 1) * 5];
uint8_t oleaf6_2[(INDEXES + 1) * 6];
uint8_t oleaf7_2[(INDEXES + 1) * 7];
#endif
int ioffset; // index insertion offset.
#ifndef JU_64BIT
#define INIT Init( 0, & eIndex, & oIndex, eleaf, oleaf3)
#define INIT2 INIT; Init(50, & eIndex, & oIndex, eleaf_2, oleaf3_2)
#else
#define INIT Init( 0, & eIndex, & oIndex, eleaf, oleaf3, \
oleaf5, oleaf6, oleaf7)
#define INIT2 INIT; Init(50, & eIndex, & oIndex, eleaf_2, oleaf3_2, \
oleaf5_2, oleaf6_2, oleaf7_2)
#endif
#define WSIZE sizeof (Word_t) // shorthand.
#ifdef PRINTALL // to turn on "noisy" printouts.
#define PRINTLEAF(Label,IOffset,Indsize,PLeaf) \
PrintLeaf(Label,IOffset,Indsize,PLeaf)
#else
#define PRINTLEAF(Label,IOffset,Indsize,PLeaf) \
if (ioffset == 0) \
PrintLeaf(Label,IOffset,Indsize,PLeaf)
#endif
(void) printf(
"In each case, tests operate on an initial array of %d indexes. Even-index\n"
"tests set index values to 0,1,2...; odd-index tests set byte values to\n"
"0,1,2... Inserted indexes have a value of 99 or else byte values 91,92,...\n",
INDEXES);
(void) puts("\nJU_INSERTINPLACE():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, WSIZE, (uint8_t *) eleaf);
JU_INSERTINPLACE(eleaf, INDEXES, ioffset, eIndex);
PrintLeaf("After ", ioffset, WSIZE, (uint8_t *) eleaf);
}
(void) puts("\nJU_INSERTINPLACE3():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, 3, oleaf3);
JU_INSERTINPLACE3(oleaf3, INDEXES, ioffset, oIndex);
PrintLeaf("After ", ioffset, 3, oleaf3);
}
#ifdef JU_64BIT
(void) puts("\nJU_INSERTINPLACE5():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, 5, oleaf5);
JU_INSERTINPLACE5(oleaf5, INDEXES, ioffset, oIndex);
PrintLeaf("After ", ioffset, 5, oleaf5);
}
(void) puts("\nJU_INSERTINPLACE6():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, 6, oleaf6);
JU_INSERTINPLACE6(oleaf6, INDEXES, ioffset, oIndex);
PrintLeaf("After ", ioffset, 6, oleaf6);
}
(void) puts("\nJU_INSERTINPLACE7():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, 7, oleaf7);
JU_INSERTINPLACE7(oleaf7, INDEXES, ioffset, oIndex);
PrintLeaf("After ", ioffset, 7, oleaf7);
}
#endif // JU_64BIT
(void) puts("\nJU_DELETEINPLACE():");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, WSIZE, (uint8_t *) eleaf);
JU_DELETEINPLACE(eleaf, INDEXES, ioffset);
PrintLeaf("After ", ioffset, WSIZE, (uint8_t *) eleaf);
}
(void) puts("\nJU_DELETEINPLACE_ODD(3):");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, 3, oleaf3);
JU_DELETEINPLACE_ODD(oleaf3, INDEXES, ioffset, 3);
PrintLeaf("After ", ioffset, 3, oleaf3);
}
#ifdef JU_64BIT
(void) puts("\nJU_DELETEINPLACE_ODD(5):");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, 5, oleaf5);
JU_DELETEINPLACE_ODD(oleaf5, INDEXES, ioffset, 5);
PrintLeaf("After ", ioffset, 5, oleaf5);
}
(void) puts("\nJU_DELETEINPLACE_ODD(6):");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, 6, oleaf6);
JU_DELETEINPLACE_ODD(oleaf6, INDEXES, ioffset, 6);
PrintLeaf("After ", ioffset, 6, oleaf6);
}
(void) puts("\nJU_DELETEINPLACE_ODD(7):");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT;
PRINTLEAF("Before", ioffset, 7, oleaf7);
JU_DELETEINPLACE_ODD(oleaf7, INDEXES, ioffset, 7);
PrintLeaf("After ", ioffset, 7, oleaf7);
}
#endif // JU_64BIT
(void) puts("\nJU_INSERTCOPY():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, WSIZE, (uint8_t *) eleaf);
PRINTLEAF("Before, dest", ioffset, WSIZE, (uint8_t *) eleaf_2);
JU_INSERTCOPY(eleaf_2, eleaf, INDEXES, ioffset, eIndex);
PRINTLEAF("After, src ", ioffset, WSIZE, (uint8_t *) eleaf);
PrintLeaf("After, dest", ioffset, WSIZE, (uint8_t *) eleaf_2);
}
(void) puts("\nJU_INSERTCOPY3():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, 3, oleaf3);
PRINTLEAF("Before, dest", ioffset, 3, oleaf3_2);
JU_INSERTCOPY3(oleaf3_2, oleaf3, INDEXES, ioffset, oIndex);
PRINTLEAF("After, src ", ioffset, 3, oleaf3);
PrintLeaf("After, dest", ioffset, 3, oleaf3_2);
}
#ifdef JU_64BIT
(void) puts("\nJU_INSERTCOPY5():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, 5, oleaf5);
PRINTLEAF("Before, dest", ioffset, 5, oleaf5_2);
JU_INSERTCOPY5(oleaf5_2, oleaf5, INDEXES, ioffset, oIndex);
PRINTLEAF("After, src ", ioffset, 5, oleaf5);
PrintLeaf("After, dest", ioffset, 5, oleaf5_2);
}
(void) puts("\nJU_INSERTCOPY6():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, 6, oleaf6);
PRINTLEAF("Before, dest", ioffset, 6, oleaf6_2);
JU_INSERTCOPY6(oleaf6_2, oleaf6, INDEXES, ioffset, oIndex);
PRINTLEAF("After, src ", ioffset, 6, oleaf6);
PrintLeaf("After, dest", ioffset, 6, oleaf6_2);
}
(void) puts("\nJU_INSERTCOPY7():");
for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, 7, oleaf7);
PRINTLEAF("Before, dest", ioffset, 7, oleaf7_2);
JU_INSERTCOPY7(oleaf7_2, oleaf7, INDEXES, ioffset, oIndex);
PRINTLEAF("After, src ", ioffset, 7, oleaf7);
PrintLeaf("After, dest", ioffset, 7, oleaf7_2);
}
#endif // JU_64BIT
(void) puts("\nJU_DELETECOPY():");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, WSIZE, (uint8_t *) eleaf);
PRINTLEAF("Before, dest", ioffset, WSIZE, (uint8_t *) eleaf_2);
JU_DELETECOPY(eleaf_2, eleaf, INDEXES, ioffset, ignore);
PRINTLEAF("After, src ", ioffset, WSIZE, (uint8_t *) eleaf);
PrintLeaf("After, dest", ioffset, WSIZE, (uint8_t *) eleaf_2);
}
(void) puts("\nJU_DELETECOPY_ODD(3):");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, 3, oleaf3);
PRINTLEAF("Before, dest", ioffset, 3, oleaf3_2);
JU_DELETECOPY_ODD(oleaf3_2, oleaf3, INDEXES, ioffset, 3);
PRINTLEAF("After, src ", ioffset, 3, oleaf3);
PrintLeaf("After, dest", ioffset, 3, oleaf3_2);
}
#ifdef JU_64BIT
(void) puts("\nJU_DELETECOPY_ODD(5):");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, 5, oleaf5);
PRINTLEAF("Before, dest", ioffset, 5, oleaf5_2);
JU_DELETECOPY_ODD(oleaf5_2, oleaf5, INDEXES, ioffset, 5);
PRINTLEAF("After, src ", ioffset, 5, oleaf5);
PrintLeaf("After, dest", ioffset, 5, oleaf5_2);
}
(void) puts("\nJU_DELETECOPY_ODD(6):");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, 6, oleaf6);
PRINTLEAF("Before, dest", ioffset, 6, oleaf6_2);
JU_DELETECOPY_ODD(oleaf6_2, oleaf6, INDEXES, ioffset, 6);
PRINTLEAF("After, src ", ioffset, 6, oleaf6);
PrintLeaf("After, dest", ioffset, 6, oleaf6_2);
}
(void) puts("\nJU_DELETECOPY_ODD(7):");
for (ioffset = 0; ioffset < INDEXES; ++ioffset)
{
INIT2;
PRINTLEAF("Before, src ", ioffset, 7, oleaf7);
PRINTLEAF("Before, dest", ioffset, 7, oleaf7_2);
JU_DELETECOPY_ODD(oleaf7_2, oleaf7, INDEXES, ioffset, 7);
PRINTLEAF("After, src ", ioffset, 7, oleaf7);
PrintLeaf("After, dest", ioffset, 7, oleaf7_2);
}
#endif // JU_64BIT
return(0);
} // main()
#endif // TEST_INSDEL

Some files were not shown because too many files have changed in this diff Show More