diff --git a/trunk/3rdparty/st-srs/.gitignore b/trunk/3rdparty/st-srs/.gitignore index e62491c96..20f61304e 100644 --- a/trunk/3rdparty/st-srs/.gitignore +++ b/trunk/3rdparty/st-srs/.gitignore @@ -1,5 +1,6 @@ DARWIN_*_DBG LINUX_*_DBG +CYGWIN64_*_DBG obj st.pc .idea @@ -10,3 +11,4 @@ googletest-* *.gcno coverage codecov +*.dSYM diff --git a/trunk/3rdparty/st-srs/LICENSE b/trunk/3rdparty/st-srs/LICENSE new file mode 100644 index 000000000..04f191384 --- /dev/null +++ b/trunk/3rdparty/st-srs/LICENSE @@ -0,0 +1,30 @@ +The state-threads is provided under the terms of the MPL-1.1 or the +GPL-2.0-or-later. For more information about these licenses, please see +https://spdx.org/licenses/MPL-1.1.html and +https://spdx.org/licenses/GPL-2.0-or-later.html + +Individual files contain the following tag instead of the full license text. + + SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later + +All source code in the "tools", "utest" and "porting" directory is +distributed under the MIT style license. + + SPDX-License-Identifier: MIT + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ + +--------------------------------------------------------------------------- +Note: https://github.com/ossrs/state-threads/blob/srs/README#L68 + +The State Threads library is a derivative of the Netscape Portable +Runtime library (NSPR). All source code in this directory is +distributed under the terms of the Mozilla Public License (MPL) version +1.1 or the GNU General Public License (GPL) version 2 or later. For +more information about these licenses please see +http://www.mozilla.org/MPL/ and http://www.gnu.org/copyleft/. + +All source code in the "examples" directory is distributed under the BSD +style license. + diff --git a/trunk/3rdparty/st-srs/Makefile b/trunk/3rdparty/st-srs/Makefile index 100036b21..12928b0d1 100644 --- a/trunk/3rdparty/st-srs/Makefile +++ b/trunk/3rdparty/st-srs/Makefile @@ -58,6 +58,17 @@ ECHO = /bin/echo BUILD = DBG TARGETDIR = $(OS)_$(shell uname -r)_$(BUILD) +# For Cygwin, it pass a default OS env, we ignore it. +ifeq ($(OS), Windows_NT) +OS = +endif + +# For cygwin/windows, the 'uname -r' generate path with parentheses, +# which cause the make fails, so we use 'uname -s' instead. +ifeq ($(OS), CYGWIN64) +TARGETDIR = $(OS)_$(shell uname -s)_$(BUILD) +endif + DEFINES = -D$(OS) CFLAGS = SFLAGS = @@ -73,10 +84,12 @@ DESC = st.pc # Possible targets: TARGETS = darwin-debug darwin-optimized \ - linux-debug linux-optimized + linux-debug linux-optimized \ + cygwin64-debug UTEST_TARGETS = darwin-debug-utest linux-debug-utest \ - darwin-debug-gcov linux-debug-gcov + darwin-debug-gcov linux-debug-gcov \ + cygwin64-debug-utest # # Platform specifics @@ -91,7 +104,7 @@ CFLAGS += -arch x86_64 LDFLAGS += -arch x86_64 LDFLAGS += -dynamiclib -install_name /sw/lib/libst.$(MAJOR).$(DSO_SUFFIX) -compatibility_version $(MAJOR) -current_version $(VERSION) OTHER_FLAGS = -Wall -DEFINES += -DMD_HAVE_KQUEUE +DEFINES += -DMD_HAVE_KQUEUE -DMD_HAVE_SELECT endif ifeq ($(OS), LINUX) @@ -99,7 +112,16 @@ EXTRA_OBJS = $(TARGETDIR)/md_linux.o SFLAGS = -fPIC LDFLAGS = -shared -soname=$(SONAME) -lc OTHER_FLAGS = -Wall -DEFINES += -DMD_HAVE_EPOLL +DEFINES += -DMD_HAVE_EPOLL -DMD_HAVE_SELECT +endif + +ifeq ($(OS), CYGWIN64) +EXTRA_OBJS = $(TARGETDIR)/md_cygwin64.o +SFLAGS = -fPIC +DSO_SUFFIX = dll +LDFLAGS = -shared -soname=$(SONAME) -lc +OTHER_FLAGS = -Wall +DEFINES += -DMD_HAVE_SELECT endif # @@ -159,6 +181,10 @@ endif # # make EXTRA_CFLAGS=-UMD_HAVE_EPOLL # +# or to enable sendmmsg(2) support: +# +# make EXTRA_CFLAGS="-DMD_HAVE_SENDMMSG -D_GNU_SOURCE" +# # or to enable stats for ST: # # make EXTRA_CFLAGS=-DDEBUG_STATS @@ -245,6 +271,9 @@ $(TARGETDIR)/md_linux.o: md_linux.S $(TARGETDIR)/md_darwin.o: md_darwin.S $(CC) $(CFLAGS) -c $< -o $@ +$(TARGETDIR)/md_cygwin64.o: md_cygwin64.S + $(CC) $(CFLAGS) -c $< -o $@ + $(TARGETDIR)/%.o: %.c common.h md.h $(CC) $(CFLAGS) -c $< -o $@ @@ -277,6 +306,9 @@ linux-debug: linux-optimized: $(MAKE) OS="LINUX" BUILD="OPT" +cygwin64-debug: + $(MAKE) OS="CYGWIN64" BUILD="DBG" + darwin-debug-utest: @echo "Build utest for state-threads" $(MAKE) OS="DARWIN" BUILD="DBG" @@ -285,6 +317,10 @@ linux-debug-utest: @echo "Build utest for state-threads" $(MAKE) OS="LINUX" BUILD="DBG" cd utest && $(MAKE) +cygwin64-debug-utest: + @echo "Build utest for state-threads" + $(MAKE) OS="CYGWIN64" BUILD="DBG" + cd utest && $(MAKE) UTEST_FLAGS="-std=gnu++0x" # @see https://www.codenong.com/18784112/ darwin-debug-gcov: @echo "Build utest with gcov for state-threads" diff --git a/trunk/3rdparty/st-srs/README.md b/trunk/3rdparty/st-srs/README.md index 79578f41d..e04a6c961 100644 --- a/trunk/3rdparty/st-srs/README.md +++ b/trunk/3rdparty/st-srs/README.md @@ -11,30 +11,45 @@ Fork from http://sourceforge.net/projects/state-threads, patched for [SRS](https For original ST without any changes, checkout the [ST master branch](https://github.com/ossrs/state-threads/tree/master). +## LICENSE + +[state-threads](https://github.com/ossrs/state-threads/blob/srs/README#L68) is licenced under [MPL or GPLv2](https://github.com/ossrs/srs/wiki/LicenseMixing#state-threads). + ## Usage Get code: -``` -git clone https://github.com/ossrs/state-threads.git && -cd state-threads && git checkout srs +```bash +git clone -b srs https://github.com/ossrs/state-threads.git ``` For Linux: -``` -make linux-debug EXTRA_CFLAGS="-DMD_HAVE_EPOLL" +```bash +make linux-debug ``` For OSX: +```bash +make darwin-debug ``` -make darwin-debug EXTRA_CFLAGS="-DMD_HAVE_KQUEUE" + +For Cygwin(Windows): + +``` +make cygwin64-debug +``` + +For Linux aarch64, which fail with `Unknown CPU architecture`: + +```bash +make linux-debug EXTRA_CFLAGS="-D__aarch64__" ``` Linux with valgrind: -``` +```bash make linux-debug EXTRA_CFLAGS="-DMD_VALGRIND" ``` @@ -42,13 +57,13 @@ make linux-debug EXTRA_CFLAGS="-DMD_VALGRIND" Linux with valgrind and epoll: -``` +```bash make linux-debug EXTRA_CFLAGS="-DMD_HAVE_EPOLL -DMD_VALGRIND" ``` For OSX, user must specifies the valgrind header files: -``` +```bash make darwin-debug EXTRA_CFLAGS="-DMD_HAVE_KQUEUE -DMD_VALGRIND -I/usr/local/include" ``` @@ -58,21 +73,24 @@ make darwin-debug EXTRA_CFLAGS="-DMD_HAVE_KQUEUE -DMD_VALGRIND -I/usr/local/incl The branch [srs](https://github.com/ossrs/state-threads/tree/srs) will be patched the following patches: -- [x] Patch [st.arm.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/1.st.arm.patch), for ARM. -- [x] Patch [st.osx.kqueue.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/3.st.osx.kqueue.patch), for osx. -- [x] Patch [st.disable.examples.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/4.st.disable.examples.patch), for ubuntu. -- [x] [Refine TAB of code](https://github.com/ossrs/state-threads/compare/c2001d30ca58f55d72a6cc6b9b6c70391eaf14db...d2101b26988b0e0db0aabc53ddf452068c1e2cbc). -- [x] Merge from [michaeltalyansky](https://github.com/michaeltalyansky/state-threads) and [xzh3836598](https://github.com/ossrs/state-threads/commit/9a17dec8f9c2814d93761665df7c5575a4d2d8a3), support [ARM](https://github.com/ossrs/state-threads/issues/1). -- [x] Merge from [toffaletti](https://github.com/toffaletti/state-threads), support [valgrind](https://github.com/ossrs/state-threads/issues/2) for ST. -- [x] Patch [st.osx10.14.build.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/6.st.osx10.14.build.patch), for osx 10.14 build. -- [x] Support macro `MD_ST_NO_ASM` to disable ASM, [#8](https://github.com/ossrs/state-threads/issues/8). -- [x] Merge patch [srs#1282](https://github.com/ossrs/srs/issues/1282#issuecomment-445539513) to support aarch64, [#9](https://github.com/ossrs/state-threads/issues/9). -- [x] Support OSX for Apple Darwin, macOS, [#11](https://github.com/ossrs/state-threads/issues/11). -- [ ] Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12). -- [x] Refine performance for sleep or epoll_wait(0), [#17](https://github.com/ossrs/state-threads/issues/17). -- [ ] Improve the performance of timer. [9fe8cfe5b](https://github.com/ossrs/state-threads/commit/9fe8cfe5b1c9741a2e671a46215184f267fba400), [7879c2b](https://github.com/ossrs/state-threads/commit/7879c2b), [387cddb](https://github.com/ossrs/state-threads/commit/387cddb) -- [x] Support utest by gtest and coverage by gcov/gocvr. -- [ ] Support Multiple Threads for Linux and Darwin. [#19](https://github.com/ossrs/state-threads/issues/19), [srs#2188](https://github.com/ossrs/srs/issues/2188). +- [x] ARM: Patch [st.arm.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/1.st.arm.patch), for ARM. +- [x] OSX: Patch [st.osx.kqueue.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/3.st.osx.kqueue.patch), for osx. +- [x] Linux: Patch [st.disable.examples.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/4.st.disable.examples.patch), for ubuntu. +- [x] System: [Refine TAB of code](https://github.com/ossrs/state-threads/compare/c2001d30ca58f55d72a6cc6b9b6c70391eaf14db...d2101b26988b0e0db0aabc53ddf452068c1e2cbc). +- [x] ARM: Merge from [michaeltalyansky](https://github.com/michaeltalyansky/state-threads) and [xzh3836598](https://github.com/ossrs/state-threads/commit/9a17dec8f9c2814d93761665df7c5575a4d2d8a3), support [ARM](https://github.com/ossrs/state-threads/issues/1). +- [x] Valgrind: Merge from [toffaletti](https://github.com/toffaletti/state-threads), support [valgrind](https://github.com/ossrs/state-threads/issues/2) for ST. +- [x] OSX: Patch [st.osx10.14.build.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/6.st.osx10.14.build.patch), for osx 10.14 build. +- [x] ARM: Support macro `MD_ST_NO_ASM` to disable ASM, [#8](https://github.com/ossrs/state-threads/issues/8). +- [x] AARCH64: Merge patch [srs#1282](https://github.com/ossrs/srs/issues/1282#issuecomment-445539513) to support aarch64, [#9](https://github.com/ossrs/state-threads/issues/9). +- [x] OSX: Support OSX for Apple Darwin, macOS, [#11](https://github.com/ossrs/state-threads/issues/11). +- [x] System: Refine performance for sleep or epoll_wait(0), [#17](https://github.com/ossrs/state-threads/issues/17). +- [x] System: Support utest by gtest and coverage by gcov/gocvr. +- [x] System: Only support for Linux and Darwin. [#19](https://github.com/ossrs/state-threads/issues/19), [srs#2188](https://github.com/ossrs/srs/issues/2188). +- [x] System: Improve the performance of timer. [9fe8cfe5b](https://github.com/ossrs/state-threads/commit/9fe8cfe5b1c9741a2e671a46215184f267fba400), [7879c2b](https://github.com/ossrs/state-threads/commit/7879c2b), [387cddb](https://github.com/ossrs/state-threads/commit/387cddb) +- [x] Windows: Support Windows 64bits. [#20](https://github.com/ossrs/state-threads/issues/20). +- [x] MIPS: Support Linux/MIPS for OpenWRT, [#21](https://github.com/ossrs/state-threads/issues/21). +- [ ] System: Support Multiple Threads for Linux and Darwin. [#19](https://github.com/ossrs/state-threads/issues/19), [srs#2188](https://github.com/ossrs/srs/issues/2188). +- [ ] System: Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12). ## GDB Tools @@ -141,6 +159,7 @@ bash auto/coverage.sh * API reference: http://ossrs.github.io/state-threads/docs/reference.html * Programming notes: http://ossrs.github.io/state-threads/docs/notes.html +* [How to porting ST to other OS/CPU?](https://github.com/ossrs/state-threads/issues/22) * About setjmp and longjmp, read [setjmp](https://gitee.com/winlinvip/srs-wiki/raw/master/images/st-setjmp.jpg). * About the stack structure, read [stack](https://gitee.com/winlinvip/srs-wiki/raw/master/images/st-stack.jpg) * About asm code comments, read [#91d530e](https://github.com/ossrs/state-threads/commit/91d530e#diff-ed9428b14ff6afda0e9ab04cc91d4445R25). diff --git a/trunk/3rdparty/st-srs/auto/fast.sh b/trunk/3rdparty/st-srs/auto/fast.sh index e772ec603..8ee39f77b 100755 --- a/trunk/3rdparty/st-srs/auto/fast.sh +++ b/trunk/3rdparty/st-srs/auto/fast.sh @@ -27,4 +27,14 @@ echo "Coverage report at coverage/st.html" && open coverage/st.html popd -echo "UTest done, restore $(pwd)" \ No newline at end of file +echo "UTest done, restore $(pwd)" + +cat << END > /dev/stdout + + # CLI For DARWIN + cd $PWD && rm -f ./obj/*.gcda && + make darwin-debug-gcov && ./obj/st_utest && + mkdir -p coverage && gcovr -r . -e LINUX -e DARWIN -e examples --html --html-details -o coverage/st.html && + open coverage/st.html + +END \ No newline at end of file diff --git a/trunk/3rdparty/st-srs/common.h b/trunk/3rdparty/st-srs/common.h index 744f37bec..7eef498f7 100644 --- a/trunk/3rdparty/st-srs/common.h +++ b/trunk/3rdparty/st-srs/common.h @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of diff --git a/trunk/3rdparty/st-srs/event.c b/trunk/3rdparty/st-srs/event.c index d7e770d34..c2386b054 100644 --- a/trunk/3rdparty/st-srs/event.c +++ b/trunk/3rdparty/st-srs/event.c @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -55,8 +57,25 @@ unsigned long long _st_stat_epoll_shake = 0; unsigned long long _st_stat_epoll_spin = 0; #endif -#if !defined(MD_HAVE_KQUEUE) && !defined(MD_HAVE_EPOLL) - #error Only support epoll(for Linux) or kqueue(for Darwin) +#if !defined(MD_HAVE_KQUEUE) && !defined(MD_HAVE_EPOLL) && !defined(MD_HAVE_SELECT) + #error Only support epoll(for Linux), kqueue(for Darwin) or select(for Cygwin) +#endif + + +#ifdef MD_HAVE_SELECT +static struct _st_seldata { + fd_set fd_read_set, fd_write_set, fd_exception_set; + int fd_ref_cnts[FD_SETSIZE][3]; + int maxfd; +} *_st_select_data; + +#define _ST_SELECT_MAX_OSFD (_st_select_data->maxfd) +#define _ST_SELECT_READ_SET (_st_select_data->fd_read_set) +#define _ST_SELECT_WRITE_SET (_st_select_data->fd_write_set) +#define _ST_SELECT_EXCEP_SET (_st_select_data->fd_exception_set) +#define _ST_SELECT_READ_CNT(fd) (_st_select_data->fd_ref_cnts[fd][0]) +#define _ST_SELECT_WRITE_CNT(fd) (_st_select_data->fd_ref_cnts[fd][1]) +#define _ST_SELECT_EXCEP_CNT(fd) (_st_select_data->fd_ref_cnts[fd][2]) #endif @@ -130,6 +149,300 @@ static struct _st_epolldata { _st_eventsys_t *_st_eventsys = NULL; +#ifdef MD_HAVE_SELECT +/***************************************** + * select event system + */ + +ST_HIDDEN int _st_select_init(void) +{ + _st_select_data = (struct _st_seldata *) malloc(sizeof(*_st_select_data)); + if (!_st_select_data) + return -1; + + memset(_st_select_data, 0, sizeof(*_st_select_data)); + _st_select_data->maxfd = -1; + + return 0; +} + +ST_HIDDEN int _st_select_pollset_add(struct pollfd *pds, int npds) +{ + struct pollfd *pd; + struct pollfd *epd = pds + npds; + + /* Do checks up front */ + for (pd = pds; pd < epd; pd++) { + if (pd->fd < 0 || pd->fd >= FD_SETSIZE || !pd->events || + (pd->events & ~(POLLIN | POLLOUT | POLLPRI))) { + errno = EINVAL; + return -1; + } + } + + for (pd = pds; pd < epd; pd++) { + if (pd->events & POLLIN) { + FD_SET(pd->fd, &_ST_SELECT_READ_SET); + _ST_SELECT_READ_CNT(pd->fd)++; + } + if (pd->events & POLLOUT) { + FD_SET(pd->fd, &_ST_SELECT_WRITE_SET); + _ST_SELECT_WRITE_CNT(pd->fd)++; + } + if (pd->events & POLLPRI) { + FD_SET(pd->fd, &_ST_SELECT_EXCEP_SET); + _ST_SELECT_EXCEP_CNT(pd->fd)++; + } + if (_ST_SELECT_MAX_OSFD < pd->fd) + _ST_SELECT_MAX_OSFD = pd->fd; + } + + return 0; +} + +ST_HIDDEN void _st_select_pollset_del(struct pollfd *pds, int npds) +{ + struct pollfd *pd; + struct pollfd *epd = pds + npds; + + for (pd = pds; pd < epd; pd++) { + if (pd->events & POLLIN) { + if (--_ST_SELECT_READ_CNT(pd->fd) == 0) + FD_CLR(pd->fd, &_ST_SELECT_READ_SET); + } + if (pd->events & POLLOUT) { + if (--_ST_SELECT_WRITE_CNT(pd->fd) == 0) + FD_CLR(pd->fd, &_ST_SELECT_WRITE_SET); + } + if (pd->events & POLLPRI) { + if (--_ST_SELECT_EXCEP_CNT(pd->fd) == 0) + FD_CLR(pd->fd, &_ST_SELECT_EXCEP_SET); + } + } +} + +ST_HIDDEN void _st_select_find_bad_fd(void) +{ + _st_clist_t *q; + _st_pollq_t *pq; + int notify; + struct pollfd *pds, *epds; + int pq_max_osfd, osfd; + short events; + + _ST_SELECT_MAX_OSFD = -1; + + for (q = _ST_IOQ.next; q != &_ST_IOQ; q = q->next) { + pq = _ST_POLLQUEUE_PTR(q); + notify = 0; + epds = pq->pds + pq->npds; + pq_max_osfd = -1; + + for (pds = pq->pds; pds < epds; pds++) { + osfd = pds->fd; + pds->revents = 0; + if (pds->events == 0) + continue; + if (fcntl(osfd, F_GETFL, 0) < 0) { + pds->revents = POLLNVAL; + notify = 1; + } + if (osfd > pq_max_osfd) { + pq_max_osfd = osfd; + } + } + + if (notify) { + ST_REMOVE_LINK(&pq->links); + pq->on_ioq = 0; + /* + * Decrement the count of descriptors for each descriptor/event + * because this I/O request is being removed from the ioq + */ + for (pds = pq->pds; pds < epds; pds++) { + osfd = pds->fd; + events = pds->events; + if (events & POLLIN) { + if (--_ST_SELECT_READ_CNT(osfd) == 0) { + FD_CLR(osfd, &_ST_SELECT_READ_SET); + } + } + if (events & POLLOUT) { + if (--_ST_SELECT_WRITE_CNT(osfd) == 0) { + FD_CLR(osfd, &_ST_SELECT_WRITE_SET); + } + } + if (events & POLLPRI) { + if (--_ST_SELECT_EXCEP_CNT(osfd) == 0) { + FD_CLR(osfd, &_ST_SELECT_EXCEP_SET); + } + } + } + + if (pq->thread->flags & _ST_FL_ON_SLEEPQ) + _ST_DEL_SLEEPQ(pq->thread); + pq->thread->state = _ST_ST_RUNNABLE; + _ST_ADD_RUNQ(pq->thread); + } else { + if (_ST_SELECT_MAX_OSFD < pq_max_osfd) + _ST_SELECT_MAX_OSFD = pq_max_osfd; + } + } +} + +ST_HIDDEN void _st_select_dispatch(void) +{ + struct timeval timeout, *tvp; + fd_set r, w, e; + fd_set *rp, *wp, *ep; + int nfd, pq_max_osfd, osfd; + _st_clist_t *q; + st_utime_t min_timeout; + _st_pollq_t *pq; + int notify; + struct pollfd *pds, *epds; + short events, revents; + + /* + * Assignment of fd_sets + */ + r = _ST_SELECT_READ_SET; + w = _ST_SELECT_WRITE_SET; + e = _ST_SELECT_EXCEP_SET; + + rp = &r; + wp = &w; + ep = &e; + + if (_ST_SLEEPQ == NULL) { + tvp = NULL; + } else { + min_timeout = (_ST_SLEEPQ->due <= _ST_LAST_CLOCK) ? 0 : + (_ST_SLEEPQ->due - _ST_LAST_CLOCK); + timeout.tv_sec = (int) (min_timeout / 1000000); + timeout.tv_usec = (int) (min_timeout % 1000000); + tvp = &timeout; + } + + /* Check for I/O operations */ + nfd = select(_ST_SELECT_MAX_OSFD + 1, rp, wp, ep, tvp); + + /* Notify threads that are associated with the selected descriptors */ + if (nfd > 0) { + _ST_SELECT_MAX_OSFD = -1; + for (q = _ST_IOQ.next; q != &_ST_IOQ; q = q->next) { + pq = _ST_POLLQUEUE_PTR(q); + notify = 0; + epds = pq->pds + pq->npds; + pq_max_osfd = -1; + + for (pds = pq->pds; pds < epds; pds++) { + osfd = pds->fd; + events = pds->events; + revents = 0; + if ((events & POLLIN) && FD_ISSET(osfd, rp)) { + revents |= POLLIN; + } + if ((events & POLLOUT) && FD_ISSET(osfd, wp)) { + revents |= POLLOUT; + } + if ((events & POLLPRI) && FD_ISSET(osfd, ep)) { + revents |= POLLPRI; + } + pds->revents = revents; + if (revents) { + notify = 1; + } + if (osfd > pq_max_osfd) { + pq_max_osfd = osfd; + } + } + if (notify) { + ST_REMOVE_LINK(&pq->links); + pq->on_ioq = 0; + /* + * Decrement the count of descriptors for each descriptor/event + * because this I/O request is being removed from the ioq + */ + for (pds = pq->pds; pds < epds; pds++) { + osfd = pds->fd; + events = pds->events; + if (events & POLLIN) { + if (--_ST_SELECT_READ_CNT(osfd) == 0) { + FD_CLR(osfd, &_ST_SELECT_READ_SET); + } + } + if (events & POLLOUT) { + if (--_ST_SELECT_WRITE_CNT(osfd) == 0) { + FD_CLR(osfd, &_ST_SELECT_WRITE_SET); + } + } + if (events & POLLPRI) { + if (--_ST_SELECT_EXCEP_CNT(osfd) == 0) { + FD_CLR(osfd, &_ST_SELECT_EXCEP_SET); + } + } + } + + if (pq->thread->flags & _ST_FL_ON_SLEEPQ) + _ST_DEL_SLEEPQ(pq->thread); + pq->thread->state = _ST_ST_RUNNABLE; + _ST_ADD_RUNQ(pq->thread); + } else { + if (_ST_SELECT_MAX_OSFD < pq_max_osfd) + _ST_SELECT_MAX_OSFD = pq_max_osfd; + } + } + } else if (nfd < 0) { + /* + * It can happen when a thread closes file descriptor + * that is being used by some other thread -- BAD! + */ + if (errno == EBADF) + _st_select_find_bad_fd(); + } +} + +ST_HIDDEN int _st_select_fd_new(int osfd) +{ + if (osfd >= FD_SETSIZE) { + errno = EMFILE; + return -1; + } + + return 0; +} + +ST_HIDDEN int _st_select_fd_close(int osfd) +{ + if (_ST_SELECT_READ_CNT(osfd) || _ST_SELECT_WRITE_CNT(osfd) || + _ST_SELECT_EXCEP_CNT(osfd)) { + errno = EBUSY; + return -1; + } + + return 0; +} + +ST_HIDDEN int _st_select_fd_getlimit(void) +{ + return FD_SETSIZE; +} + +static _st_eventsys_t _st_select_eventsys = { + "select", + ST_EVENTSYS_SELECT, + _st_select_init, + _st_select_dispatch, + _st_select_pollset_add, + _st_select_pollset_del, + _st_select_fd_new, + _st_select_fd_close, + _st_select_fd_getlimit +}; +#endif + + #ifdef MD_HAVE_KQUEUE /***************************************** * kqueue event system @@ -885,20 +1198,27 @@ int st_set_eventsys(int eventsys) return -1; } -#if defined (MD_HAVE_KQUEUE) - _st_eventsys = &_st_kq_eventsys; - return 0; -#elif defined (MD_HAVE_EPOLL) - if (_st_epoll_is_supported()) { - _st_eventsys = &_st_epoll_eventsys; + if (eventsys == ST_EVENTSYS_SELECT || eventsys == ST_EVENTSYS_DEFAULT) { +#if defined (MD_HAVE_SELECT) + _st_eventsys = &_st_select_eventsys; return 0; +#endif + } + + if (eventsys == ST_EVENTSYS_ALT) { +#if defined (MD_HAVE_KQUEUE) + _st_eventsys = &_st_kq_eventsys; + return 0; +#elif defined (MD_HAVE_EPOLL) + if (_st_epoll_is_supported()) { + _st_eventsys = &_st_epoll_eventsys; + return 0; + } +#endif } errno = EINVAL; return -1; -#else - #error Only support epoll(for Linux) or kqueue(for Darwin) -#endif } int st_get_eventsys(void) diff --git a/trunk/3rdparty/st-srs/io.c b/trunk/3rdparty/st-srs/io.c index c4ec8f010..22998b05c 100644 --- a/trunk/3rdparty/st-srs/io.c +++ b/trunk/3rdparty/st-srs/io.c @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of diff --git a/trunk/3rdparty/st-srs/key.c b/trunk/3rdparty/st-srs/key.c index 5e64022c0..03f73a73a 100644 --- a/trunk/3rdparty/st-srs/key.c +++ b/trunk/3rdparty/st-srs/key.c @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of diff --git a/trunk/3rdparty/st-srs/md.h b/trunk/3rdparty/st-srs/md.h index a7e77eab7..037612072 100644 --- a/trunk/3rdparty/st-srs/md.h +++ b/trunk/3rdparty/st-srs/md.h @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -67,7 +69,7 @@ #define MD_USE_BUILTIN_SETJMP #if defined(__amd64__) || defined(__x86_64__) - #define JB_SP 12 + #define JB_SP 12 /* The jmpbuf is int(4B) array, while MD_GET_SP covert to long(8B) pointer, so the JB_SP should be 12 which is 6*sizeof(long)/sizeof(int) */ #define MD_GET_SP(_t) *((long *)&((_t)->context[JB_SP])) #else #error Unknown CPU architecture @@ -115,15 +117,7 @@ (void) gettimeofday(&tv, NULL); \ return (tv.tv_sec * 1000000LL + tv.tv_usec) - #if defined(__mips__) - #define MD_INIT_CONTEXT(_thread, _sp, _main) \ - ST_BEGIN_MACRO \ - MD_SETJMP((_thread)->context); \ - _thread->context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \ - _thread->context[0].__jmpbuf[0].__sp = _sp; \ - ST_END_MACRO - - #else /* Not mips */ + #if 1 /* * On linux, there are a few styles of jmpbuf format. These vary based @@ -188,6 +182,11 @@ #error "ARM/Linux pre-glibc2 not supported yet" #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */ + #elif defined(__mips__) + /* https://github.com/ossrs/state-threads/issues/21 */ + #define MD_USE_BUILTIN_SETJMP + #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jb[0])) + #else #error "Unknown CPU architecture" #endif /* Cases with common MD_INIT_CONTEXT and different SP locations */ @@ -212,6 +211,42 @@ #define MD_LONGJMP(env, val) longjmp(env, val) #endif +#elif defined (CYGWIN64) + + // For CYGWIN64, build SRS on Windows. + #define MD_USE_BSD_ANON_MMAP + #define MD_ACCEPT_NB_INHERITED + #define MD_HAVE_SOCKLEN_T + + #define MD_USE_BUILTIN_SETJMP + + #if defined(__amd64__) || defined(__x86_64__) + #define JB_SP 6 // The context is long(32) array, @see https://github.com/ossrs/state-threads/issues/20#issuecomment-887569093 + #define MD_GET_SP(_t) *((long *)&((_t)->context[JB_SP])) + #else + #error Unknown CPU architecture + #endif + + #define MD_INIT_CONTEXT(_thread, _sp, _main) \ + ST_BEGIN_MACRO \ + if (MD_SETJMP((_thread)->context)) \ + _main(); \ + MD_GET_SP(_thread) = (long) (_sp); \ + ST_END_MACRO + + #if defined(MD_USE_BUILTIN_SETJMP) + #define MD_SETJMP(env) _st_md_cxt_save(env) + #define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val) + + extern int _st_md_cxt_save(jmp_buf env); + extern void _st_md_cxt_restore(jmp_buf env, int val); + #endif + + #define MD_GET_UTIME() \ + struct timeval tv; \ + (void) gettimeofday(&tv, NULL); \ + return (tv.tv_sec * 1000000LL + tv.tv_usec) + #else #error Unknown OS #endif /* OS */ diff --git a/trunk/3rdparty/st-srs/md_cygwin64.S b/trunk/3rdparty/st-srs/md_cygwin64.S new file mode 100644 index 000000000..332ef3384 --- /dev/null +++ b/trunk/3rdparty/st-srs/md_cygwin64.S @@ -0,0 +1,77 @@ + +/* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */ +#if !defined(MD_ST_NO_ASM) + +#if defined(__amd64__) || defined(__x86_64__) + + /****************************************************************/ + + /* + * Internal __jmp_buf layout + */ + #define JB_RBX 0 + #define JB_RBP 1 + #define JB_R12 2 /* R12:R15 Nonvolatile Must be preserved by callee */ + #define JB_R13 3 /* @see https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-160#register-usage */ + #define JB_R14 4 /* RBX, RBP, RDI, RSI, R12, R14, R14, and R15 must be saved in any function using them. */ + #define JB_R15 5 /* @see https://software.intel.com/content/www/us/en/develop/articles/introduction-to-x64-assembly.html */ + #define JB_RSP 6 + #define JB_PC 7 + + .file "md_cygwin64.S" + .text + + /* _st_md_cxt_save(__jmp_buf env) */ /* The env is rcx, https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160 */ + .globl _st_md_cxt_save + .align 16 + _st_md_cxt_save: + /* + * Save registers. + */ + movq %rbx, (JB_RBX*8)(%rcx) /* Save rbx to env[0], *(int64_t*)(rcx+0)=rbx */ + movq %rbp, (JB_RBP*8)(%rcx) /* Save rbp to env[1], *(int64_t*)(rcx+1)=rbp */ + movq %r12, (JB_R12*8)(%rcx) /* Save r12 to env[2], *(int64_t*)(rcx+2)=r12 */ + movq %r13, (JB_R13*8)(%rcx) /* Save r13 to env[3], *(int64_t*)(rcx+3)=r13 */ + movq %r14, (JB_R14*8)(%rcx) /* Save r14 to env[4], *(int64_t*)(rcx+4)=r14 */ + movq %r15, (JB_R15*8)(%rcx) /* Save r15 to env[5], *(int64_t*)(rcx+5)=r15 */ + /* Save SP */ + leaq 8(%rsp), %r8 /* Save *(int64_t*)(rsp+8) to r8, https://github.com/ossrs/state-threads/issues/20#issuecomment-887569093 */ + movq %r8, (JB_RSP*8)(%rcx) /* Save r8(rsp) to env[6], *(int64_t*)(rcx+6)=r8 */ + /* Save PC we are returning to */ + movq (%rsp), %r9 /* Save PC(parent function address) %(rsp) to r9, https://github.com/ossrs/state-threads/issues/20#issuecomment-887569093 */ + movq %r9, (JB_PC*8)(%rcx) /* Save r9(PC) to env[7], *(int64_t*)(rcx+7)=r9 */ + xorq %rax, %rax /* Reset rax(return value) to 0 */ + ret + + + /****************************************************************/ + + /* _st_md_cxt_restore(__jmp_buf env, int val) */ /* The env is rcx, val is edx/rdx, https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160 */ + .globl _st_md_cxt_restore + .align 16 + _st_md_cxt_restore: + /* + * Restore registers. + */ + movq (JB_RBX*8)(%rcx), %rbx /* Load rbx from env[0] */ + movq (JB_RBP*8)(%rcx), %rbp /* Load rbp from env[1] */ + movq (JB_R12*8)(%rcx), %r12 /* Load r12 from env[2] */ + movq (JB_R13*8)(%rcx), %r13 /* Load r13 from env[3] */ + movq (JB_R14*8)(%rcx), %r14 /* Load r14 from env[4] */ + movq (JB_R15*8)(%rcx), %r15 /* Load r15 from env[5] */ + /* Set return value */ /* The edx is param1 val, the eax is return value */ + test %edx, %edx /* if (!val) { */ + mov $01, %eax /* val=1; */ + cmove %eax, %edx /* } */ + mov %edx, %eax /* return val; */ + /* Restore PC and RSP */ + movq (JB_PC*8)(%rcx), %r8 /* Load r8(PC) from env[7], https://github.com/ossrs/state-threads/issues/20#issuecomment-887569093 */ + movq (JB_RSP*8)(%rcx), %rsp /* Load rsp from env[6] */ + /* Jump to saved PC */ + jmpq *%r8 /* Jump to r8(PC) */ + + /****************************************************************/ + +#endif + +#endif diff --git a/trunk/3rdparty/st-srs/md_darwin.S b/trunk/3rdparty/st-srs/md_darwin.S index 7ccf65f87..cfad14ce7 100644 --- a/trunk/3rdparty/st-srs/md_darwin.S +++ b/trunk/3rdparty/st-srs/md_darwin.S @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright (c) 2021 Winlin */ /* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */ #if !defined(MD_ST_NO_ASM) diff --git a/trunk/3rdparty/st-srs/md_linux.S b/trunk/3rdparty/st-srs/md_linux.S index d8da00374..333b2e391 100644 --- a/trunk/3rdparty/st-srs/md_linux.S +++ b/trunk/3rdparty/st-srs/md_linux.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ /* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */ #if !defined(MD_ST_NO_ASM) @@ -347,6 +348,86 @@ /****************************************************************/ + + + + + + + + + +#elif defined(__mips__) + + /****************************************************************/ + + /* + * Internal __jmp_buf layout + */ + #define JB_SP 0 /* Stack pointer */ + #define JB_RA 11 /* Return address */ + #define JB_GP 1 /* Global pointer */ + #define JB_S0 3 /* S0-S7, Saved temporaries */ + #define JB_S1 4 /* S0-S7, Saved temporaries */ + #define JB_S2 5 /* S0-S7, Saved temporaries */ + #define JB_S3 6 /* S0-S7, Saved temporaries */ + #define JB_S4 7 /* S0-S7, Saved temporaries */ + #define JB_S5 8 /* S0-S7, Saved temporaries */ + #define JB_S6 9 /* S0-S7, Saved temporaries */ + #define JB_S7 10 /* S0-S7, Saved temporaries */ + #define JB_FP 2 /* FP/S8 Frame pointer */ + + .file "md_linux.S" + .text + + /* _st_md_cxt_save(__jmp_buf env) */ /* The env is $a0, https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions */ + .globl _st_md_cxt_save + .type _st_md_cxt_save, %function + .align 2 + _st_md_cxt_save: + sw $sp, 0($a0) /* Save sp to env[0], *(long*)($a0+0) =sp */ + sw $ra, 4($a0) /* Save ra to env[1], *(long*)($a0+4)=ra, the return address, https://chortle.ccsu.edu/AssemblyTutorial/Chapter-26/ass26_4.html */ + sw $gp, 8($a0) /* Save gp to env[2], *(long*)($a0+8) =gp */ + sw $s0, 12($a0) /* Save s0 to env[3], *(long*)($a0+12)=s0 */ + sw $s1, 16($a0) /* Save s1 to env[4], *(long*)($a0+16)=s1 */ + sw $s2, 20($a0) /* Save s2 to env[5], *(long*)($a0+20)=s2 */ + sw $s3, 24($a0) /* Save s3 to env[6], *(long*)($a0+24)=s3 */ + sw $s4, 28($a0) /* Save s4 to env[7], *(long*)($a0+28)=s4 */ + sw $s5, 32($a0) /* Save s5 to env[8], *(long*)($a0+32)=s5 */ + sw $s6, 36($a0) /* Save s6 to env[9], *(long*)($a0+36)=s6 */ + sw $s7, 40($a0) /* Save s7 to env[10], *(long*)($a0+40)=s7 */ + sw $fp, 44($a0) /* Save fp to env[11], *(long*)($a0+44) =fp */ + li $v0, 0 /* Set return value to 0 */ + jr $ra /* Return */ + + .size _st_md_cxt_save, .-_st_md_cxt_save + + /****************************************************************/ + + /* _st_md_cxt_restore(__jmp_buf env, int val) */ + .globl _st_md_cxt_restore + .type _st_md_cxt_restore, %function + .align 2 + _st_md_cxt_restore: + lw $sp, 0($a0) /* Load sp from env[0], sp=*(long*)($a0+0) */ + lw $ra, 4($a0) /* Load sp from env[1], ra=*(long*)($a0+4), the saved return address */ + lw $gp, 8($a0) /* Load sp from env[2], gp=*(long*)($a0+8) */ + lw $s0, 12($a0) /* Load sp from env[3], s0=*(long*)($a0+12) */ + lw $s1, 16($a0) /* Load sp from env[4], s1=*(long*)($a0+16) */ + lw $s2, 20($a0) /* Load sp from env[5], s2=*(long*)($a0+20) */ + lw $s3, 24($a0) /* Load sp from env[6], s3=*(long*)($a0+24) */ + lw $s4, 28($a0) /* Load sp from env[7], s4=*(long*)($a0+28) */ + lw $s5, 32($a0) /* Load sp from env[8], s5=*(long*)($a0+32) */ + lw $s6, 36($a0) /* Load sp from env[9], s6=*(long*)($a0+36) */ + lw $s7, 40($a0) /* Load sp from env[10], s7=*(long*)($a0+40) */ + lw $fp, 44($a0) /* Load sp from env[2], fp=*(long*)($a0+44) */ + li $v0, 1 /* Set return value to 1 */ + jr $ra /* Return to the saved return address */ + + .size _st_md_cxt_restore, .-_st_md_cxt_restore + + /****************************************************************/ + #endif #endif diff --git a/trunk/3rdparty/st-srs/public.h b/trunk/3rdparty/st-srs/public.h index b7217ca53..75f53a4c2 100644 --- a/trunk/3rdparty/st-srs/public.h +++ b/trunk/3rdparty/st-srs/public.h @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -65,6 +67,7 @@ #endif #define ST_EVENTSYS_DEFAULT 0 +#define ST_EVENTSYS_SELECT 1 #define ST_EVENTSYS_ALT 3 #ifdef __cplusplus diff --git a/trunk/3rdparty/st-srs/sched.c b/trunk/3rdparty/st-srs/sched.c index 2fe9c1822..845b7f4d7 100644 --- a/trunk/3rdparty/st-srs/sched.c +++ b/trunk/3rdparty/st-srs/sched.c @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of diff --git a/trunk/3rdparty/st-srs/stk.c b/trunk/3rdparty/st-srs/stk.c index 3e681e595..6569e78e8 100644 --- a/trunk/3rdparty/st-srs/stk.c +++ b/trunk/3rdparty/st-srs/stk.c @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of diff --git a/trunk/3rdparty/st-srs/sync.c b/trunk/3rdparty/st-srs/sync.c index 907fdfac3..f69e22477 100644 --- a/trunk/3rdparty/st-srs/sync.c +++ b/trunk/3rdparty/st-srs/sync.c @@ -1,4 +1,6 @@ -/* +/* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ + +/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of diff --git a/trunk/3rdparty/st-srs/tools/helloworld/.gitignore b/trunk/3rdparty/st-srs/tools/helloworld/.gitignore new file mode 100644 index 000000000..31e0fce56 --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/helloworld/.gitignore @@ -0,0 +1 @@ +helloworld diff --git a/trunk/3rdparty/st-srs/tools/helloworld/Makefile b/trunk/3rdparty/st-srs/tools/helloworld/Makefile new file mode 100644 index 000000000..2ec9a2d78 --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/helloworld/Makefile @@ -0,0 +1,11 @@ +.PHONY: clean + +LDLIBS=../../obj/libst.a +CFLAGS=-g -O0 -I../../obj + +./helloworld: helloworld.c $(LDLIBS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o helloworld helloworld.c $(LDLIBS) + +clean: + rm -f helloworld + diff --git a/trunk/3rdparty/st-srs/tools/helloworld/helloworld.c b/trunk/3rdparty/st-srs/tools/helloworld/helloworld.c new file mode 100644 index 000000000..2f3481a5c --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/helloworld/helloworld.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright (c) 2021 Winlin */ + +#include + +#include + +int main(int argc, char** argv) +{ + st_init(); + + for (int i = 0; i < 10000; i++) { + printf("#%03d, Hello, state-threads world!\n", i); + st_sleep(1); + } + + return 0; +} + diff --git a/trunk/3rdparty/st-srs/tools/porting/.gitignore b/trunk/3rdparty/st-srs/tools/porting/.gitignore new file mode 100644 index 000000000..d9bcb42a5 --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/porting/.gitignore @@ -0,0 +1 @@ +porting diff --git a/trunk/3rdparty/st-srs/tools/porting/Makefile b/trunk/3rdparty/st-srs/tools/porting/Makefile new file mode 100644 index 000000000..e31722b97 --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/porting/Makefile @@ -0,0 +1,10 @@ +.PHONY: clean + +CFLAGS=-g -O0 + +./porting: porting.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) + +clean: + rm -f porting + diff --git a/trunk/3rdparty/st-srs/tools/porting/porting.c b/trunk/3rdparty/st-srs/tools/porting/porting.c new file mode 100644 index 000000000..1f1f4977a --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/porting/porting.c @@ -0,0 +1,157 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright (c) 2021 Winlin */ + +#include +#include + +int foo_return_zero(); +int foo_return_one(); +extern void print_buf(unsigned char* p, int nn_jb); +extern void print_jmpbuf(); + +int main(int argc, char** argv) +{ + printf("OS specs:\n"); +#ifdef __linux__ + printf("__linux__: %d\n", __linux__); +#endif +#ifdef __APPLE__ + printf("__APPLE__: %d\n", __APPLE__); +#endif + + printf("\nCPU specs:\n"); +#ifdef __mips__ + // https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00565-2B-MIPS32-QRC-01.01.pdf + printf("__mips__: %d, __mips:%d, _MIPSEL:%d\n", __mips__, __mips, _MIPSEL); +#endif +#ifdef __x86_64__ + printf("__x86_64__: %d\n", __x86_64__); +#endif + + printf("\nCompiler specs:\n"); +#ifdef __GLIBC__ + printf("__GLIBC__: %d\n", __GLIBC__); +#endif + printf("sizeof(long)=%d\n", (int)sizeof(long)); + printf("sizeof(long long int)=%d\n", (int)sizeof(long long int)); + printf("sizeof(void*)=%d\n", (int)sizeof(void*)); +#ifdef __ptr_t + printf("sizeof(__ptr_t)=%d\n", sizeof(__ptr_t)); +#endif + + printf("\nReturn value:\n"); + int r0 = foo_return_zero(); + int r1 = foo_return_one(); + printf("foo_return_zero=%d, foo_return_one=%d\n", r0, r1); + + printf("\nCalling conventions:\n"); + print_jmpbuf(); + + return 0; +} + +int foo_return_zero() +{ + return 0; +} + +int foo_return_one() +{ + return 1; +} + +#ifdef __linux__ +#ifdef __mips__ +void print_jmpbuf() +{ + // https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions + register void* ra asm("ra"); + register void* gp asm("gp"); + register void* sp asm("sp"); + register void* fp asm("fp"); + // $s0–$s7 $16–$23 saved temporaries + register void* s0 asm("s0"); + register void* s1 asm("s1"); + register void* s2 asm("s2"); + register void* s3 asm("s3"); + register void* s4 asm("s4"); + register void* s5 asm("s5"); + register void* s6 asm("s6"); + register void* s7 asm("s7"); + + /* + typedef unsigned long long __jmp_buf[13]; + typedef struct __jmp_buf_tag { + __jmp_buf __jb; + unsigned long __fl; + unsigned long __ss[128/sizeof(long)]; + } jmp_buf[1]; + */ + jmp_buf ctx = {0}; + int r0 = setjmp(ctx); + if (!r0) { + longjmp(ctx, 1); + } + + printf("ra=%p, sp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, fp=%p, gp=%p\n", + ra, sp, s0, s1, s2, s3, s4, s5, s6, s7, fp, gp); + + int nn_jb = sizeof(ctx[0].__jb); + printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8); + + unsigned char* p = (unsigned char*)ctx[0].__jb; + print_buf(p, nn_jb); +} +#endif +#endif + +#ifdef __APPLE__ +#ifdef __x86_64__ +void print_jmpbuf() +{ + // https://courses.cs.washington.edu/courses/cse378/10au/sections/Section1_recap.pdf + void *rbx, *rbp, *r12, *r13, *r14, *r15, *rsp; + __asm__ __volatile__ ("movq %%rbx,%0": "=r"(rbx): /* No input */); + __asm__ __volatile__ ("movq %%rbp,%0": "=r"(rbp): /* No input */); + __asm__ __volatile__ ("movq %%r12,%0": "=r"(r12): /* No input */); + __asm__ __volatile__ ("movq %%r13,%0": "=r"(r13): /* No input */); + __asm__ __volatile__ ("movq %%r14,%0": "=r"(r14): /* No input */); + __asm__ __volatile__ ("movq %%r15,%0": "=r"(r15): /* No input */); + __asm__ __volatile__ ("movq %%rsp,%0": "=r"(rsp): /* No input */); + + printf("rbx=%p, rbp=%p, r12=%p, r13=%p, r14=%p, r15=%p, rsp=%p\n", + rbx, rbp, r12, r13, r14, r15, rsp); + + jmp_buf ctx = {0}; + int r0 = setjmp(ctx); + if (!r0) { + longjmp(ctx, 1); + } + + int nn_jb = sizeof(ctx); + printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8); + + unsigned char* p = (unsigned char*)ctx; + print_buf(p, nn_jb); +} +#endif +#endif + +void print_buf(unsigned char* p, int nn_jb) +{ + printf(" "); + + for (int i = 0; i < nn_jb; i++) { + printf("0x%02x ", (unsigned char)p[i]); + + int newline = ((i + 1) % sizeof(void*)); + if (!newline || i == nn_jb - 1) { + printf("\n"); + } + + if (!newline && i < nn_jb - 1) { + printf(" "); + } + } +} + diff --git a/trunk/3rdparty/st-srs/tools/verify/.gitignore b/trunk/3rdparty/st-srs/tools/verify/.gitignore new file mode 100644 index 000000000..0b5987362 --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/verify/.gitignore @@ -0,0 +1 @@ +verify diff --git a/trunk/3rdparty/st-srs/tools/verify/Makefile b/trunk/3rdparty/st-srs/tools/verify/Makefile new file mode 100644 index 000000000..7c0107cf9 --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/verify/Makefile @@ -0,0 +1,11 @@ +.PHONY: clean + +LDLIBS=../../obj/libst.a +CFLAGS=-g -O0 + +./verify: verify.c $(LDLIBS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o verify verify.c $(LDLIBS) + +clean: + rm -f verify + diff --git a/trunk/3rdparty/st-srs/tools/verify/verify.c b/trunk/3rdparty/st-srs/tools/verify/verify.c new file mode 100644 index 000000000..316c5597d --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/verify/verify.c @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright (c) 2021 Winlin */ + +#include + +#include +extern int _st_md_cxt_save(jmp_buf env); +extern void _st_md_cxt_restore(jmp_buf env, int val); + +void verify_jmpbuf(); +void print_buf(unsigned char* p, int nn_jb); + +int main(int argc, char** argv) +{ + verify_jmpbuf(); + return 0; +} + +#ifdef __linux__ +#ifdef __mips__ +void verify_jmpbuf() +{ + // https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions + register void* ra asm("ra"); + register void* gp asm("gp"); + register void* sp asm("sp"); + register void* fp asm("fp"); + // $s0–$s7 $16–$23 saved temporaries + register void* s0 asm("s0"); + register void* s1 asm("s1"); + register void* s2 asm("s2"); + register void* s3 asm("s3"); + register void* s4 asm("s4"); + register void* s5 asm("s5"); + register void* s6 asm("s6"); + register void* s7 asm("s7"); + + jmp_buf ctx = {0}; + int r0 = _st_md_cxt_save(ctx); + if (!r0) { + _st_md_cxt_restore(ctx, 1); // Restore/Jump to previous line, set r0 to 1. + } + + printf("sp=%p, ra=%p, gp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, fp=%p\n", + sp, ra, gp, s0, s1, s2, s3, s4, s5, s6, s7, fp); + + int nn_jb = sizeof(ctx[0].__jb); + unsigned char* p = (unsigned char*)ctx[0].__jb; + print_buf(p, nn_jb); +} +#endif +#endif + +#ifdef __APPLE__ +#ifdef __x86_64__ +void verify_jmpbuf() +{ + // https://courses.cs.washington.edu/courses/cse378/10au/sections/Section1_recap.pdf + void *rbx, *rbp, *r12, *r13, *r14, *r15, *rsp; + __asm__ __volatile__ ("movq %%rbx,%0": "=r"(rbx): /* No input */); + __asm__ __volatile__ ("movq %%rbp,%0": "=r"(rbp): /* No input */); + __asm__ __volatile__ ("movq %%r12,%0": "=r"(r12): /* No input */); + __asm__ __volatile__ ("movq %%r13,%0": "=r"(r13): /* No input */); + __asm__ __volatile__ ("movq %%r14,%0": "=r"(r14): /* No input */); + __asm__ __volatile__ ("movq %%r15,%0": "=r"(r15): /* No input */); + __asm__ __volatile__ ("movq %%rsp,%0": "=r"(rsp): /* No input */); + + printf("rbx=%p, rbp=%p, r12=%p, r13=%p, r14=%p, r15=%p, rsp=%p\n", + rbx, rbp, r12, r13, r14, r15, rsp); + + jmp_buf ctx = {0}; + int r0 = _st_md_cxt_save(ctx); + if (!r0) { + _st_md_cxt_restore(ctx, 1); // Restore/Jump to previous line, set r0 to 1. + } + + int nn_jb = sizeof(ctx); + printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8); + + unsigned char* p = (unsigned char*)ctx; + print_buf(p, nn_jb); +} +#endif +#endif + +void print_buf(unsigned char* p, int nn_jb) +{ + printf(" "); + + for (int i = 0; i < nn_jb; i++) { + printf("0x%02x ", (unsigned char)p[i]); + + int newline = ((i + 1) % sizeof(void*)); + if (!newline || i == nn_jb - 1) { + printf("\n"); + } + + if (!newline && i < nn_jb - 1) { + printf(" "); + } + } +} + diff --git a/trunk/3rdparty/st-srs/utest/Makefile b/trunk/3rdparty/st-srs/utest/Makefile index 5be3a408d..a294af7b6 100644 --- a/trunk/3rdparty/st-srs/utest/Makefile +++ b/trunk/3rdparty/st-srs/utest/Makefile @@ -28,7 +28,7 @@ GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_DIR)/include/gt # compiles fast and for ordinary users its source rarely changes. $(ST_DIR)/obj/gtest-all.o : $(GTEST_SRCS_) $(CXX) -c $(GTEST_DIR)/src/gtest-all.cc -o $@ \ - $(CXXFLAGS) \ + $(CXXFLAGS) $(UTEST_FLAGS) \ $(WARNFLAGS) \ -I$(GTEST_DIR)/include -I$(GTEST_DIR) diff --git a/trunk/3rdparty/st-srs/utest/st_utest.cpp b/trunk/3rdparty/st-srs/utest/st_utest.cpp index a31744bc0..469b16e95 100644 --- a/trunk/3rdparty/st-srs/utest/st_utest.cpp +++ b/trunk/3rdparty/st-srs/utest/st_utest.cpp @@ -1,25 +1,5 @@ -/* -The MIT License (MIT) - -Copyright (c) 2021 Winlin - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ +/* SPDX-License-Identifier: MIT */ +/* Copyright (c) 2021 Winlin */ #include @@ -30,8 +10,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // Copy from gtest-1.6.0/src/gtest_main.cc GTEST_API_ int main(int argc, char **argv) { // Select the best event system available on the OS. In Linux this is - // epoll(). On BSD it will be kqueue. + // epoll(). On BSD it will be kqueue. On Cygwin it will be select. +#if __CYGWIN__ + assert(st_set_eventsys(ST_EVENTSYS_SELECT) != -1); +#else assert(st_set_eventsys(ST_EVENTSYS_ALT) != -1); +#endif + + // Initialize state-threads, create idle coroutine. assert(st_init() == 0); testing::InitGoogleTest(&argc, argv); @@ -47,3 +33,107 @@ VOID TEST(SampleTest, FastSampleInt64Test) EXPECT_EQ(8, (int)sizeof(int64_t)); } +void* pfn_coroutine(void* /*arg*/) +{ + st_usleep(0); + return NULL; +} + +VOID TEST(SampleTest, StartCoroutine) +{ + st_thread_t trd = st_thread_create(pfn_coroutine, NULL, 1, 0); + EXPECT_TRUE(trd != NULL); + + // Wait for joinable coroutine to quit. + st_thread_join(trd, NULL); +} + +VOID TEST(SampleTest, StartCoroutineX3) +{ + st_thread_t trd0 = st_thread_create(pfn_coroutine, NULL, 1, 0); + st_thread_t trd1 = st_thread_create(pfn_coroutine, NULL, 1, 0); + st_thread_t trd2 = st_thread_create(pfn_coroutine, NULL, 1, 0); + EXPECT_TRUE(trd0 != NULL && trd1 != NULL && trd2 != NULL); + + // Wait for joinable coroutine to quit. + st_thread_join(trd1, NULL); + st_thread_join(trd2, NULL); + st_thread_join(trd0, NULL); +} + +void* pfn_coroutine_add(void* arg) +{ + int v = 0; + int* pi = (int*)arg; + + // Load the change of arg. + while (v != *pi) { + v = *pi; + st_usleep(0); + } + + // Add with const. + v += 100; + *pi = v; + + return NULL; +} + +VOID TEST(SampleTest, StartCoroutineAdd) +{ + int v = 0; + st_thread_t trd = st_thread_create(pfn_coroutine_add, &v, 1, 0); + EXPECT_TRUE(trd != NULL); + + // Wait for joinable coroutine to quit. + st_thread_join(trd, NULL); + + EXPECT_EQ(100, v); +} + +VOID TEST(SampleTest, StartCoroutineAddX3) +{ + int v = 0; + st_thread_t trd0 = st_thread_create(pfn_coroutine_add, &v, 1, 0); + st_thread_t trd1 = st_thread_create(pfn_coroutine_add, &v, 1, 0); + st_thread_t trd2 = st_thread_create(pfn_coroutine_add, &v, 1, 0); + EXPECT_TRUE(trd0 != NULL && trd1 != NULL && trd2 != NULL); + + // Wait for joinable coroutine to quit. + st_thread_join(trd0, NULL); + st_thread_join(trd1, NULL); + st_thread_join(trd2, NULL); + + EXPECT_EQ(300, v); +} + +int pfn_coroutine_params_x4(int a, int b, int c, int d) +{ + int e = 0; + + st_usleep(0); + + e += a + b + c + d; + e += 100; + return e; +} + +void* pfn_coroutine_params(void* arg) +{ + int r0 = pfn_coroutine_params_x4(1, 2, 3, 4); + *(int*)arg = r0; + return NULL; +} + +VOID TEST(SampleTest, StartCoroutineParams) +{ + int r0 = 0; + st_thread_t trd = st_thread_create(pfn_coroutine_params, &r0, 1, 0); + EXPECT_TRUE(trd != NULL); + + // Wait for joinable coroutine to quit. + st_thread_join(trd, NULL); + + EXPECT_EQ(110, r0); +} + diff --git a/trunk/3rdparty/st-srs/utest/st_utest.hpp b/trunk/3rdparty/st-srs/utest/st_utest.hpp index a310bb0fe..8d39a06b2 100644 --- a/trunk/3rdparty/st-srs/utest/st_utest.hpp +++ b/trunk/3rdparty/st-srs/utest/st_utest.hpp @@ -1,25 +1,5 @@ -/* -The MIT License (MIT) - -Copyright (c) 2021 Winlin - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ +/* SPDX-License-Identifier: MIT */ +/* Copyright (c) 2021 Winlin */ #ifndef ST_UTEST_PUBLIC_HPP #define ST_UTEST_PUBLIC_HPP diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 499b36142..bd4067460 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -8,8 +8,9 @@ The changelog for SRS. ## SRS 5.0 Changelog +* v5.0, 2021-10-02, ST: Support Cygwin64 and MIPS. 5.0.13 * v5.0, 2021-09-23, Merge [#2578](https://github.com/ossrs/srs/pull/2578) Support http callback on_play/stop. 5.0.12 -* v4.0, 2021-08-07, Fix [#2508](https://github.com/ossrs/srs/pull/2508), Support features query by API. 5.0.10 +* v5.0, 2021-08-07, Fix [#2508](https://github.com/ossrs/srs/pull/2508), Support features query by API. 5.0.10 * v5.0, 2021-07-07, Refine AUTHORS.txt to AUTHORS.md, etc. 5.0.8 * v5.0, 2021-07-01, Move AUTHORS.txt to trunk for docker. 5.0.7 * v5.0, 2021-06-28, Squash: Support query lastest available version. 5.0.6 diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index 2181492b1..67167dba9 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 12 +#define VERSION_REVISION 13 #endif