/pliant/language/schedule/nestedsem.pli
 
 1  # Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx 
 2  # 
 3  # This program is free software; you can redistribute it and/or 
 4  # modify it under the terms of the GNU General Public License version 2 
 5  # as published by the Free Software Foundation. 
 6  # 
 7  # This program is distributed in the hope that it will be useful, 
 8  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 9  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 10  # GNU General Public License for more details. 
 11  # 
 12  # You should have received a copy of the GNU General Public License 
 13  # version 2 along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 15   
 16  scope "/pliant/language/" "/pliant/install/" 
 17  module "/pliant/install/ring2.pli" 
 18   
 19   
 20  doc 
 21    [Should be implemented more cleverly (lock algorithm):] 
 22    list 
 23      item 
 24        [Try to get the semaphore through atomic_read_and_set:] 
 25        list 
 26          item 
 27            [If we succeed, then we record the stack offset (but we don't loose time through findind the current thread header).] 
 28          item 
 29            [If we fail, we look at the the recorded stack offset:] 
 30            list 
 31              item [If it's one belonging to the current thread, then we can increment the count and succeed.] 
 32              item [else, we 'yield' the processor and retry, or record ourself in the queue then suspend outself.] 
 33   
 34  type NestedSem 
 35    field Sem sem 
 36    field Pointer:ThreadHeader header 
 37    field Int count 
 38   
 39  function build  ns 
 40    arg_w NestedSem ns 
 41    ns header :> null map ThreadHeader 
 42   
 43   
 44  method ns request 
 45    arg_rw NestedSem ns 
 46    var Pointer:ThreadHeader :> current_thread_header 
 47    if (addressof ns:header)<>addressof:h 
 48      ns:sem request 
 49      ns header :> h 
 50      ns count := 1 
 51    else 
 52      ns count += 1 
 53   
 54  method ns release 
 55    arg_rw NestedSem ns 
 56    if ns:count=1 
 57      ns header :> null map ThreadHeader 
 58      ns:sem release 
 59    else 
 60      ns count -= 1 
 61   
 62   
 63  method ns rd_request 
 64    arg_rw NestedSem ns 
 65    var Pointer:ThreadHeader :> current_thread_header 
 66    if (addressof ns:header)<>addressof:h 
 67      ns:sem rd_request 
 68    # else 
 69    #   ns count += 1 
 70   
 71  method ns rd_release 
 72    arg_rw NestedSem ns 
 73    var Pointer:ThreadHeader :> current_thread_header 
 74    if (addressof ns:header)<>addressof:h 
 75      ns:sem rd_release 
 76    # else 
 77    #   ns count -= 1 
 78   
 79   
 80   
 81  export NestedSem '. request' '. release' '. rd_request' '. rd_release' 
 82   
 83   
 84  public 
 85    gvar NestedSem pliant_compiler_semaphore