/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
/* Format with:
* clang-format -i --style=file src/greenlet/greenlet.c
*
*
* Fix missing braces with:
* clang-tidy src/greenlet/greenlet.c -fix -checks="readability-braces-around-statements"
*/
#define GREENLET_MODULE
#include "greenlet.h"
#include "structmember.h"
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunused-parameter"
# pragma clang diagnostic ignored "-Wmissing-field-initializers"
#endif
/***********************************************************
A PyGreenlet is a range of C stack addresses that must be
saved and restored in such a way that the full range of the
stack contains valid data when we switch to it.
Stack layout for a greenlet:
| ^^^ |
| older data |
| |
stack_stop . |_______________|
. | |
. | greenlet data |
. | in stack |
. * |_______________| . . _____________ stack_copy + stack_saved
. | | | |
. | data | |greenlet data|
. | unrelated | | saved |
. | to | | in heap |
stack_start . | this | . . |_____________| stack_copy
| greenlet |
| |
| newer data |
| vvv |
Note that a greenlet's stack data is typically partly at its correct
place in the stack, and partly saved away in the heap, but always in
the above configuration: two blocks, the more recent one in the heap
and the older one still in the stack (either block may be empty).
Greenlets are chained: each points to the previous greenlet, which is
the one that owns the data currently in the C stack above my
stack_stop. The currently running greenlet is the first element of
this chain. The main (initial) greenlet is the last one. Greenlets
whose stack is entirely in the heap can be skipped from the chain.
The chain is not related to execution order, but only to the order
in which bits of C stack happen to belong to greenlets at a particular
point in time.
The main greenlet doesn't have a stack_stop: it is responsible for the
complete rest of the C stack, and we don't know where it begins. We
use (char*) -1, the largest possible address.
States:
stack_stop == NULL && stack_start == NULL: did not start yet
stack_stop != NULL && stack_start == NULL: already finished
stack_stop != NULL && stack_start != NULL: active
The running greenlet's stack_start is undefined but not NULL.
***********************************************************/
/*** global state ***/
/* In the presence of multithreading, this is a bit tricky:
- ts_current always store a reference to a greenlet, but it is
not really the current greenlet after a thread switch occurred.
- each *running* greenlet uses its run_info field to know which
thread it is attached to. A greenlet can only run in the thread
where it was created. This run_info is a ref to tstate->dict.
- the thread state dict is used to save and restore ts_current,
using the dictionary key 'ts_curkey'.
*/
extern PyTypeObject PyGreenlet_Type;
#if PY_VERSION_HEX >= 0x030700A3
# define GREENLET_PY37 1
#else
# define GREENLET_PY37 0
#endif
#if PY_VERSION_HEX >= 0x30A00B1
/*
Python 3.10 beta 1 changed tstate->use_tracing to a nested cframe member.
See https://github.com/python/cpython/pull/25276
We have to save and restore this as well.
*/
#define TSTATE_USE_TRACING(tstate) (tstate->cframe->use_tracing)
#define GREENLET_USE_CFRAME 1
#else
#define TSTATE_USE_TRACING(tstate) (tstate->use_tracing)
#define GREENLET_USE_CFRAME 0
#endif
#ifndef Py_SET_REFCNT
/* Py_REFCNT and Py_SIZE macros are converted to functions
https://bugs.python.org/issue39573 */
# define Py_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt)
#endif
#ifndef _Py_DEC_REFTOTAL
/* _Py_DEC_REFTOTAL macro has been removed from Python 3.9 by:
https://github.com/python/cpython/commit/49932fec62c616ec88da52642339d83ae719e924
*/
# ifdef Py_REF_DEBUG
# define _Py_DEC_REFTOTAL _Py_RefTotal--
# else
# define _Py_DEC_REFTOTAL
# endif
#endif
/* Weak reference to the switching-to greenlet during the slp switch */
static PyGreenlet* volatile ts_target = NULL;
/* Strong reference to the switching from greenlet after the switch */
static PyGreenlet* volatile ts_origin = NULL;
/* Strong reference to the current greenlet in this thread state */
static PyGreenlet* volatile ts_current = NULL;
/* NULL if error, otherwise args tuple to pass around during slp switch */
static PyObject* volatile ts_passaround_args = NULL;
static PyObject* volatile ts_passaround_kwargs = NULL;
/* Used internally in ``g_switchstack()`` */
#if GREENLET_USE_CFRAME
static int volatile ts__g_switchstack_use_tracing = 0;
#endif
/***********************************************************/
/* Thread-aware routines, switching global variables when needed */
#define STATE_OK \
(ts_current->run_info == PyThreadState_GET()->dict || \
!green_updatecurrent())
static PyObject* ts_curkey;
static PyObject* ts_delkey;
static PyObject* ts_tracekey;
static PyObject* ts_event_switch;
static PyObject* ts_event_throw;
static PyObject* PyExc_GreenletError;
static PyObject* PyExc_GreenletExit;
static PyObject* ts_empty_tuple;
static PyObject* ts_empty_dict;
#define GREENLET_GC_FLAGS Py_TPFLAGS_HAVE_GC
#define GREENLET_tp_alloc PyType_GenericAlloc
#define GREENLET_tp_free PyObject_GC_Del
#define GREENLET_tp_traverse green_traverse
#define GREENLET_tp_clear green_clear
#define GREENLET_tp_is_gc green_is_gc
static void
green_clear_exc(PyGreenlet* g)
{
#if GREENLET_PY37
g->exc_info = NULL;
g->exc_state.exc_value = NULL;
#if !GREENLET_PY311
g->exc_state.exc_type = NULL;
g->exc_state.exc_traceback = NULL;
#endif
g->exc_state.previous_item = NULL;
#else
g->exc_type = NULL;
g->exc_value = NULL;
g->exc_traceback = NULL;
#endif
}
static PyGreenlet*
green_create_main(void)
{
PyGreenlet* gmain;
PyObject* dict = PyThreadState_GetDict();
if (dict == NULL) {
if (!PyErr_Occurred()) {
PyErr_NoMemory();
}
return NULL;
}
/* create the main greenlet for this thread */
gmain = (PyGreenlet*)PyType_GenericAlloc(&PyGreenlet_Type, 0);
if (gmain == NULL) {
return NULL;
}
gmain->stack_start = (char*)1;
gmain->stack_stop = (char*)-1;
/* GetDict() returns a borrowed reference. Make it strong. */
gmain->run_info = dict;
Py_INCREF(dict);
return gmain;
}
static int
green_updatecurrent(void)
{
PyObject *exc, *val, *tb;
PyThreadState* tstate;
PyGreenlet* current;
PyGreenlet* previous;
PyObject* deleteme;
green_updatecurrent_restart:
/* save current exception */
PyErr_Fetch(&exc, &val, &tb);
/* get ts_current from the active tstate */
tstate = PyThreadState_GET();
if (tstate->dict &&
(current = (PyGreenlet*)PyDict_GetItem(tstate->dict, ts_curkey))) {
/* found -- remove it, to avoid keeping a ref */
Py_INCREF(current);
PyDict_DelItem(tstate->dict, ts_curkey);
}
else {
/* first time we see this tstate */
current = green_create_main();
if (current == NULL) {
Py_XDECREF(exc);
Py_XDECREF(val);
Py_XDECREF(tb);
return -1;
}
}
assert(current->run_info == tstate->dict);
green_updatecurrent_retry:
/* update ts_current as soon as possible, in case of nested switches */
Py_INCREF(current);
previous = ts_current;
ts_current = current;
/* save ts_current as the current greenlet of its own thread */
if (PyDict_SetItem(previous->run_info, ts_curkey, (PyObj
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
该项目为山东大学数据库课程设计作品,基于Flask框架构建,实现了一个电影院管理系统。源码包含2014个文件,涵盖1056个Python脚本、473个Python字节码文件、251个图片文件、28个文本文件以及少量C、C++、HTML、JavaScript和CSS相关文件。此外,还包括了必要的构建和元数据文件。该系统旨在提升电影院运营效率,适用于各类电影院管理场景。
资源推荐
资源详情
资源评论
收起资源包目录
基于Flask框架的山东大学数据库课设——电影院管理系统设计源码 (2000个子文件)
AUTHORS 849B
greenlet.c 66KB
_speedups.c 7KB
_test_extension.c 5KB
sysconfig.cfg 3KB
_test_extension_cpp.cpp 3KB
style.css 6KB
test.doc 10KB
gui-arm64.exe 135KB
cli-arm64.exe 134KB
t64.exe 104KB
w64.exe 98KB
t32.exe 95KB
w32.exe 88KB
gui-64.exe 74KB
cli-64.exe 73KB
cli-32.exe 64KB
cli.exe 64KB
gui-32.exe 64KB
gui.exe 64KB
.gitignore 176B
greenlet.h 5KB
greenlet.h 5KB
switch_ppc64_aix.h 4KB
switch_ppc64_linux.h 4KB
slp_platformselect.h 3KB
switch_x86_unix.h 3KB
switch_ppc_aix.h 3KB
switch_sparc_sun_gcc.h 3KB
switch_s390_unix.h 3KB
switch_ppc_linux.h 3KB
switch_ppc_unix.h 3KB
switch_ppc_macosx.h 3KB
switch_amd64_unix.h 3KB
switch_arm32_gcc.h 2KB
switch_x86_msvc.h 2KB
switch_aarch64_gcc.h 2KB
switch_arm32_ios.h 2KB
switch_x64_msvc.h 2KB
switch_x32_unix.h 1KB
switch_mips_unix.h 1KB
switch_csky_gcc.h 1KB
switch_m68k_gcc.h 928B
switch_riscv_unix.h 758B
switch_alpha_unix.h 689B
staff.html 22KB
movies.html 21KB
VIS.html 8KB
seats.html 7KB
staff_movie.html 7KB
seat.html 5KB
user.html 5KB
header.html 4KB
tiket.html 4KB
board.html 4KB
login.html 3KB
register.html 3KB
first.html 2KB
flaskProject1.iml 627B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
INSTALLER 4B
bglogin.jpg 299KB
11.jpg 45KB
222.jpg 45KB
27.jpg 42KB
135.jpg 40KB
39.jpg 38KB
15.jpg 36KB
129.jpg 36KB
205.jpg 36KB
79.jpg 36KB
112.jpg 35KB
182.jpg 34KB
96.jpg 34KB
191.jpg 34KB
239.jpg 34KB
137.jpg 34KB
17.jpg 33KB
95.jpg 33KB
189.jpg 33KB
154.jpg 33KB
103.jpg 33KB
207.jpg 33KB
164.jpg 33KB
217.jpg 33KB
共 2000 条
- 1
- 2
- 3
- 4
- 5
- 6
- 20
资源评论
lly202406
- 粉丝: 2534
- 资源: 5428
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功