tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

suspend.c (4164B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "nspr.h"
      7 #include "prpriv.h"
      8 #include "prinrval.h"
      9 
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 
     14 PRMonitor* mon;
     15 PRInt32 count;
     16 PRInt32 alive;
     17 
     18 #define SLEEP_TIME 4 /* secs */
     19 
     20 void PR_CALLBACK Level_2_Thread(void* arg) {
     21  PR_Sleep(PR_MillisecondsToInterval(4 * 1000));
     22  printf("Level_2_Thread[0x%lx] exiting\n", PR_GetCurrentThread());
     23  return;
     24 }
     25 
     26 void PR_CALLBACK Level_1_Thread(void* arg) {
     27  PRUint32 tmp = (PRUint32)arg;
     28  PRThreadScope scope = (PRThreadScope)tmp;
     29  PRThread* thr;
     30 
     31  thr = PR_CreateThreadGCAble(PR_USER_THREAD, Level_2_Thread, NULL,
     32                              PR_PRIORITY_HIGH, scope, PR_JOINABLE_THREAD, 0);
     33 
     34  if (!thr) {
     35    printf("Could not create thread!\n");
     36  } else {
     37    printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n",
     38           PR_GetCurrentThread(),
     39           (scope == PR_GLOBAL_THREAD) ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
     40           thr);
     41    PR_JoinThread(thr);
     42  }
     43  PR_EnterMonitor(mon);
     44  alive--;
     45  PR_Notify(mon);
     46  PR_ExitMonitor(mon);
     47  printf("Thread[0x%lx] exiting\n", PR_GetCurrentThread());
     48 }
     49 
     50 static PRStatus PR_CALLBACK print_thread(PRThread* thread, int i, void* arg) {
     51  PRInt32 words;
     52  PRWord* registers;
     53 
     54  printf("\nprint_thread[0x%lx]: %-20s - i = %ld\n", thread,
     55         (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ? "PR_GLOBAL_THREAD"
     56                                                         : "PR_LOCAL_THREAD",
     57         i);
     58  registers = PR_GetGCRegisters(thread, 0, (int*)&words);
     59  if (registers)
     60    printf("Registers R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n", registers[0],
     61           registers[1], registers[2], registers[3]);
     62  printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread));
     63  return PR_SUCCESS;
     64 }
     65 
     66 static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2) {
     67  PRThread* thr;
     68  PRThread* me = PR_GetCurrentThread();
     69  int n;
     70  PRInt32 words;
     71  PRWord* registers;
     72 
     73  alive = 0;
     74  mon = PR_NewMonitor();
     75 
     76  alive = count;
     77  for (n = 0; n < count; n++) {
     78    thr = PR_CreateThreadGCAble(PR_USER_THREAD, Level_1_Thread, (void*)scope2,
     79                                PR_PRIORITY_NORMAL, scope1,
     80                                PR_UNJOINABLE_THREAD, 0);
     81    if (!thr) {
     82      printf("Could not create thread!\n");
     83      alive--;
     84    }
     85    printf(
     86        "Level_0_Thread[0x%lx] created %15s thread 0x%lx\n",
     87        PR_GetCurrentThread(),
     88        (scope1 == PR_GLOBAL_THREAD) ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
     89        thr);
     90 
     91    PR_Sleep(0);
     92  }
     93  PR_SuspendAll();
     94  PR_EnumerateThreads(print_thread, NULL);
     95  registers = PR_GetGCRegisters(me, 1, (int*)&words);
     96  if (registers)
     97    printf("My Registers: R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
     98           registers[0], registers[1], registers[2], registers[3]);
     99  printf("My Stack Pointer = 0x%lx\n", PR_GetSP(me));
    100  PR_ResumeAll();
    101 
    102  /* Wait for all threads to exit */
    103  PR_EnterMonitor(mon);
    104  while (alive) {
    105    PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
    106  }
    107 
    108  PR_ExitMonitor(mon);
    109  PR_DestroyMonitor(mon);
    110 }
    111 
    112 static void CreateThreadsUU(void) {
    113  Level_0_Thread(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
    114 }
    115 
    116 static void CreateThreadsUK(void) {
    117  Level_0_Thread(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
    118 }
    119 
    120 static void CreateThreadsKU(void) {
    121  Level_0_Thread(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
    122 }
    123 
    124 static void CreateThreadsKK(void) {
    125  Level_0_Thread(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
    126 }
    127 
    128 int main(int argc, char** argv) {
    129  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    130 
    131  if (argc > 1) {
    132    count = atoi(argv[1]);
    133  } else {
    134    count = 5;
    135  }
    136 
    137  printf("\n\n%20s%30s\n\n", " ", "Suspend_Resume Test");
    138  CreateThreadsUU();
    139  CreateThreadsUK();
    140  CreateThreadsKU();
    141  CreateThreadsKK();
    142  PR_SetConcurrency(2);
    143 
    144  printf("\n%20s%30s\n\n", " ", "Added 2nd CPU\n");
    145 
    146  CreateThreadsUK();
    147  CreateThreadsKK();
    148  CreateThreadsUU();
    149  CreateThreadsKU();
    150  PR_Cleanup();
    151 
    152  return 0;
    153 }