Rev 3185 | Rev 3188 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3185 | Rev 3187 | ||
---|---|---|---|
Line 56... | Line 56... | ||
56 | #include <mm/as.h> |
56 | #include <mm/as.h> |
57 | #include <panic.h> |
57 | #include <panic.h> |
58 | #include <debug.h> |
58 | #include <debug.h> |
59 | #include <adt/list.h> |
59 | #include <adt/list.h> |
60 | #include <synch/spinlock.h> |
60 | #include <synch/spinlock.h> |
- | 61 | #include <synch/mutex.h> |
|
- | 62 | #include <synch/condvar.h> |
|
61 | #include <arch/asm.h> |
63 | #include <arch/asm.h> |
62 | #include <arch.h> |
64 | #include <arch.h> |
63 | #include <print.h> |
65 | #include <print.h> |
64 | #include <align.h> |
66 | #include <align.h> |
65 | #include <mm/slab.h> |
67 | #include <mm/slab.h> |
Line 101... | Line 103... | ||
101 | zone_t *info[ZONES_MAX]; |
103 | zone_t *info[ZONES_MAX]; |
102 | } zones_t; |
104 | } zones_t; |
103 | 105 | ||
104 | static zones_t zones; |
106 | static zones_t zones; |
105 | 107 | ||
- | 108 | /* |
|
- | 109 | * Synchronization primitives used to sleep when there is no memory |
|
- | 110 | * available. |
|
- | 111 | */ |
|
- | 112 | mutex_t zones_mtx; |
|
- | 113 | condvar_t zones_cv; |
|
- | 114 | int new_freed_mem = false; |
|
106 | 115 | ||
107 | /********************/ |
116 | /********************/ |
108 | /* Helper functions */ |
117 | /* Helper functions */ |
109 | /********************/ |
118 | /********************/ |
110 | 119 | ||
Line 989... | Line 998... | ||
989 | zone = find_free_zone_and_lock(order, pzone); |
998 | zone = find_free_zone_and_lock(order, pzone); |
990 | } |
999 | } |
991 | } |
1000 | } |
992 | if (!zone) { |
1001 | if (!zone) { |
993 | /* |
1002 | /* |
994 | * TODO: Sleep until frames are available again. |
1003 | * Sleep until some frames are available again. |
995 | */ |
1004 | */ |
- | 1005 | if (flags & FRAME_ATOMIC) { |
|
996 | interrupts_restore(ipl); |
1006 | interrupts_restore(ipl); |
997 | - | ||
998 | if (flags & FRAME_ATOMIC) |
- | |
999 | return 0; |
1007 | return 0; |
- | 1008 | } |
|
1000 | 1009 | ||
- | 1010 | #ifdef CONFIG_DEBUG |
|
- | 1011 | printf("Thread %" PRIu64 " falling asleep, low memory.\n", THREAD->tid); |
|
- | 1012 | #endif |
|
- | 1013 | ||
- | 1014 | mutex_lock(&zones_mtx); |
|
- | 1015 | if (!new_freed_mem) |
|
1001 | panic("Sleep not implemented.\n"); |
1016 | condvar_wait(&zones_cv, &zones_mtx); |
- | 1017 | new_freed_mem = false; |
|
- | 1018 | mutex_unlock(&zones_mtx); |
|
- | 1019 | ||
- | 1020 | #ifdef CONFIG_DEBUG |
|
- | 1021 | printf("Thread %" PRIu64 " woken up, memory available.\n", THREAD->tid); |
|
- | 1022 | #endif |
|
- | 1023 | ||
- | 1024 | interrupts_restore(ipl); |
|
1002 | goto loop; |
1025 | goto loop; |
1003 | } |
1026 | } |
1004 | 1027 | ||
1005 | v = zone_frame_alloc(zone, order); |
1028 | v = zone_frame_alloc(zone, order); |
1006 | v += zone->base; |
1029 | v += zone->base; |
Line 1026... | Line 1049... | ||
1026 | ipl_t ipl; |
1049 | ipl_t ipl; |
1027 | zone_t *zone; |
1050 | zone_t *zone; |
1028 | pfn_t pfn = ADDR2PFN(frame); |
1051 | pfn_t pfn = ADDR2PFN(frame); |
1029 | 1052 | ||
1030 | ipl = interrupts_disable(); |
1053 | ipl = interrupts_disable(); |
1031 | 1054 | ||
1032 | /* |
1055 | /* |
1033 | * First, find host frame zone for addr. |
1056 | * First, find host frame zone for addr. |
1034 | */ |
1057 | */ |
1035 | zone = find_zone_and_lock(pfn,NULL); |
1058 | zone = find_zone_and_lock(pfn, NULL); |
1036 | ASSERT(zone); |
1059 | ASSERT(zone); |
1037 | 1060 | ||
1038 | zone_frame_free(zone, pfn-zone->base); |
1061 | zone_frame_free(zone, pfn - zone->base); |
1039 | 1062 | ||
1040 | spinlock_unlock(&zone->lock); |
1063 | spinlock_unlock(&zone->lock); |
- | 1064 | ||
- | 1065 | /* |
|
- | 1066 | * Signal that some memory has been freed. |
|
- | 1067 | */ |
|
- | 1068 | mutex_lock(&zones_mtx); |
|
- | 1069 | new_freed_mem = true; |
|
- | 1070 | condvar_broadcast(&zones_cv); |
|
- | 1071 | mutex_unlock(&zones_mtx); |
|
- | 1072 | ||
1041 | interrupts_restore(ipl); |
1073 | interrupts_restore(ipl); |
1042 | } |
1074 | } |
1043 | 1075 | ||
1044 | /** Add reference to frame. |
1076 | /** Add reference to frame. |
1045 | * |
1077 | * |
Line 1114... | Line 1146... | ||
1114 | 1146 | ||
1115 | /* Black list first frame, as allocating NULL would |
1147 | /* Black list first frame, as allocating NULL would |
1116 | * fail in some places */ |
1148 | * fail in some places */ |
1117 | frame_mark_unavailable(0, 1); |
1149 | frame_mark_unavailable(0, 1); |
1118 | } |
1150 | } |
- | 1151 | ||
- | 1152 | mutex_initialize(&zones_mtx, MUTEX_ACTIVE); /* mimic spinlock */ |
|
- | 1153 | condvar_initialize(&zones_cv); |
|
1119 | } |
1154 | } |
1120 | 1155 | ||
1121 | 1156 | ||
1122 | /** Return total size of all zones. */ |
1157 | /** Return total size of all zones. */ |
1123 | uint64_t zone_total_size(void) |
1158 | uint64_t zone_total_size(void) |