/
proc
/
self
/
root
/
snap
/
lxd
/
current
/
lib
/
python3
/
dist-packages
/
crc32c
/
ext
/
File Upload :
llllll
Current File: //proc/self/root/snap/lxd/current/lib/python3/dist-packages/crc32c/ext/_crc32c.c
/* * This module provides crc32c checksum (http://www.rfc-editor.org/rfc/rfc3385.txt) * based on the Intel CRC32 instruction * provided in the Intel SSE4.2 instruction set * * ICRAR - International Centre for Radio Astronomy Research * (c) UWA - The University of Western Australia, 2014 * Copyright by UWA (in the framework of the ICRAR) * All rights reserved * * 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 * */ #include <Python.h> #include "checkarm.h" #include "checksse42.h" #include "common.h" #include "crc32c.h" #define MIN_BUFSIZE_FOR_AUTOMATIC_RELEASE 32 * 1024 /* threshold for GIL release is 32KiB */ /* Used in other files so needs global visibility */ int is_big_endian; typedef struct _CRC32CState { crc_function crc_fn; } CRC32CState; CRC32CState *get_state(PyObject *module) { return (CRC32CState *)PyModule_GetState(module); } static inline int crc32c_inline(crc_function crc_fn, uint32_t crc, unsigned char *bin_data, Py_ssize_t len) { int result; crc ^= 0xffffffff; result = crc_fn(crc, bin_data, len); result ^= 0xffffffff; return result; } static PyObject* crc32c_crc32c(PyObject *module, PyObject *args, PyObject *kwargs) { Py_buffer pbin; unsigned char *bin_data = NULL; uint32_t crc = 0U, result; int gil_release_mode = -1; static char *kwlist[] = {"data", "value", "gil_release_mode", NULL}; /* In python 3 we accept only bytes-like objects */ const char *format ="y*|Ii:crc32"; crc_function crc_fn = get_state(module)->crc_fn; if (!crc_fn) { PyErr_SetString( PyExc_RuntimeError, "crc32c: software mode disabled and no hardware acceleration found, can't calculate checksum" ); return NULL; } if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwlist, &pbin, &crc, &gil_release_mode) ) return NULL; bin_data = pbin.buf; #ifndef Py_GIL_DISABLED if ((gil_release_mode < 0 && pbin.len >= MIN_BUFSIZE_FOR_AUTOMATIC_RELEASE) || gil_release_mode >= 1) { Py_BEGIN_ALLOW_THREADS result = crc32c_inline(crc_fn, crc, bin_data, pbin.len); Py_END_ALLOW_THREADS } else #endif { result = crc32c_inline(crc_fn, crc, bin_data, pbin.len); } PyBuffer_Release(&pbin); return PyLong_FromUnsignedLong(result); } static PyObject *crc32c_crc32(PyObject *self, PyObject *args, PyObject *kwargs) { if (PyErr_WarnEx(PyExc_DeprecationWarning, "crc32c.crc32 will be eventually removed, use crc32c.crc32c instead", 1) == -1) { return NULL; } return crc32c_crc32c(self, args, kwargs); } /* The different values the SW mode preference can take */ enum crc32c_sw_mode { UNSPECIFIED, AUTO, FORCE, NONE }; static enum crc32c_sw_mode get_sw_mode(void) { char *sw_mode = getenv("CRC32C_SW_MODE"); if (sw_mode == NULL) { return UNSPECIFIED; } else if (!strcmp(sw_mode, "auto")) { return AUTO; } else if (!strcmp(sw_mode, "force")) { return FORCE; } else if (!strcmp(sw_mode, "none")) { return NONE; } return UNSPECIFIED; } #ifdef CRC32C_CAN_PROBE_HW static int get_skip_hw_probe(void) { char *skip_hw_probe = getenv("CRC32C_SKIP_HW_PROBE"); if (skip_hw_probe == NULL) { return 0; } return !strcmp(skip_hw_probe, "1"); } #endif static PyMethodDef CRC32CMethods[] = { {"crc32", (PyCFunction)crc32c_crc32, METH_VARARGS | METH_KEYWORDS, "Calculate crc32c incrementally (deprecated)"}, {"crc32c", (PyCFunction)crc32c_crc32c, METH_VARARGS | METH_KEYWORDS, "Calculate crc32c incrementally"}, {NULL, NULL, 0, NULL} /* Sentinel */ }; static int crc32c_mod_exec(PyObject *module); static PyModuleDef_Slot CRC32CSlots[] = { {Py_mod_exec, crc32c_mod_exec}, #if PY_VERSION_HEX >= 0x030C0000 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, #endif #ifdef Py_GIL_DISABLED {Py_mod_gil, Py_MOD_GIL_NOT_USED}, #endif {0, NULL} }; static const char *no_hw_or_sw_error_msg = "\n\n" "Hardware extensions providing a crc32c hardware instruction are not available in\n" "your processor. This package comes with a software implementation, but this\n" "support has been opted out because the CRC32C_SW_MODE environment variable is\n" "set to \"none\", and therefore any checksum calculation will result in a\n" "RuntimeError. CRC32C_SW_MODE can take one of the following values:\n" " * If unset: use the software implementation if no hardware support is found\n" " * 'auto': as above, but will eventually be discontinued\n" " * 'force': use software implementation regardless of hardware support.\n" " * 'none': fail if no hardware support is found.\n"; static struct PyModuleDef crc32c_def = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "_crc32c", .m_doc = "crc32c implementation in hardware and software", .m_size = sizeof(CRC32CState), .m_methods = CRC32CMethods, .m_slots = CRC32CSlots, .m_traverse = NULL, .m_clear = NULL, .m_free = NULL, }; PyMODINIT_FUNC PyInit__crc32c(void) { return PyModuleDef_Init(&crc32c_def); } static int crc32c_mod_exec(PyObject *module) { PyObject *hardware_based; enum crc32c_sw_mode sw_mode; const uint32_t n = 1; #ifdef CRC32C_CAN_PROBE_HW int skip_hw_probe; #endif sw_mode = get_sw_mode(); #ifdef CRC32C_CAN_PROBE_HW skip_hw_probe = get_skip_hw_probe(); #endif crc_function crc_fn = NULL; if (sw_mode == FORCE) { crc_fn = _crc32c_sw_slicing_by_8; hardware_based = Py_False; } #if defined(IS_INTEL) else if (!skip_hw_probe && _crc32c_intel_probe()) { crc_fn = _crc32c_hw_adler; crc32c_init_hw_adler(); hardware_based = Py_True; } #elif defined(IS_ARM) && (defined(__linux__) || defined(linux)) else if (!skip_hw_probe && _crc32c_arm64_probe()) { crc_fn = _crc32c_hw_arm64; hardware_based = Py_True; } #endif else if (sw_mode == UNSPECIFIED || sw_mode == AUTO) { crc_fn = _crc32c_sw_slicing_by_8; hardware_based = Py_False; } else if (sw_mode == NONE) { if (PyErr_WarnEx(PyExc_RuntimeWarning, no_hw_or_sw_error_msg, 1) == -1) { return -1; } hardware_based = Py_False; } is_big_endian = (*(const char *)(&n) == 0); Py_INCREF(hardware_based); get_state(module)->crc_fn = crc_fn; if (PyModule_AddObject(module, "hardware_based", hardware_based) < 0) { return -1; } if (PyModule_AddIntConstant(module, "big_endian", is_big_endian) < 0) { return -1; } return 0; }
Copyright ©2k19 -
Hexid
|
Tex7ure