2
0

srs.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <arpa/inet.h>
  7. #include <signal.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include "public.h"
  12. #define srs_trace(msg, ...) printf(msg, ##__VA_ARGS__);printf("\n")
  13. int io_port = 1990;
  14. int sleep_ms = 100;
  15. void stack_print(long int previous_sp, int level)
  16. {
  17. if (level <= 0) {
  18. return;
  19. }
  20. register long int rsp asm("sp");
  21. char buf[level * 1024];
  22. stack_print(rsp, level - 1);
  23. srs_trace("%d. psp=%#lx, sp=%#lx, size=%dB(%dB+%dKB)",
  24. level, previous_sp, rsp, (int)(previous_sp - rsp),
  25. (int)(previous_sp - rsp - sizeof(buf)), (int)(sizeof(buf) / 1024));
  26. }
  27. int huge_stack_test()
  28. {
  29. srs_trace("===================================================");
  30. srs_trace("huge_stack test: start");
  31. register long int rsp asm("sp");
  32. stack_print(rsp, 10);
  33. srs_trace("huge_stack test: end");
  34. return 0;
  35. }
  36. int sleep_test()
  37. {
  38. srs_trace("===================================================");
  39. srs_trace("sleep test: start");
  40. srs_trace("1. sleep...");
  41. st_utime_t start = st_utime();
  42. st_usleep(sleep_ms * 1000);
  43. st_utime_t end = st_utime();
  44. srs_trace("2. sleep ok, sleep=%dus, deviation=%dus",
  45. (int)(sleep_ms * 1000), (int)(end - start - sleep_ms * 1000));
  46. srs_trace("sleep test: end");
  47. return 0;
  48. }
  49. void* sleep2_func0(void* arg)
  50. {
  51. int sleep_ms = 100;
  52. st_utime_t start = st_utime();
  53. st_usleep(sleep_ms * 1000);
  54. st_utime_t end = st_utime();
  55. srs_trace("sleep ok, sleep=%dus, deviation=%dus",
  56. (int)(sleep_ms * 1000), (int)(end - start - sleep_ms * 1000));
  57. return NULL;
  58. }
  59. void* sleep2_func1(void* arg)
  60. {
  61. int sleep_ms = 250;
  62. st_utime_t start = st_utime();
  63. st_usleep(sleep_ms * 1000);
  64. st_utime_t end = st_utime();
  65. srs_trace("sleep ok, sleep=%dus, deviation=%dus",
  66. (int)(sleep_ms * 1000), (int)(end - start - sleep_ms * 1000));
  67. return NULL;
  68. }
  69. int sleep2_test()
  70. {
  71. srs_trace("===================================================");
  72. srs_trace("sleep2 test: start");
  73. st_thread_t trd0 = st_thread_create(sleep2_func0, NULL, 1, 0);
  74. st_thread_t trd1 = st_thread_create(sleep2_func1, NULL, 1, 0);
  75. st_thread_join(trd0, NULL);
  76. st_thread_join(trd1, NULL);
  77. srs_trace("sleep test: end");
  78. return 0;
  79. }
  80. st_mutex_t sleep_work_cond = NULL;
  81. void* sleep_deviation_func(void* arg)
  82. {
  83. st_mutex_lock(sleep_work_cond);
  84. srs_trace("2. work thread start.");
  85. int64_t i;
  86. for (i = 0; i < 3000000000ULL; i++) {
  87. }
  88. st_mutex_unlock(sleep_work_cond);
  89. srs_trace("3. work thread end.");
  90. return NULL;
  91. }
  92. int sleep_deviation_test()
  93. {
  94. srs_trace("===================================================");
  95. srs_trace("sleep deviation test: start");
  96. sleep_work_cond = st_mutex_new();
  97. st_thread_create(sleep_deviation_func, NULL, 0, 0);
  98. st_mutex_lock(sleep_work_cond);
  99. srs_trace("1. sleep...");
  100. st_utime_t start = st_utime();
  101. // other thread to do some complex work.
  102. st_mutex_unlock(sleep_work_cond);
  103. st_usleep(1000 * 1000);
  104. st_utime_t end = st_utime();
  105. srs_trace("4. sleep ok, sleep=%dus, deviation=%dus",
  106. (int)(sleep_ms * 1000), (int)(end - start - sleep_ms * 1000));
  107. st_mutex_lock(sleep_work_cond);
  108. srs_trace("sleep deviation test: end");
  109. st_mutex_destroy(sleep_work_cond);
  110. return 0;
  111. }
  112. void* thread_func(void* arg)
  113. {
  114. srs_trace("1. thread run");
  115. st_usleep(sleep_ms * 1000);
  116. srs_trace("2. thread completed");
  117. return NULL;
  118. }
  119. int thread_test()
  120. {
  121. srs_trace("===================================================");
  122. srs_trace("thread test: start");
  123. st_thread_t trd = st_thread_create(thread_func, NULL, 1, 0);
  124. if (trd == NULL) {
  125. srs_trace("st_thread_create failed");
  126. return -1;
  127. }
  128. st_thread_join(trd, NULL);
  129. srs_trace("3. thread joined");
  130. srs_trace("thread test: end");
  131. return 0;
  132. }
  133. st_mutex_t sync_start = NULL;
  134. st_cond_t sync_cond = NULL;
  135. st_mutex_t sync_mutex = NULL;
  136. st_cond_t sync_end = NULL;
  137. void* sync_master(void* arg)
  138. {
  139. // wait for main to sync_start this thread.
  140. st_mutex_lock(sync_start);
  141. st_mutex_unlock(sync_start);
  142. st_usleep(sleep_ms * 1000);
  143. st_cond_signal(sync_cond);
  144. st_mutex_lock(sync_mutex);
  145. srs_trace("2. st mutex is ok");
  146. st_mutex_unlock(sync_mutex);
  147. st_usleep(sleep_ms * 1000);
  148. srs_trace("3. st thread is ok");
  149. st_cond_signal(sync_cond);
  150. return NULL;
  151. }
  152. void* sync_slave(void* arg)
  153. {
  154. // lock mutex to control thread.
  155. st_mutex_lock(sync_mutex);
  156. // wait for main to sync_start this thread.
  157. st_mutex_lock(sync_start);
  158. st_mutex_unlock(sync_start);
  159. // wait thread to ready.
  160. st_cond_wait(sync_cond);
  161. srs_trace("1. st cond is ok");
  162. // release mutex to control thread
  163. st_usleep(sleep_ms * 1000);
  164. st_mutex_unlock(sync_mutex);
  165. // wait thread to exit.
  166. st_cond_wait(sync_cond);
  167. srs_trace("4. st is ok");
  168. st_cond_signal(sync_end);
  169. return NULL;
  170. }
  171. int sync_test()
  172. {
  173. srs_trace("===================================================");
  174. srs_trace("sync test: start");
  175. if ((sync_start = st_mutex_new()) == NULL) {
  176. srs_trace("st_mutex_new sync_start failed");
  177. return -1;
  178. }
  179. st_mutex_lock(sync_start);
  180. if ((sync_cond = st_cond_new()) == NULL) {
  181. srs_trace("st_cond_new cond failed");
  182. return -1;
  183. }
  184. if ((sync_end = st_cond_new()) == NULL) {
  185. srs_trace("st_cond_new end failed");
  186. return -1;
  187. }
  188. if ((sync_mutex = st_mutex_new()) == NULL) {
  189. srs_trace("st_mutex_new mutex failed");
  190. return -1;
  191. }
  192. if (!st_thread_create(sync_master, NULL, 0, 0)) {
  193. srs_trace("st_thread_create failed");
  194. return -1;
  195. }
  196. if (!st_thread_create(sync_slave, NULL, 0, 0)) {
  197. srs_trace("st_thread_create failed");
  198. return -1;
  199. }
  200. // run all threads.
  201. st_mutex_unlock(sync_start);
  202. st_cond_wait(sync_end);
  203. srs_trace("sync test: end");
  204. return 0;
  205. }
  206. void* io_client(void* arg)
  207. {
  208. int fd;
  209. if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  210. srs_trace("create linux socket error.");
  211. return NULL;
  212. }
  213. srs_trace("6. client create linux socket success. fd=%d", fd);
  214. st_netfd_t stfd;
  215. if ((stfd = st_netfd_open_socket(fd)) == NULL){
  216. srs_trace("st_netfd_open_socket open socket failed.");
  217. return NULL;
  218. }
  219. srs_trace("7. client st open socket success. fd=%d", fd);
  220. struct sockaddr_in addr;
  221. addr.sin_family = AF_INET;
  222. addr.sin_port = htons(io_port);
  223. addr.sin_addr.s_addr = INADDR_ANY;
  224. if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(struct sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1) {
  225. srs_trace("bind socket error.");
  226. return NULL;
  227. }
  228. char buf[1024];
  229. if (st_read_fully(stfd, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT) != sizeof(buf)) {
  230. srs_trace("st_read_fully failed");
  231. return NULL;
  232. }
  233. if (st_write(stfd, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT) != sizeof(buf)) {
  234. srs_trace("st_write failed");
  235. return NULL;
  236. }
  237. st_netfd_close(stfd);
  238. return NULL;
  239. }
  240. int io_test()
  241. {
  242. srs_trace("===================================================");
  243. srs_trace("io test: start, port=%d", io_port);
  244. int fd;
  245. if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  246. srs_trace("create linux socket error.");
  247. return -1;
  248. }
  249. srs_trace("1. server create linux socket success. fd=%d", fd);
  250. int reuse_socket = 1;
  251. if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_socket, sizeof(int)) == -1) {
  252. srs_trace("setsockopt reuse-addr error.");
  253. return -1;
  254. }
  255. srs_trace("2. server setsockopt reuse-addr success. fd=%d", fd);
  256. struct sockaddr_in addr;
  257. addr.sin_family = AF_INET;
  258. addr.sin_port = htons(io_port);
  259. addr.sin_addr.s_addr = INADDR_ANY;
  260. if (bind(fd, (const struct sockaddr*)&addr, sizeof(struct sockaddr_in)) == -1) {
  261. srs_trace("bind socket error.");
  262. return -1;
  263. }
  264. srs_trace("3. server bind socket success. fd=%d", fd);
  265. if (listen(fd, 10) == -1) {
  266. srs_trace("listen socket error.");
  267. return -1;
  268. }
  269. srs_trace("4. server listen socket success. fd=%d", fd);
  270. st_netfd_t stfd;
  271. if ((stfd = st_netfd_open_socket(fd)) == NULL){
  272. srs_trace("st_netfd_open_socket open socket failed.");
  273. return -1;
  274. }
  275. srs_trace("5. server st open socket success. fd=%d", fd);
  276. if (!st_thread_create(io_client, NULL, 0, 0)) {
  277. srs_trace("st_thread_create failed");
  278. return -1;
  279. }
  280. st_netfd_t client_stfd = st_accept(stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT);
  281. srs_trace("8. server get a client. fd=%d", st_netfd_fileno(client_stfd));
  282. char buf[1024];
  283. if (st_write(client_stfd, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT) != sizeof(buf)) {
  284. srs_trace("st_write failed");
  285. return -1;
  286. }
  287. if (st_read_fully(client_stfd, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT) != sizeof(buf)) {
  288. srs_trace("st_read_fully failed");
  289. return -1;
  290. }
  291. srs_trace("9. server io completed.");
  292. st_netfd_close(stfd);
  293. st_netfd_close(client_stfd);
  294. srs_trace("io test: end");
  295. return 0;
  296. }
  297. int pipe_test()
  298. {
  299. srs_trace("===================================================");
  300. srs_trace("pipe test: start");
  301. int fds[2];
  302. if (pipe(fds) < 0) {
  303. srs_trace("pipe failed");
  304. return -1;
  305. }
  306. srs_trace("1. pipe ok, %d=>%d", fds[1], fds[0]);
  307. st_netfd_t fdw;
  308. if ((fdw = st_netfd_open_socket(fds[1])) == NULL) {
  309. srs_trace("st_netfd_open_socket open socket failed.");
  310. return -1;
  311. }
  312. srs_trace("2. open write fd ok");
  313. st_netfd_t fdr;
  314. if ((fdr = st_netfd_open_socket(fds[0])) == NULL) {
  315. srs_trace("st_netfd_open_socket open socket failed.");
  316. return -1;
  317. }
  318. srs_trace("3. open read fd ok");
  319. char buf[1024];
  320. if (st_write(fdw, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT) < 0) {
  321. srs_trace("st_write socket failed.");
  322. return -1;
  323. }
  324. srs_trace("4. write to pipe ok");
  325. if (st_read(fdr, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT) < 0) {
  326. srs_trace("st_read socket failed.");
  327. return -1;
  328. }
  329. srs_trace("5. read from pipe ok");
  330. st_netfd_close(fdw);
  331. st_netfd_close(fdr);
  332. srs_trace("pipe test: end");
  333. return 0;
  334. }
  335. int main(int argc, char** argv)
  336. {
  337. srs_trace("ETIME=%d", ETIME);
  338. if (st_set_eventsys(ST_EVENTSYS_ALT) < 0) {
  339. srs_trace("st_set_eventsys failed");
  340. return -1;
  341. }
  342. if (st_init() < 0) {
  343. srs_trace("st_init failed");
  344. return -1;
  345. }
  346. if (sleep2_test() < 0) {
  347. srs_trace("sleep2_test failed");
  348. return -1;
  349. }
  350. if (sleep_test() < 0) {
  351. srs_trace("sleep_test failed");
  352. return -1;
  353. }
  354. if (sleep_deviation_test() < 0) {
  355. srs_trace("sleep_deviation_test failed");
  356. return -1;
  357. }
  358. if (huge_stack_test() < 0) {
  359. srs_trace("huge_stack_test failed");
  360. return -1;
  361. }
  362. if (thread_test() < 0) {
  363. srs_trace("thread_test failed");
  364. return -1;
  365. }
  366. if (sync_test() < 0) {
  367. srs_trace("sync_test failed");
  368. return -1;
  369. }
  370. if (io_test() < 0) {
  371. srs_trace("io_test failed");
  372. return -1;
  373. }
  374. if (pipe_test() < 0) {
  375. srs_trace("pipe_test failed");
  376. return -1;
  377. }
  378. // cleanup.
  379. srs_trace("wait for all thread completed");
  380. st_thread_exit(NULL);
  381. // the following never enter,
  382. // the above code will exit when all thread exit,
  383. // current is a primordial st-thread, when all thread exit,
  384. // the st idle thread will exit(0), see _st_idle_thread_start()
  385. srs_trace("all thread completed");
  386. return 0;
  387. }