1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

Merge branch 'develop' into merge/develop

This commit is contained in:
winlin 2021-10-02 18:57:01 +08:00
commit 78e5b6f1b0
31 changed files with 1119 additions and 107 deletions

View file

@ -1,5 +1,6 @@
DARWIN_*_DBG
LINUX_*_DBG
CYGWIN64_*_DBG
obj
st.pc
.idea
@ -10,3 +11,4 @@ googletest-*
*.gcno
coverage
codecov
*.dSYM

30
trunk/3rdparty/st-srs/LICENSE vendored Normal file
View file

@ -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.

View file

@ -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 <target>
#
# 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"

View file

@ -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).

View file

@ -27,4 +27,14 @@ echo "Coverage report at coverage/st.html" &&
open coverage/st.html
popd
echo "UTest done, restore $(pwd)"
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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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 */

77
trunk/3rdparty/st-srs/md_cygwin64.S vendored Normal file
View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
helloworld

View file

@ -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

View file

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2021 Winlin */
#include <stdio.h>
#include <st.h>
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;
}

View file

@ -0,0 +1 @@
porting

View file

@ -0,0 +1,10 @@
.PHONY: clean
CFLAGS=-g -O0
./porting: porting.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS)
clean:
rm -f porting

View file

@ -0,0 +1,157 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2021 Winlin */
#include <stdio.h>
#include <setjmp.h>
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(" ");
}
}
}

View file

@ -0,0 +1 @@
verify

View file

@ -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

View file

@ -0,0 +1,103 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2021 Winlin */
#include <stdio.h>
#include <setjmp.h>
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(" ");
}
}
}

View file

@ -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)

View file

@ -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 <st_utest.hpp>
@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -9,6 +9,6 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 12
#define VERSION_REVISION 13
#endif