home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / quartz / quartz10.lha / src / presto / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  17.2 KB  |  719 lines

  1. //
  2. // process.c:
  3. //
  4. //      Implementation of process class.
  5. //
  6. //      Main routine p_wait is where each scheduling thread lives.
  7. //
  8. // Modification History:
  9. //
  10. //   12-Jan-90  John Faust
  11. //   Add support for processor affinity on Sequent Symmetry.
  12. //
  13. //   05-Dec-89  John Faust
  14. //   Remove all stack free lists.  Allocate stacks of fixed size when thread
  15. //   is allocated.  Stack remains associated with owning thread.  More
  16. //   efficient (removes search of stack freelist for stack of proper size,
  17. //   allocation of stack if one of proper size not found, and eliminates
  18. //   need to balance stack freelists).
  19. //
  20. //   30-Nov-1989  John Faust
  21. //   Incorporate Bob Sandstro fix which allows gprof monitor files to be
  22. //   captured.
  23. //
  24. //   16-Nov-1989  John Faust
  25. //   Implement per-processor free lists of stacks.
  26. //
  27. //   08-Nov-1989  John Faust
  28. //   Implement per-processor free lists of thread templates.
  29. //
  30.  
  31.  
  32. #define _PROCESS_C
  33.  
  34.  
  35. #include <sys/types.h>
  36. #include <signal.h>
  37. #include <osfcn.h>
  38. #include "presto.h"
  39.  
  40. #ifdef i386
  41. #include <sys/tmp_ctl.h>
  42. #endif i386
  43.  
  44. Process staticproc;
  45. Process *sysproc = &staticproc;
  46.  
  47. #ifdef GPROF
  48. extern char *_mon_file;
  49. static char mon_name[20];
  50. #endif GPROF
  51.  
  52. private_t Process *thisproc = 0;    // always ME!
  53.  
  54. extern Main *MAIN;
  55.  
  56. //
  57. // This is the global free list of thread templates.  Deleted threads
  58. // go here when the local free list of the owning processor is full.
  59. // Threads are taken from here only when a local free list is exhausted.
  60. // The local lists (see process.h) are non-shared and are thus unlocked,
  61. // for speed.  The global list is shared and is thus locked.  That makes
  62. // it slow, so we only access it when we really have to.
  63. //
  64. static shared_t ThreadQ thread_global_freelist (TS_ANY);
  65.  
  66.  
  67. //
  68. // This constructor is called to create the root process.
  69. //
  70. // ptag proc constructor is useful for getting a handle on the root
  71. // process.  Since we weren't around when he got forked, we kluge
  72. // with this.
  73. //
  74. Process::Process(int ptag, int id)
  75. {
  76.        int p_continue();        // signal handler
  77.        int i;
  78.        Thread* tlist [1+NUMPROCS+NUM_PREALLOC_THREADS];
  79.  
  80. #ifdef DEBUG_STARTUP
  81.         cout << "making root process\n";
  82. #endif DEBUG_STARTUP
  83.  
  84.     if (ptag != P_ROOT /* || no root exists */ )    {
  85.         error("Invalid attempt to flag root Process\n");
  86.     }
  87.  
  88.         //
  89.         //  Create process local thread freelist, and preallocate
  90.         //  some threads.
  91.         //
  92.     //  The root process is responsible for creating the
  93.     //  schuduler_starter thread as well as each of the main threads.
  94.     //  Therefore, preallocate enough extra threads (1 for the
  95.         //  scheduler_starter, one for each possible processor).
  96.     //
  97.     //  Be sure to use MAINSTACKSIZE for the main threads,
  98.     //  and STACKSIZE for the remaining preallocated threads.
  99.     //  For now, STACKSIZE is used for all preallocated threads,
  100.     //  and MAINSTACKSIZE ends up being ignored.
  101.         //
  102.         p_thread_freelist = new ThreadQUnlocked (TS_ANY);
  103.         for (i=0; i<1+NUMPROCS+NUM_PREALLOC_THREADS; i++)
  104.             tlist [i] = thisthread->newthread ("prealloc", 0,
  105.                                                DEFSTACKSIZ);
  106.         for (i=0; i<1+NUMPROCS+NUM_PREALLOC_THREADS; i++)
  107.             free_thread (tlist[i]);    // put on local freelist
  108.  
  109. //cout << "threads have been preallocated for root process\n";
  110.  
  111.     p_id = id;
  112.     p_ppid = getppid();
  113.     p_pid = getpid();
  114.     p_name = "ROOT";
  115.     p_flags = P_ROOT;
  116.     p_state = S_RUN;        // obviously
  117.     p_request = 0;
  118.     p_thread = 0;
  119.     p_schedthread = thisthread;
  120.     thisproc = this;
  121. #ifdef DEBUG_STARTUP
  122.         cout << form ("root process - this = %x\n", this); cout.flush();
  123. #endif DEBUG_STARTUP
  124.  
  125.         //
  126.         // Set processor affinity if applicable.
  127.         //
  128. #ifdef i386
  129.  
  130. #ifdef DEBUG_STARTUP
  131.         cout << form ("root - affinity = %d\n", MAIN->get_affinity());
  132.         cout.flush ();
  133. #endif DEBUG_STARTUP
  134.         if (MAIN->get_affinity ())
  135.         {
  136.         extern int tmp_affinity (int);
  137.  
  138.             if (tmp_affinity (thisproc->id()) == -1)
  139.                 cout << "unable to set affinity on root process "
  140.                      << thisproc->id() << "\n";
  141. //            else
  142. //                cout << "affinity set on root process "
  143. //                     << thisproc->id() << "\n";
  144.             cout.flush ();
  145.         }
  146. #endif i386
  147.  
  148.     signal(SIGCONT, p_continue);
  149.  
  150. #ifdef DEBUG_STARTUP
  151.         cout << "done making root process\n";
  152. #endif DEBUG_STARTUP
  153. }
  154.  
  155.  
  156. //
  157. //  This constructor is the one invoked by newprocess.  It creates all
  158. //  processes with the exception of the root process and the original
  159. //  static process.
  160. //
  161. Process::Process(char* name, int id, int delayedfork)
  162. {
  163.         int i;
  164.         Thread* tlist [NUM_PREALLOC_THREADS];
  165.  
  166. #ifdef DEBUG_STARTUP
  167.         cout << "making new process " << name << "\n";
  168. #endif DEBUG_STARTUP
  169.  
  170.         //
  171.         //  Create process local thread freelist, and preallocate
  172.         //  some threads.
  173.         //
  174.         p_thread_freelist = new ThreadQUnlocked (TS_ANY);
  175.         for (i=0; i<NUM_PREALLOC_THREADS; i++)
  176.             tlist [i] = thisthread->newthread ("prealloc", 0, DEFSTACKSIZ);
  177.         for (i=0; i<NUM_PREALLOC_THREADS; i++)
  178.             free_thread (tlist[i]);    // put on local freelist
  179.  
  180. //cout << "threads have been preallocated for process " << name << "\n";
  181.  
  182.     p_name = name;
  183.     p_request = 0;
  184.     p_flags = 0;
  185.     p_id = id;
  186.     p_schedthread = p_thread = 0;
  187.     if  (!delayedfork) {
  188. #ifdef DEBUG_STARTUP
  189.                 cout << "not delayed fork, calling p_fork\n";
  190. #endif DEBUG_STARTUP
  191.         p_fork();
  192.         }
  193.     else {
  194. #ifdef DEBUG_STARTUP
  195.                 cout << "delayed fork\n";
  196. #endif DEBUG_STARTUP
  197.         p_state = S_DELAYEDFORK;
  198.         }
  199.     return;
  200. }
  201.  
  202. //
  203. // Constructor for staticproc (sysproc).
  204. //
  205. Process::Process()
  206. {
  207. #ifdef DEBUG_STARTUP
  208. //      cout << "making static sysproc\n";   cout here = segmentation fault
  209. #endif DEBUG_STARTUP
  210.  
  211. #if (sun && THREAD_HAS_INTERRUPTIBLE_FIELD)
  212.     p_interruptible = 0;
  213. #endif
  214. #ifdef vax 
  215.     p_interruptible = 0;
  216. #endif vax
  217.     p_name = "sysproc";
  218.         p_thread_freelist = new ThreadQUnlocked (TS_ANY);
  219.  
  220. #ifdef DEBUG_STARTUP
  221. //      cout << "done making static sysproc\n";
  222. #endif DEBUG_STARTUP
  223. }
  224.  
  225. //
  226. // Delay the fork until after the return of the constructor.  Derived
  227. // classes will need to take advantage of this to ensure that the
  228. // virtual table in the derived class is properly initalized.  Use
  229. // for a derived class is:
  230. //
  231. //    DerivedProcess::DerivedProcess(args) : (name, id,  S_DELAYEDFORK)
  232. //    {
  233. //        initialize derived part
  234. //        Process::p_fork();        
  235. //        /* only parent returns to here.  Child never does */
  236. //    }
  237. //
  238. // Must be careful to use private stack when forking into child; else
  239. // parent and child can race on the shared stack (leads to strange
  240. // core dumps -- hard to diagnose).  This should be cleaned up; use of
  241. // asm-functions may help.
  242.  
  243. void
  244. Process::p_fork()
  245. {
  246.     int pid;
  247.     int spinonfork = 1;        // hold child until done
  248.     static private_t int private_stack[256];
  249.  
  250.     extern int _rtmp;
  251.  
  252. #ifdef DEBUG_STARTUP
  253.         cout << "in p_fork\n";
  254. #endif DEBUG_STARTUP
  255.  
  256. #ifdef sun
  257.     _rtmp = (int) &private_stack[sizeof(private_stack) / sizeof(int)];
  258. #endif sun
  259. #ifdef sequent
  260.     _rtmp = (int) &private_stack[sizeof(private_stack) / sizeof(int)];
  261. #endif sequent
  262.  
  263. #ifdef mc68020
  264.     asm("movl sp, a0");
  265.     asm("movl __rtmp, sp");
  266.     asm("movl a0, __rtmp");
  267. #endif mc68020
  268. #ifdef    i386
  269.     asm("xchgl %esp, __rtmp");
  270. #endif    i386
  271. #ifdef    ns32000
  272.     asm("sprd sp, r0");
  273.     asm("lprd sp, __rtmp");
  274.     asm("movd r0, __rtmp");
  275. #endif    ns32000
  276.  
  277.     p_state = S_FORKING;
  278.  
  279.     pid = fork();
  280.     switch (pid)    {
  281.     case -1:    // fork error
  282. #ifdef mc68020
  283.         asm("movl __rtmp, sp");
  284. #endif mc68020
  285. #ifdef    i386
  286.         asm("movl __rtmp, %esp");
  287. #endif    i386
  288. #ifdef    ns32000
  289.         asm("lprd sp, __rtmp");
  290. #endif    ns32000
  291.         p_pid = -1;
  292.         return;    
  293.     case 0:        // child
  294.         p_ppid = getppid();
  295.         p_pid = getpid();
  296. #ifdef GPROF
  297.                 (void) sprintf (mon_name, "%s.%d", _mon_file, p_pid);
  298.                 _mon_file = mon_name;
  299. #endif GPROF
  300.         p_runchild(&spinonfork);
  301.         // NOTREACHED
  302.         error("Process forked child returned???");
  303.     default:    // parent: can't return until child finished with stack
  304. #ifdef mc68020
  305.         asm("movl __rtmp, sp");
  306. #endif mc68020
  307. #ifdef    i386
  308.         asm("movl __rtmp, %esp");
  309. #endif    i386
  310. #ifdef    ns32000
  311.         asm("lprd sp, __rtmp");
  312. #endif    ns32000
  313.         p_pid = pid;
  314.         while (spinonfork)
  315.             continue;
  316.     }
  317. }
  318.  
  319.  
  320. //
  321. // Fake being able to virtualize the constructor
  322. //
  323. Process*
  324. Process::newprocess(char* name, int id)
  325. {
  326.     return new Process(name, id);
  327. }
  328.  
  329.  
  330. //
  331. // Run the child scheduler.  Hold onto the parent until we get all
  332. // that we need from the args (this especially).  See comments.
  333. //
  334. void
  335. Process::p_runchild(int *spinonfork)
  336. {
  337.     extern int _rtmp;
  338.  
  339.         Thread* t = thisthread->newthread(p_name, 0, DEFSTACKSIZ);
  340.  
  341. #ifdef DEBUG_STARTUP
  342.         cout << "in p_runchild (after fork)\n";
  343. #endif DEBUG_STARTUP
  344.  
  345.     thisthread = t;            //  get what we need from our parents
  346.     thisproc = this;        //  stack
  347.  
  348.     //
  349.     _rtmp = (int)(thisthread->stack()->top());
  350.     { 
  351. #ifdef vax
  352. //    asm("movl    __rtmp, sp");
  353. #endif
  354. #ifdef mc68020
  355.     asm("movl    __rtmp, sp");
  356. #endif mc68020
  357. #ifdef ns32000
  358.     asm("lprd    sp, __rtmp");
  359. #endif
  360. #ifdef    i386
  361.     asm("movl    __rtmp, %esp");
  362. #endif
  363.     }    
  364.     //
  365.     // should have secondary entry point into start to avoid the test
  366.     // for a scheduler.
  367.     //
  368.     //
  369.     thisthread->setflags(TF_SCHEDULER|TF_KEEPSTACK|TF_NONPREEMPTABLE);
  370.     thisthread->start(thisproc, (PFany)(thisproc->invoke));
  371.     thisthread->setproc(thisproc);
  372.  
  373.     thisproc->p_schedthread = thisthread;
  374.     *spinonfork = 0;        // Let him go...
  375.     //
  376.     // The parent has just returned using the frame that our
  377.     // fp references.  This means that we can never return beyond
  378.     // this routine, AND we can't reference any of the params
  379.     // passed to us on the stack  (use thisthread and thisproc from
  380.     // here on).
  381.         //
  382.  
  383.         //
  384.         // Set processor affinity if applicable.
  385.         //
  386. #ifdef i386
  387.  
  388. #ifdef DEBUG_STARTUP
  389.         cout << form ("affinity = %d\n", MAIN->get_affinity()); cout.flush ();
  390. #endif DEBUG_STARTUP
  391.         if (MAIN->get_affinity ())
  392.         {
  393.             extern int tmp_affinity (int);
  394.  
  395.             if (tmp_affinity (thisproc->id()) == -1)
  396.                 cout << "unable to set affinity on process "
  397.                      << thisproc->id() << "\n";
  398. //            else
  399. //                cout << "affinity set on process "
  400. //                     << thisproc->id() << "\n";
  401.             cout.flush ();
  402.         }
  403. #endif i386
  404. #ifdef PROFILE
  405.     QProcInit(thisproc->id());
  406. #endif
  407.  
  408.     //
  409.     // Can't use run since it won't let us idle "thisthread" and run
  410.     // "thisthread" at the same time.
  411.     //
  412.     thisthread->isrunning();
  413.     thisthread->runrun();        // fall into p_wait
  414.     thisthread->isnotrunning();
  415.  
  416.     //
  417.     // fall out of p_wait on its return to here
  418.     //
  419.     delete thisproc;
  420.     //
  421.     // should never get here
  422.     //
  423.     error("PROCESS DESTRUCTOR RETURNED");
  424. }
  425.  
  426. //
  427. // ~Process:    kill a Process.
  428. //    If we are the process to be killed, then we mark ourselves as a 
  429. //    zombie and _exit()  (no destructors will be called).  If we are
  430. //    trying to destroy another process, then we mark it
  431. //    as S_EXITING and then ask the process to actually return.
  432. //    This will have it fall back into runrun and then into
  433. //    p_runchild, where we will get called to kill it running
  434. //    as the process which is being asked to die.
  435. //
  436. //    Doing it this way allow processes to perform whatever cleanup
  437. //    they feel like before actually disappearing.
  438. //
  439. //    If we are the root process, we just return quietly
  440. //    
  441. //
  442.  
  443. Process::~Process()
  444. {
  445.     extern void shfree(Process*);
  446.     extern void free(Process*);
  447.  
  448.  
  449.     if (/*this &&*/  ((this->p_state&S_EXITING) == 0))    {
  450.         int pid = p_pid;
  451.         if (this == thisproc)    {
  452.             this->p_state = S_ZOMBIE;
  453.             if (this->isroot())    {
  454.                 this = 0;
  455.                 return;
  456.             }
  457.             //
  458.             // Our stack frame is gonna be all screwed up here
  459.             // since we started off with the fp running
  460.             // on our parent's frame, and he has now return.
  461.             // We can never return from this routine.
  462.             //
  463. #ifdef GPROF
  464.                         monitor(0);
  465. #endif GPROF
  466.             _exit(0);
  467.         } else    {
  468.             this->p_state = S_EXITING;
  469.             this->request(R_RETURN);
  470.         }
  471.     }
  472.     this = 0;
  473. }
  474.  
  475. int
  476. Process::invoke()
  477. {
  478. #ifdef DEBUG_STARTUP
  479.         cout << "in Process::invoke()\n";  cout.flush ();
  480. #endif DEBUG_STARTUP
  481.  
  482.     p_wait();
  483.     return 0;
  484. }
  485.  
  486. //
  487. // Parent (or sibling) wakes up a looping Process here with the
  488. // "special" request code
  489. //
  490. int
  491. Process::request(int req)        
  492. {
  493.  
  494.     //
  495.     // If someone is stupid enough to make a request on a proc that
  496.     // is already servicing someone else... then they are just
  497.     // gonna have to wait their turn!
  498.     //
  499.     while (p_request != R_NULL)    {
  500.         if (p_request&(R_DIE|R_RETURN))    // no way to satisfy
  501.             return -1;
  502.     }
  503.  
  504.     p_request = req;
  505. #ifdef TDEBUG    
  506.     cerr << thisproc->name() << "making request " << req <<
  507.             " on " << this->name() << "\n";
  508. #endif        
  509.  
  510.     if (p_state&S_OSPAUSE)    {    // sleeping in os
  511.         cerr << "\nWaking up " << this << "\n";
  512.         return (kill(p_pid, SIGCONT));
  513.     } else        
  514.         return 0;
  515. }
  516.  
  517.  
  518. //
  519. // p_wait:    hang around and wait for something interesting
  520. //        to happen. That is, loop until someone bangs
  521. //        on our door, or until there is a readythread to
  522. //        start working on, OR we are not the root process, but our
  523. //        parent process seems to have disappeared (in which case
  524. //        we abort the scheduler, killing ourselves and all our 
  525. //        siblings).  We only check the last case "every so often" when 
  526. //        can't find anything else to do.
  527. //        This is an example of a "heuristic."  AI in action!
  528. //
  529. //        This doesn't guarantee that the system will always stop.  If
  530. //        the parent dies of as the result of an uncaught signal while
  531. //        holding a spinlock, the rest of the system could be blocked.
  532. //        If all other process are blocked, then the system will
  533. //        spin forever waiting for the holding process to relase
  534. //        the spinlock (which will never happend).  Lesson:
  535. //            Don't kill -9 the root process.
  536. //
  537. void
  538. Process::p_wait()
  539. {
  540.     int idlespan = 0;    
  541.  
  542. #ifdef PROFILE
  543.     QIdleLoopBegin();
  544. #endif
  545. #ifdef DEBUG_STARTUP
  546.         cout << "in Process::p_wait()\n"; cout.flush ();
  547. #endif DEBUG_STARTUP
  548.  
  549.     for (;;)    {
  550.         p_state = S_WAIT;
  551.         // wait until readythread, or until we get asynch request
  552.         if ( (p_request == NULL) && (p_thread = sched->getreadythread()) == NULL)    {
  553.              if (idlespan++ == 50000)    {
  554.                  // check if our parent has died and we are not root
  555.             if (!isroot() && getppid() != this->ppid())    {
  556.                 // kill myself and all siblings
  557.                 sched->abort(-SIGKILL);
  558.             } else    
  559.                 idlespan = 0;
  560.              }
  561.              continue;
  562.         }
  563.  
  564.         if (p_request)    {
  565.             //
  566.             // assumption is that only one thread can be diddling
  567.             // with processes at a time... otherwise this might
  568.             // not work.
  569.             //
  570.  
  571.             if (p_request & R_RETURN)    {
  572. //                if ( (p_flags&P_ROOT) == 0)
  573. //                    error("PROCS CANT RETURN YET\n");
  574. //                else
  575.                     return;
  576.             }
  577.  
  578.             //
  579.             // They can only die
  580.             //
  581.             if (p_request & R_DIE)        {    
  582.                 delete this;
  583.                 // not reached! 
  584.             }
  585.  
  586.             if (p_request & R_PARK)    {
  587.                 this->p_pause();
  588.                 continue;
  589.             };
  590.         } else    {        // must have a readythread
  591. #ifdef DEBUG_STARTUP
  592.                         cout << "p_wait - got ready thread\n"; cout.flush ();
  593. #endif DEBUG_STARTUP
  594.             if (p_thread->flags()&TF_SCHEDULER)    {    
  595.                 p_thread->error("Can't schedule a scheduling thread");
  596.                 continue;        // NOT REACHED?
  597.             }
  598.             p_state = S_RUN;
  599.             (void)p_thread->run();    
  600.         }
  601.         // others
  602.     }
  603. }    
  604.  
  605.  
  606. //
  607. // p_pause:    internal version of park
  608. //
  609. void
  610. Process::p_pause()
  611. {
  612.     if (p_state != S_WAIT)    
  613.         error("p_pause called to pause non spinning process");
  614.  
  615.     p_state = S_OSPAUSE;
  616.     p_request = 0;        // must clear here, not above
  617.     ::pause();
  618.     p_state = S_WAIT;
  619. }
  620.  
  621. //
  622. // park:    Give it a rest buddy boy
  623. //
  624. void
  625. Process::park()
  626. {
  627.     if (this == thisproc)    {
  628.         cerr << "Warning: putting myself to sleep\n";
  629.         this->p_pause();
  630.     }
  631.     else    {
  632.         // baby you can drive my car
  633.         p_request = R_WAKEUP|R_PARK;
  634.     }
  635. }
  636.  
  637. void
  638. Process::drive()
  639. {
  640.     if (this == thisproc)
  641.         return;
  642.     else    {
  643.         if (p_state != S_OSPAUSE)
  644.             cerr << "Warning: proc not parked\n";
  645.         ::kill(p_pid, SIGCONT);
  646.     }
  647. }
  648.  
  649.  
  650. void
  651. Process::error(char *s)
  652. {
  653.     cerr << "Process error " << s << "  " << this << "\n";
  654.     fatalerror();
  655. }
  656.  
  657. // signal handler
  658. int p_continue()
  659. {
  660.     return 0;
  661. }
  662.  
  663.  
  664. //
  665. // A process comes here when it's local thread freelist is empty.
  666. // Get any extra threads that are lying around in the global thread freelist.
  667. // Could optimize to lock global list and grab all threads before unlock,
  668. // instead of doing lock-get-unlock for each thread.
  669. //
  670. void
  671. Process::get_gbl_threads ()
  672. {
  673.     register Thread* t;
  674.     int i;
  675.  
  676.     if (thread_global_freelist.length() == 0) return;
  677.     for (i=0; i<LCL_THREAD_FREELIST_THRESH/2-1; i++)
  678.     {
  679.         t = thread_global_freelist.get ();
  680.         if (t == 0) break;
  681.         p_thread_freelist->append (t);
  682.     }
  683. }
  684.  
  685. //
  686. // A process comes here when it's local thread freelist is too full.
  687. // Put some of the extra threads into the global thread freelist.
  688. // Could optimize to lock global list and append all extras before unlock,
  689. // instead of doing lock-append-unlock for each thread.
  690. //
  691. void
  692. Process::free_gbl_threads ()
  693. {
  694.     Thread* t;
  695.     int i;
  696.  
  697.     for (i=p_thread_freelist->length(); i>LCL_THREAD_FREELIST_THRESH/2; i--)
  698.     {
  699.         t = p_thread_freelist->get ();
  700.         if (t == 0) break;
  701.         if (thread_global_freelist.length() > GBL_THREAD_FREELIST_MAX)
  702.         {
  703. //#ifdef DEBUG_STARTUP
  704.             cout << "Global thread freelist too big, deleting thread\n";
  705. //#endif DEBUG_STARTUP
  706.             delete (t);
  707.         }
  708.         else
  709.             thread_global_freelist.append (t);
  710.     }
  711. }
  712.  
  713.  
  714. void
  715. Process::print(ostream& s)
  716. {
  717.     s << form("(Process)=0x%x, p_id=%d, p_name=%s, p_pid=%d, p_ppid=%d, p_state=0x%x, p_request=%d",this,p_id,p_name,p_pid,p_ppid,p_state,p_request);
  718. }
  719.